<commit_before>/*
** Copyright 2015 Centreon
**
** 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.
**
** For more information : contact@centreon.com
*/

#include <cstdlib>
#include <ctime>
#include <iostream>
#include "test/cbd.hh"
#include "test/centengine.hh"
#include "test/centengine_config.hh"
#include "test/db.hh"
#include "test/file.hh"
#include "test/misc.hh"
#include "test/predicate.hh"
#include "test/time_points.hh"
#include "test/vars.hh"

using namespace com::centreon::broker;

#define TEST_NAME "rtmonitoring_v2_instances"
#define DB_NAME "broker_" TEST_NAME

// Check count.
static int check_number(0);

/**
 *  Precheck routine.
 */
static void precheck(test::time_points& tpoints, char const* name) {
  ++check_number;
  std::cout << "check #" << check_number << " (" << name << ")\n";
  tpoints.store();
  return ;
}

/**
 *  Postcheck routine.
 */
static void postcheck(
              test::centengine& engine,
              test::time_points& tpoints,
              test::db& db,
              test::predicate expected[][25]) {
  static std::string check_query(
    "SELECT instance_id, name, active_host_checks,"
    "       active_service_checks, check_hosts_freshness,"
    "       check_services_freshness, deleted, end_time, engine,"
    "       event_handlers, failure_prediction, flap_detection,"
    "       global_host_event_handler,"
    "       global_service_event_handler, last_alive,"
    "       last_command_check, notifications, obsess_over_hosts,"
    "       obsess_over_services, outdated, passive_host_checks,"
    "       passive_service_checks, pid, running, start_time"
    // XXX : not checked yet       "       version"
    "  FROM instances");
  engine.reload();
  test::sleep_for(3);
  tpoints.store();
  expected[0][14]
    = test::predicate(tpoints.prelast(), tpoints.last() + 1);
  db.check_content(check_query, expected);
  std::cout << "  passed\n";
  return ;
}

/**
 *  Check that the instances table work properly.
 *
 *  @return EXIT_SUCCESS on success.
 */
int main() {
  // Error flag.
  bool error(true);

  try {
    // Database.
    char const* tables[] = { "instances", NULL };
    test::db db(DB_NAME, tables);

    // Monitoring broker.
    test::file cbd_cfg;
    cbd_cfg.set_template(
      PROJECT_SOURCE_DIR "/test/cfg/sql.xml.in");
    cbd_cfg.set("BROKER_ID", "84");
    cbd_cfg.set("BROKER_NAME", "my-broker-cbd");
    cbd_cfg.set("POLLER_ID", "42");
    cbd_cfg.set("POLLER_NAME", "my-poller");
    cbd_cfg.set("TCP_PORT", "5571");
    cbd_cfg.set("DB_NAME", DB_NAME);
    cbd_cfg.set(
      "SQL_ADDITIONAL",
      "<write_filters>"
      "  <category>neb:instance</category>"
      "  <category>neb:instance_status</category>"
      "</write_filters>");
    test::cbd broker;
    broker.set_config_file(cbd_cfg.generate());
    broker.start();
    test::sleep_for(1);

    // Monitoring engine.
    test::file cbmod_cfg;
    cbmod_cfg.set_template(
      PROJECT_SOURCE_DIR "/test/cfg/tcp.xml.in");
    cbmod_cfg.set("BROKER_ID", "83");
    cbmod_cfg.set("BROKER_NAME", "my-broker-cbmod");
    cbmod_cfg.set("POLLER_ID", "42");
    cbmod_cfg.set("POLLER_NAME", "my-poller");
    cbmod_cfg.set("TCP_HOST", "localhost");
    cbmod_cfg.set("TCP_PORT", "5571");
    test::centengine_config engine_config;
    engine_config.generate_hosts(3);
    engine_config.generate_services(5);
    engine_config.set_cbmod_cfg_file(cbmod_cfg.generate());
    engine_config.set_directive("accept_passive_host_checks", "0");
    engine_config.set_directive("accept_passive_service_checks", "0");
    engine_config.set_directive("check_host_freshness", "0");
    engine_config.set_directive("check_service_freshness", "0");
    engine_config.set_directive("enable_event_handlers", "0");
    engine_config.set_directive("enable_failure_prediction", "0");
    engine_config.set_directive("enable_flap_detection", "0");
    engine_config.set_directive("enable_notifications", "0");
    engine_config.set_directive("execute_host_checks", "0");
    engine_config.set_directive("execute_service_checks", "0");
    engine_config.set_directive("obsess_over_hosts", "0");
    engine_config.set_directive("obsess_over_services", "0");
    test::centengine engine(&engine_config);

    // Objects.
    test::time_points tpoints;

    // Check default entry.
    precheck(tpoints, "engine, last_alive, pid, running, start_time");
    engine.start();
    test::sleep_for(1);
    test::predicate expected[][25] = {
      { 42u, "my-poller", false, false, false, false, false,
        test::predicate(test::predicate::type_null), "Centreon Engine",
        false, false, false, "", "",
        test::predicate(tpoints.prelast(), tpoints.last() + 1),
        test::predicate(test::predicate::type_null), false, false,
        false, false, false, false,
        true, // PID will be converted to boolean, any non-0 will match.
        true, test::predicate(tpoints.prelast(), tpoints.last() + 1) },
      { test::predicate() }
    };
    postcheck(engine, tpoints, db, expected);

    // Check name.
    precheck(tpoints, "name");
    // XXX
    // postcheck(engine, tpoints, db, expected);
    std::cout << "  not tested\n";

    // Check active_host_checks.
    precheck(tpoints, "active_host_checks");
    engine_config.set_directive("execute_host_checks", "1");
    expected[0][2] = true;
    postcheck(engine, tpoints, db, expected);

    // Check active_service_checks.
    precheck(tpoints, "active_service_checks");
    engine_config.set_directive("execute_service_checks", "1");
    expected[0][3] = true;
    postcheck(engine, tpoints, db, expected);

    // Check check_hosts_freshness.
    precheck(tpoints, "check_hosts_freshness");
    engine_config.set_directive("check_host_freshness", "1");
    expected[0][4] = true;
    postcheck(engine, tpoints, db, expected);

    // Check check_service_freshness.
    precheck(tpoints, "check_service_freshness");
    engine_config.set_directive("check_service_freshness", "1");
    expected[0][5] = true;
    postcheck(engine, tpoints, db, expected);

    // Check event_handlers.
    precheck(tpoints, "event_handlers");
    engine_config.set_directive("enable_event_handlers", "1");
    expected[0][9] = true;
    postcheck(engine, tpoints, db, expected);

    // Check failure_prediction.
    precheck(tpoints, "failure_prediction");
    engine_config.set_directive("enable_failure_prediction", "1");
    expected[0][10] = true;
    postcheck(engine, tpoints, db, expected);

    // Check flap_detection.
    precheck(tpoints, "flap_detection");
    engine_config.set_directive("enable_flap_detection", "1");
    expected[0][11] = true;
    postcheck(engine, tpoints, db, expected);

    // Check global_host_event_handler.
    precheck(tpoints, "global_host_event_handler");
    // XXX
    // postcheck(engine, tpoints, db, expected);
    std::cout << "  not tested\n";

    // Check global_service_event_handler.
    precheck(tpoints, "global_service_event_handler");
    // XXX
    // postcheck(engine, tpoints, db, expected);
    std::cout << "  not tested\n";

    // Check notifications.
    precheck(tpoints, "enable_notifications");
    engine_config.set_directive("enable_notifications", "1");
    expected[0][16] = true;
    postcheck(engine, tpoints, db, expected);

    // Check obsess_over_hosts.
    precheck(tpoints, "obsess_over_hosts");
    engine_config.set_directive("obsess_over_hosts", "1");
    expected[0][17] = true;
    postcheck(engine, tpoints, db, expected);

    // Check obsess_over_services.
    precheck(tpoints, "obsess_over_services");
    engine_config.set_directive("obsess_over_services", "1");
    expected[0][18] = true;
    postcheck(engine, tpoints, db, expected);

    // Check passive_host_checks.
    precheck(tpoints, "passive_host_checks");
    engine_config.set_directive("accept_passive_host_checks", "1");
    expected[0][20] = true;
    postcheck(engine, tpoints, db, expected);

    // Check passive_service_checks.
    precheck(tpoints, "passive_service_checks");
    engine_config.set_directive("accept_passive_service_checks", "1");
    expected[0][21] = true;
    postcheck(engine, tpoints, db, expected);

    // Check version.
    precheck(tpoints, "version");
    // XXX
    // postcheck(engine, tpoints, db, expected);
    std::cout << "  not tested\n";

    // Check last_command_check.
    precheck(tpoints, "last_command_check");
    // XXX
    // postcheck(engine, tpoints, db, expected);
    std::cout << "  not tested\n";

    // Check end_time.
    precheck(tpoints, "end_time");
    engine.stop();
    test::sleep_for(2);
    tpoints.store();
    {
      test::predicate expected_end_time[][3] = {
        { 42u, test::predicate(tpoints.prelast(), tpoints.last() + 1),
          false },
        { test::predicate() }
      };
      db.check_content(
           "SELECT instance_id, end_time, running FROM instances",
           expected_end_time);
    }
    std::cout << "  passed\n";

    // Check outdated.
    precheck(tpoints, "outdated");
    // XXX
    // postcheck(engine, tpoints, db, expected);
    std::cout << "  not tested\n";

    // Check deleted.
    precheck(tpoints, "deleted");
    // XXX
    // postcheck(engine, tpoints, db, expected);
    std::cout << "  not tested\n";

    // Success.
    error = false;
    db.set_remove_db_on_close(true);
    broker.stop();
  }
  catch (std::exception const& e) {
    std::cout << "  " << e.what() << "\n";
  }
  catch (...) {
    std::cout << "  unknown exception\n";
  }

  return (error ? EXIT_FAILURE : EXIT_SUCCESS);
}
<commit_msg>test: minor fixes to unit test.<commit_after>/*
** Copyright 2015 Centreon
**
** 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.
**
** For more information : contact@centreon.com
*/

#include <cstdlib>
#include <iostream>
#include "test/cbd.hh"
#include "test/centengine.hh"
#include "test/centengine_config.hh"
#include "test/db.hh"
#include "test/file.hh"
#include "test/misc.hh"
#include "test/predicate.hh"
#include "test/time_points.hh"
#include "test/vars.hh"

using namespace com::centreon::broker;

#define TEST_NAME "rtmonitoring_v2_instances"
#define DB_NAME "broker_" TEST_NAME

// Check count.
static int check_number(0);

/**
 *  Precheck routine.
 */
static void precheck(test::time_points& tpoints, char const* name) {
  ++check_number;
  std::cout << "check #" << check_number << " (" << name << ")\n";
  tpoints.store();
  return ;
}

/**
 *  Postcheck routine.
 */
static void postcheck(
              test::centengine& engine,
              test::time_points& tpoints,
              test::db& db,
              test::predicate expected[][25]) {
  static std::string check_query(
    "SELECT instance_id, name, active_host_checks,"
    "       active_service_checks, check_hosts_freshness,"
    "       check_services_freshness, deleted, end_time, engine,"
    "       event_handlers, failure_prediction, flap_detection,"
    "       global_host_event_handler,"
    "       global_service_event_handler, last_alive,"
    "       last_command_check, notifications, obsess_over_hosts,"
    "       obsess_over_services, outdated, passive_host_checks,"
    "       passive_service_checks, pid, running, start_time"
    // XXX : not checked yet       "       version"
    "  FROM instances");
  engine.reload();
  test::sleep_for(3);
  tpoints.store();
  expected[0][14]
    = test::predicate(tpoints.prelast(), tpoints.last() + 1);
  db.check_content(check_query, expected);
  std::cout << "  passed\n";
  return ;
}

/**
 *  Check that the instances table work properly.
 *
 *  @return EXIT_SUCCESS on success.
 */
int main() {
  // Error flag.
  bool error(true);

  try {
    // Database.
    char const* tables[] = { "instances", NULL };
    test::db db(DB_NAME, tables);

    // Monitoring broker.
    test::file cbd_cfg;
    cbd_cfg.set_template(
      PROJECT_SOURCE_DIR "/test/cfg/sql.xml.in");
    cbd_cfg.set("BROKER_ID", "84");
    cbd_cfg.set("BROKER_NAME", TEST_NAME "-cbd");
    cbd_cfg.set("POLLER_ID", "42");
    cbd_cfg.set("POLLER_NAME", "my-poller");
    cbd_cfg.set("TCP_PORT", "5571");
    cbd_cfg.set("DB_NAME", DB_NAME);
    cbd_cfg.set(
      "SQL_ADDITIONAL",
      "<write_filters>"
      "  <category>neb:instance</category>"
      "  <category>neb:instance_status</category>"
      "</write_filters>");
    test::cbd broker;
    broker.set_config_file(cbd_cfg.generate());
    broker.start();
    test::sleep_for(1);

    // Monitoring engine.
    test::file cbmod_cfg;
    cbmod_cfg.set_template(
      PROJECT_SOURCE_DIR "/test/cfg/tcp.xml.in");
    cbmod_cfg.set("BROKER_ID", "83");
    cbmod_cfg.set("BROKER_NAME", TEST_NAME "-cbmod");
    cbmod_cfg.set("POLLER_ID", "42");
    cbmod_cfg.set("POLLER_NAME", "my-poller");
    cbmod_cfg.set("TCP_HOST", "localhost");
    cbmod_cfg.set("TCP_PORT", "5571");
    test::centengine_config engine_config;
    engine_config.generate_hosts(3);
    engine_config.generate_services(5);
    engine_config.set_cbmod_cfg_file(cbmod_cfg.generate());
    engine_config.set_directive("accept_passive_host_checks", "0");
    engine_config.set_directive("accept_passive_service_checks", "0");
    engine_config.set_directive("check_host_freshness", "0");
    engine_config.set_directive("check_service_freshness", "0");
    engine_config.set_directive("enable_event_handlers", "0");
    engine_config.set_directive("enable_failure_prediction", "0");
    engine_config.set_directive("enable_flap_detection", "0");
    engine_config.set_directive("enable_notifications", "0");
    engine_config.set_directive("execute_host_checks", "0");
    engine_config.set_directive("execute_service_checks", "0");
    engine_config.set_directive("obsess_over_hosts", "0");
    engine_config.set_directive("obsess_over_services", "0");
    test::centengine engine(&engine_config);

    // Time points.
    test::time_points tpoints;

    // Check default entry.
    precheck(tpoints, "engine, last_alive, pid, running, start_time");
    engine.start();
    test::sleep_for(1);
    test::predicate expected[][25] = {
      { 42u, "my-poller", false, false, false, false, false,
        test::predicate(test::predicate::type_null), "Centreon Engine",
        false, false, false, "", "",
        test::predicate(tpoints.prelast(), tpoints.last() + 1),
        test::predicate(test::predicate::type_null), false, false,
        false, false, false, false,
        true, // PID will be converted to boolean, any non-0 will match.
        true, test::predicate(tpoints.prelast(), tpoints.last() + 1) },
      { test::predicate() }
    };
    postcheck(engine, tpoints, db, expected);

    // Check name.
    precheck(tpoints, "name");
    // XXX
    // postcheck(engine, tpoints, db, expected);
    std::cout << "  not tested\n";

    // Check active_host_checks.
    precheck(tpoints, "active_host_checks");
    engine_config.set_directive("execute_host_checks", "1");
    expected[0][2] = true;
    postcheck(engine, tpoints, db, expected);

    // Check active_service_checks.
    precheck(tpoints, "active_service_checks");
    engine_config.set_directive("execute_service_checks", "1");
    expected[0][3] = true;
    postcheck(engine, tpoints, db, expected);

    // Check check_hosts_freshness.
    precheck(tpoints, "check_hosts_freshness");
    engine_config.set_directive("check_host_freshness", "1");
    expected[0][4] = true;
    postcheck(engine, tpoints, db, expected);

    // Check check_service_freshness.
    precheck(tpoints, "check_service_freshness");
    engine_config.set_directive("check_service_freshness", "1");
    expected[0][5] = true;
    postcheck(engine, tpoints, db, expected);

    // Check event_handlers.
    precheck(tpoints, "event_handlers");
    engine_config.set_directive("enable_event_handlers", "1");
    expected[0][9] = true;
    postcheck(engine, tpoints, db, expected);

    // Check failure_prediction.
    precheck(tpoints, "failure_prediction");
    engine_config.set_directive("enable_failure_prediction", "1");
    expected[0][10] = true;
    postcheck(engine, tpoints, db, expected);

    // Check flap_detection.
    precheck(tpoints, "flap_detection");
    engine_config.set_directive("enable_flap_detection", "1");
    expected[0][11] = true;
    postcheck(engine, tpoints, db, expected);

    // Check global_host_event_handler.
    precheck(tpoints, "global_host_event_handler");
    // XXX
    // postcheck(engine, tpoints, db, expected);
    std::cout << "  not tested\n";

    // Check global_service_event_handler.
    precheck(tpoints, "global_service_event_handler");
    // XXX
    // postcheck(engine, tpoints, db, expected);
    std::cout << "  not tested\n";

    // Check notifications.
    precheck(tpoints, "enable_notifications");
    engine_config.set_directive("enable_notifications", "1");
    expected[0][16] = true;
    postcheck(engine, tpoints, db, expected);

    // Check obsess_over_hosts.
    precheck(tpoints, "obsess_over_hosts");
    engine_config.set_directive("obsess_over_hosts", "1");
    expected[0][17] = true;
    postcheck(engine, tpoints, db, expected);

    // Check obsess_over_services.
    precheck(tpoints, "obsess_over_services");
    engine_config.set_directive("obsess_over_services", "1");
    expected[0][18] = true;
    postcheck(engine, tpoints, db, expected);

    // Check passive_host_checks.
    precheck(tpoints, "passive_host_checks");
    engine_config.set_directive("accept_passive_host_checks", "1");
    expected[0][20] = true;
    postcheck(engine, tpoints, db, expected);

    // Check passive_service_checks.
    precheck(tpoints, "passive_service_checks");
    engine_config.set_directive("accept_passive_service_checks", "1");
    expected[0][21] = true;
    postcheck(engine, tpoints, db, expected);

    // Check version.
    precheck(tpoints, "version");
    // XXX
    // postcheck(engine, tpoints, db, expected);
    std::cout << "  not tested\n";

    // Check last_command_check.
    precheck(tpoints, "last_command_check");
    // XXX
    // postcheck(engine, tpoints, db, expected);
    std::cout << "  not tested\n";

    // Check end_time.
    precheck(tpoints, "end_time");
    engine.stop();
    test::sleep_for(2);
    tpoints.store();
    {
      test::predicate expected_end_time[][3] = {
        { 42u, test::predicate(tpoints.prelast(), tpoints.last() + 1),
          false },
        { test::predicate() }
      };
      db.check_content(
           "SELECT instance_id, end_time, running FROM instances",
           expected_end_time);
    }
    std::cout << "  passed\n";

    // Check outdated.
    precheck(tpoints, "outdated");
    // XXX
    // postcheck(engine, tpoints, db, expected);
    std::cout << "  not tested\n";

    // Check deleted.
    precheck(tpoints, "deleted");
    // XXX
    // postcheck(engine, tpoints, db, expected);
    std::cout << "  not tested\n";

    // Success.
    error = false;
    db.set_remove_db_on_close(true);
    broker.stop();
  }
  catch (std::exception const& e) {
    std::cout << "  " << e.what() << "\n";
  }
  catch (...) {
    std::cout << "  unknown exception\n";
  }

  return (error ? EXIT_FAILURE : EXIT_SUCCESS);
}
<|endoftext|>


<commit_before>/*******************************************************************************
 *
 * MIT License
 *
 * Copyright (c) 2017 Advanced Micro Devices, Inc.
 *
 * 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.
 *
 *******************************************************************************/

#include "miopen/handle.hpp"
#include "miopen/legacy_exhaustive_search.hpp"
#include "miopen/solver.hpp"

namespace miopen {
namespace solver {

bool ConvOclDirectFwd::IsApplicable(const ConvolutionContext& params) const
{
    // clang-format off
    return params.kernel_stride0 == params.kernel_stride1
        && params.pad0 == params.pad1
        && !(params.kernel_size0 == 1 && params.kernel_size1 == 1)
        && !(params.direction.IsBackwardData() && (params.kernel_stride0 > 2 || params.kernel_stride1 > 2))
        /// \todo Workaround to avoid LDS overallocation issue:
        && !(params.direction.IsForward() && params.float_size == 16 && params.kernel_size0 == 11 && params.kernel_size1 == 11)
        /// \todo Workaround to avoid FP16 precision issue:
        /// While MIOpenConvUni is up to 4x faster than MIOpenCDFGen (even not auto-tuned),
        /// it seems that is has 4x..20x worse precision, and some "test_conv --half" tests fail.
        && !(params.direction.IsForward() && params.float_size == 16);
    // clang-format on
}

ConvSolution ConvOclDirectFwd::GetSolution(const ConvolutionContext& params,
                                           const LegacyPerformanceConfig& searched_params) const
{
    ConvSolution result;

    // std::size_t localMemSize = params.stream.GetLocalMemorySize();

    searched_params.CopyTo(result);
    auto pad0 = params.pad0;
    auto pad1 = params.pad1;

    auto hw_wave_sz = 64;
    // auto dev_local_mem_sz = localMemSize; // in bytes

    if(!params.direction.IsForward())
    {
        // backward
        pad0 = params.kernel_size0 - 1 - pad0;
        pad1 = params.kernel_size1 - 1 - pad1;
    }

    result.n_in_data_tiles = std::min(params.n_inputs, searched_params.n_in_data_tiles);
    result.n_out_pix_tiles = std::min(params.n_outputs, searched_params.n_out_pix_tiles);

    // hacky fix of the incorrect kernel local memory address calculation for data
    result.out_pix_tile1 = (!params.direction.IsForward() && params.kernel_stride1 > 1)
                               ? params.kernel_stride1
                               : searched_params.out_pix_tile1;
    result.out_pix_tile0 = (!params.direction.IsForward() && params.kernel_stride0 > 1)
                               ? params.kernel_stride0
                               : searched_params.out_pix_tile0;

    if(result.out_pix_tile1 == 0 || result.out_pix_tile0 == 0 /* DIV/0 */)
    {
        MIOPEN_LOG_E("result.out_pix_tile1 == 0 || result.out_pix_tile0 == 0");
        return ConvSolution(miopenStatusInternalError);
    }
    result.grp_tile0 = std::max(8, (result.in_tile0 / result.out_pix_tile0));
    result.grp_tile1 = std::max(8, (result.in_tile1 / result.out_pix_tile1));
    result.in_tile0  = result.grp_tile0 * result.out_pix_tile0;
    result.in_tile1  = result.grp_tile1 * result.out_pix_tile1;

    int alu_tile0    = (result.in_tile0 + result.out_pix_tile0 - 1) / result.out_pix_tile0;
    int alu_tile1    = (result.in_tile1 + result.out_pix_tile1 - 1) / result.out_pix_tile1;
    int alu_tiles_sz = (alu_tile0 * alu_tile1);
    if(alu_tiles_sz > 256 || alu_tiles_sz == 0 /* DIV/0 */)
    {
        MIOPEN_LOG_E("need out pix size ajustments (alu_tiles_sz > 256 || alu_tiles_sz == 0)");
        return ConvSolution(miopenStatusInternalError);
    }

    int n_alus_total = (result.grp_tile0 * result.grp_tile1);

    result.n_stacks = std::min(result.n_stacks, (n_alus_total + alu_tiles_sz - 1) / alu_tiles_sz);
    result.n_stacks = std::min(params.batch_sz, result.n_stacks);

    if(result.n_stacks == 0 /* DIV/0 */)
    {
        MIOPEN_LOG_E("result.n_stacks == 0");
        return ConvSolution(miopenStatusInternalError);
    }
    int n_alus_perstack = (n_alus_total + result.n_stacks - 1) / result.n_stacks;

    int n_read_procs;
    if((result.grp_tile1 * result.grp_tile0) <=
       static_cast<float>(result.in_tile1 * result.in_tile0))
    {
        n_read_procs = result.grp_tile1 * result.grp_tile0;
    }
    else
    {
        float proc_data_ratio = static_cast<float>(result.in_tile1 * result.in_tile0) /
                                static_cast<float>(result.grp_tile1 * result.grp_tile0);
        n_read_procs = (proc_data_ratio <= 0.25)
                           ? (result.grp_tile1 * result.grp_tile0) / 4
                           : (proc_data_ratio <= 0.5) ? (result.grp_tile1 * result.grp_tile0) / 2
                                                      : (result.grp_tile1 * result.grp_tile0);
    }

    int n_out_tile_blocks0 = (params.out_width + result.in_tile0 - 1) / (result.in_tile0);
    int n_out_tile_blocks1 = (params.out_height + result.in_tile1 - 1) / (result.in_tile1);

    int n_alu_tiles_perstack = (n_alus_perstack + alu_tiles_sz - 1) / alu_tiles_sz;
    int n_out_tiles_perstack = n_alu_tiles_perstack * result.n_out_pix_tiles;

    n_out_tiles_perstack = std::min(n_out_tiles_perstack, params.n_outputs);

    KernelInfo kernel_params;

    kernel_params.comp_options =
        std::string(" -DMLO_HW_WAVE_SZ=") + std::to_string(static_cast<long long>(hw_wave_sz)) +
        std::string(" -DMLO_DIR_FORWARD=") + (params.direction.IsForward() ? "1" : "0") +
        std::string(" -DMLO_FILTER_SIZE0=") +
        std::to_string(static_cast<long long>(params.kernel_size0)) +
        std::string(" -DMLO_FILTER_SIZE1=") +
        std::to_string(static_cast<long long>(params.kernel_size1)) +
        std::string(" -DMLO_FILTER_PAD0=") + std::to_string(static_cast<long long>(pad0)) +
        std::string(" -DMLO_FILTER_PAD1=") + std::to_string(static_cast<long long>(pad1)) +
        std::string(" -DMLO_FILTER_STRIDE0=") +
        std::to_string(static_cast<long long>(params.kernel_stride0)) +
        std::string(" -DMLO_FILTER_STRIDE1=") +
        std::to_string(static_cast<long long>(params.kernel_stride1)) +
        std::string(" -DMLO_N_OUTPUTS=") +
        std::to_string(static_cast<long long>(params.n_outputs)) + std::string(" -DMLO_N_INPUTS=") +
        std::to_string(static_cast<long long>(params.n_inputs)) + std::string(" -DMLO_BATCH_SZ=") +
        std::to_string(static_cast<long long>(params.batch_sz)) + std::string(" -DMLO_OUT_WIDTH=") +
        std::to_string(static_cast<long long>(params.out_width)) +
        std::string(" -DMLO_OUT_HEIGHT=") +
        std::to_string(static_cast<long long>(params.out_height)) +
        std::string(" -DMLO_OUT_BATCH_STRIDE=") +
        std::to_string(static_cast<long long>(params.out_batch_stride)) +
        std::string(" -DMLO_OUT_CHANNEL_STRIDE=") +
        std::to_string(static_cast<long long>(params.out_channel_stride)) +
        std::string(" -DMLO_OUT_STRIDE=") +
        std::to_string(static_cast<long long>(params.out_stride)) +
        std::string(" -DMLO_IN_WIDTH=") + std::to_string(static_cast<long long>(params.in_width)) +
        std::string(" -DMLO_IN_HEIGHT=") +
        std::to_string(static_cast<long long>(params.in_height)) +
        std::string(" -DMLO_IN_BATCH_STRIDE=") +
        std::to_string(static_cast<long long>(params.in_batch_stride)) +
        std::string(" -DMLO_IN_CHANNEL_STRIDE=") +
        std::to_string(static_cast<long long>(params.in_channel_stride)) +
        std::string(" -DMLO_IN_STRIDE=") + std::to_string(static_cast<long long>(params.in_stride))
        // algorithm parameters
        + std::string(" -DMLO_IN_TILE0=") +
        std::to_string(static_cast<long long>(result.in_tile0)) // size of input data per ALU plane
        + std::string(" -DMLO_IN_TILE1=") +
        std::to_string(static_cast<long long>(result.in_tile1)) // size of input data per ALU plane
        + std::string(" -DMLO_GRP_TILE0=") +
        std::to_string(static_cast<long long>(result.grp_tile0)) // # of ALUs (group size)
        + std::string(" -DMLO_GRP_TILE1=") +
        std::to_string(static_cast<long long>(result.grp_tile1)) //
        + std::string(" -DMLO_OUT_TILE0=") +
        std::to_string(
            static_cast<long long>(result.out_pix_tile0)) // size of ouptput tile per wk-item (ALU))
        + std::string(" -DMLO_OUT_TILE1=") +
        std::to_string(static_cast<long long>(result.out_pix_tile1)) //
        + std::string(" -DMLO_N_STACKS=") +
        std::to_string(static_cast<long long>(result.n_stacks)) // # of diff stacks (part of batch).
        + std::string(" -DMLO_N_OUT_TILES=") +
        std::to_string(static_cast<long long>(
            result.n_out_pix_tiles)) // # output pixel tiles per wk-item (ALU)
        + std::string(" -DMLO_N_OUT_TILES_PERSTACK=") +
        std::to_string(static_cast<long long>(n_out_tiles_perstack)) +
        std::string(" -DMLO_N_IN_TILES_PERSTACK=") +
        std::to_string(static_cast<long long>(
            result.n_in_data_tiles)) // total # of blocks of different inputs in LDS
        + std::string(" -DMLO_N_READ_PROCS=") +
        std::to_string(static_cast<long long>(n_read_procs)) + std::string(" -DMLO_CONV_BIAS=") +
        std::to_string(static_cast<long long>(params.bias)) + std::string(" -DMLO_ALU_VTILE0=") +
        std::to_string(static_cast<long long>(alu_tile0)) + std::string(" -DMLO_ALU_VTILE1=") +
        std::to_string(static_cast<long long>(alu_tile1)) + params.general_compile_options;

    kernel_params.l_wk.push_back(result.grp_tile1 * result.grp_tile0);
    kernel_params.l_wk.push_back(1);
    kernel_params.l_wk.push_back(1);

    size_t gbl_wk0 = n_out_tile_blocks0 * n_out_tile_blocks1;

    if(n_out_tiles_perstack == 0 /* DIV/0 */)
    {
        MIOPEN_LOG_E("n_out_tiles_perstack == 0");
        return ConvSolution(miopenStatusInternalError);
    }
    size_t gbl_wk1 = (params.n_outputs + n_out_tiles_perstack - 1) / n_out_tiles_perstack;
    size_t gbl_wk2 = (params.batch_sz + result.n_stacks - 1) / result.n_stacks;

    kernel_params.g_wk.push_back(gbl_wk0 * kernel_params.l_wk[0]);
    kernel_params.g_wk.push_back(gbl_wk1);
    kernel_params.g_wk.push_back(gbl_wk2);

    kernel_params.kernel_file = "MIOpenConvDirUni.cl";
    kernel_params.kernel_name = "MIOpenConvUni";

    result.construction_params.push_back(kernel_params);
    return result;
}
} // namespace solver
} // namespace miopen
<commit_msg>select-fastest-solution(27) Narrowed FP16 fwd conv fix (exclusions in MIOpenConvUni).<commit_after>/*******************************************************************************
 *
 * MIT License
 *
 * Copyright (c) 2017 Advanced Micro Devices, Inc.
 *
 * 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.
 *
 *******************************************************************************/

#include "miopen/handle.hpp"
#include "miopen/legacy_exhaustive_search.hpp"
#include "miopen/solver.hpp"

namespace miopen {
namespace solver {

bool ConvOclDirectFwd::IsApplicable(const ConvolutionContext& params) const
{
    // clang-format off
    return params.kernel_stride0 == params.kernel_stride1
        && params.pad0 == params.pad1
        && !(params.kernel_size0 == 1 && params.kernel_size1 == 1)
        && !(params.direction.IsBackwardData() && (params.kernel_stride0 > 2 || params.kernel_stride1 > 2))
        /// \todo Workaround to avoid LDS overallocation issue:
        && !(params.direction.IsForward()
            && params.float_size == 16
            && params.kernel_size0 == 11
            && params.kernel_size1 == 11
            && params.kernel_stride0 == 4)
        /// \todo Workaround to avoid FP16 precision issue:
        /// While MIOpenConvUni is up to 4x faster than MIOpenCDFGen (even not auto-tuned),
        /// it seems that is has 4x..20x worse precision, and some "test_conv --half" tests fail.
        && !(params.direction.IsForward()
            && params.float_size == 16
            && params.kernel_stride0 == 2);
    // clang-format on
}

ConvSolution ConvOclDirectFwd::GetSolution(const ConvolutionContext& params,
                                           const LegacyPerformanceConfig& searched_params) const
{
    ConvSolution result;

    // std::size_t localMemSize = params.stream.GetLocalMemorySize();

    searched_params.CopyTo(result);
    auto pad0 = params.pad0;
    auto pad1 = params.pad1;

    auto hw_wave_sz = 64;
    // auto dev_local_mem_sz = localMemSize; // in bytes

    if(!params.direction.IsForward())
    {
        // backward
        pad0 = params.kernel_size0 - 1 - pad0;
        pad1 = params.kernel_size1 - 1 - pad1;
    }

    result.n_in_data_tiles = std::min(params.n_inputs, searched_params.n_in_data_tiles);
    result.n_out_pix_tiles = std::min(params.n_outputs, searched_params.n_out_pix_tiles);

    // hacky fix of the incorrect kernel local memory address calculation for data
    result.out_pix_tile1 = (!params.direction.IsForward() && params.kernel_stride1 > 1)
                               ? params.kernel_stride1
                               : searched_params.out_pix_tile1;
    result.out_pix_tile0 = (!params.direction.IsForward() && params.kernel_stride0 > 1)
                               ? params.kernel_stride0
                               : searched_params.out_pix_tile0;

    if(result.out_pix_tile1 == 0 || result.out_pix_tile0 == 0 /* DIV/0 */)
    {
        MIOPEN_LOG_E("result.out_pix_tile1 == 0 || result.out_pix_tile0 == 0");
        return ConvSolution(miopenStatusInternalError);
    }
    result.grp_tile0 = std::max(8, (result.in_tile0 / result.out_pix_tile0));
    result.grp_tile1 = std::max(8, (result.in_tile1 / result.out_pix_tile1));
    result.in_tile0  = result.grp_tile0 * result.out_pix_tile0;
    result.in_tile1  = result.grp_tile1 * result.out_pix_tile1;

    int alu_tile0    = (result.in_tile0 + result.out_pix_tile0 - 1) / result.out_pix_tile0;
    int alu_tile1    = (result.in_tile1 + result.out_pix_tile1 - 1) / result.out_pix_tile1;
    int alu_tiles_sz = (alu_tile0 * alu_tile1);
    if(alu_tiles_sz > 256 || alu_tiles_sz == 0 /* DIV/0 */)
    {
        MIOPEN_LOG_E("need out pix size ajustments (alu_tiles_sz > 256 || alu_tiles_sz == 0)");
        return ConvSolution(miopenStatusInternalError);
    }

    int n_alus_total = (result.grp_tile0 * result.grp_tile1);

    result.n_stacks = std::min(result.n_stacks, (n_alus_total + alu_tiles_sz - 1) / alu_tiles_sz);
    result.n_stacks = std::min(params.batch_sz, result.n_stacks);

    if(result.n_stacks == 0 /* DIV/0 */)
    {
        MIOPEN_LOG_E("result.n_stacks == 0");
        return ConvSolution(miopenStatusInternalError);
    }
    int n_alus_perstack = (n_alus_total + result.n_stacks - 1) / result.n_stacks;

    int n_read_procs;
    if((result.grp_tile1 * result.grp_tile0) <=
       static_cast<float>(result.in_tile1 * result.in_tile0))
    {
        n_read_procs = result.grp_tile1 * result.grp_tile0;
    }
    else
    {
        float proc_data_ratio = static_cast<float>(result.in_tile1 * result.in_tile0) /
                                static_cast<float>(result.grp_tile1 * result.grp_tile0);
        n_read_procs = (proc_data_ratio <= 0.25)
                           ? (result.grp_tile1 * result.grp_tile0) / 4
                           : (proc_data_ratio <= 0.5) ? (result.grp_tile1 * result.grp_tile0) / 2
                                                      : (result.grp_tile1 * result.grp_tile0);
    }

    int n_out_tile_blocks0 = (params.out_width + result.in_tile0 - 1) / (result.in_tile0);
    int n_out_tile_blocks1 = (params.out_height + result.in_tile1 - 1) / (result.in_tile1);

    int n_alu_tiles_perstack = (n_alus_perstack + alu_tiles_sz - 1) / alu_tiles_sz;
    int n_out_tiles_perstack = n_alu_tiles_perstack * result.n_out_pix_tiles;

    n_out_tiles_perstack = std::min(n_out_tiles_perstack, params.n_outputs);

    KernelInfo kernel_params;

    kernel_params.comp_options =
        std::string(" -DMLO_HW_WAVE_SZ=") + std::to_string(static_cast<long long>(hw_wave_sz)) +
        std::string(" -DMLO_DIR_FORWARD=") + (params.direction.IsForward() ? "1" : "0") +
        std::string(" -DMLO_FILTER_SIZE0=") +
        std::to_string(static_cast<long long>(params.kernel_size0)) +
        std::string(" -DMLO_FILTER_SIZE1=") +
        std::to_string(static_cast<long long>(params.kernel_size1)) +
        std::string(" -DMLO_FILTER_PAD0=") + std::to_string(static_cast<long long>(pad0)) +
        std::string(" -DMLO_FILTER_PAD1=") + std::to_string(static_cast<long long>(pad1)) +
        std::string(" -DMLO_FILTER_STRIDE0=") +
        std::to_string(static_cast<long long>(params.kernel_stride0)) +
        std::string(" -DMLO_FILTER_STRIDE1=") +
        std::to_string(static_cast<long long>(params.kernel_stride1)) +
        std::string(" -DMLO_N_OUTPUTS=") +
        std::to_string(static_cast<long long>(params.n_outputs)) + std::string(" -DMLO_N_INPUTS=") +
        std::to_string(static_cast<long long>(params.n_inputs)) + std::string(" -DMLO_BATCH_SZ=") +
        std::to_string(static_cast<long long>(params.batch_sz)) + std::string(" -DMLO_OUT_WIDTH=") +
        std::to_string(static_cast<long long>(params.out_width)) +
        std::string(" -DMLO_OUT_HEIGHT=") +
        std::to_string(static_cast<long long>(params.out_height)) +
        std::string(" -DMLO_OUT_BATCH_STRIDE=") +
        std::to_string(static_cast<long long>(params.out_batch_stride)) +
        std::string(" -DMLO_OUT_CHANNEL_STRIDE=") +
        std::to_string(static_cast<long long>(params.out_channel_stride)) +
        std::string(" -DMLO_OUT_STRIDE=") +
        std::to_string(static_cast<long long>(params.out_stride)) +
        std::string(" -DMLO_IN_WIDTH=") + std::to_string(static_cast<long long>(params.in_width)) +
        std::string(" -DMLO_IN_HEIGHT=") +
        std::to_string(static_cast<long long>(params.in_height)) +
        std::string(" -DMLO_IN_BATCH_STRIDE=") +
        std::to_string(static_cast<long long>(params.in_batch_stride)) +
        std::string(" -DMLO_IN_CHANNEL_STRIDE=") +
        std::to_string(static_cast<long long>(params.in_channel_stride)) +
        std::string(" -DMLO_IN_STRIDE=") + std::to_string(static_cast<long long>(params.in_stride))
        // algorithm parameters
        + std::string(" -DMLO_IN_TILE0=") +
        std::to_string(static_cast<long long>(result.in_tile0)) // size of input data per ALU plane
        + std::string(" -DMLO_IN_TILE1=") +
        std::to_string(static_cast<long long>(result.in_tile1)) // size of input data per ALU plane
        + std::string(" -DMLO_GRP_TILE0=") +
        std::to_string(static_cast<long long>(result.grp_tile0)) // # of ALUs (group size)
        + std::string(" -DMLO_GRP_TILE1=") +
        std::to_string(static_cast<long long>(result.grp_tile1)) //
        + std::string(" -DMLO_OUT_TILE0=") +
        std::to_string(
            static_cast<long long>(result.out_pix_tile0)) // size of ouptput tile per wk-item (ALU))
        + std::string(" -DMLO_OUT_TILE1=") +
        std::to_string(static_cast<long long>(result.out_pix_tile1)) //
        + std::string(" -DMLO_N_STACKS=") +
        std::to_string(static_cast<long long>(result.n_stacks)) // # of diff stacks (part of batch).
        + std::string(" -DMLO_N_OUT_TILES=") +
        std::to_string(static_cast<long long>(
            result.n_out_pix_tiles)) // # output pixel tiles per wk-item (ALU)
        + std::string(" -DMLO_N_OUT_TILES_PERSTACK=") +
        std::to_string(static_cast<long long>(n_out_tiles_perstack)) +
        std::string(" -DMLO_N_IN_TILES_PERSTACK=") +
        std::to_string(static_cast<long long>(
            result.n_in_data_tiles)) // total # of blocks of different inputs in LDS
        + std::string(" -DMLO_N_READ_PROCS=") +
        std::to_string(static_cast<long long>(n_read_procs)) + std::string(" -DMLO_CONV_BIAS=") +
        std::to_string(static_cast<long long>(params.bias)) + std::string(" -DMLO_ALU_VTILE0=") +
        std::to_string(static_cast<long long>(alu_tile0)) + std::string(" -DMLO_ALU_VTILE1=") +
        std::to_string(static_cast<long long>(alu_tile1)) + params.general_compile_options;

    kernel_params.l_wk.push_back(result.grp_tile1 * result.grp_tile0);
    kernel_params.l_wk.push_back(1);
    kernel_params.l_wk.push_back(1);

    size_t gbl_wk0 = n_out_tile_blocks0 * n_out_tile_blocks1;

    if(n_out_tiles_perstack == 0 /* DIV/0 */)
    {
        MIOPEN_LOG_E("n_out_tiles_perstack == 0");
        return ConvSolution(miopenStatusInternalError);
    }
    size_t gbl_wk1 = (params.n_outputs + n_out_tiles_perstack - 1) / n_out_tiles_perstack;
    size_t gbl_wk2 = (params.batch_sz + result.n_stacks - 1) / result.n_stacks;

    kernel_params.g_wk.push_back(gbl_wk0 * kernel_params.l_wk[0]);
    kernel_params.g_wk.push_back(gbl_wk1);
    kernel_params.g_wk.push_back(gbl_wk2);

    kernel_params.kernel_file = "MIOpenConvDirUni.cl";
    kernel_params.kernel_name = "MIOpenConvUni";

    result.construction_params.push_back(kernel_params);
    return result;
}
} // namespace solver
} // namespace miopen
<|endoftext|>


<commit_before>#include "unlimited.h"

#include "test/test_bitcoin.h"
#include "../consensus/consensus.h"

#include <boost/algorithm/string.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/lexical_cast.hpp>

using namespace std;

// Defined in rpc_tests.cpp not bitcoin-cli.cpp
extern UniValue CallRPC(string strMethod);

BOOST_FIXTURE_TEST_SUITE(excessiveblock_test, TestingSetup)

BOOST_AUTO_TEST_CASE(rpc_excessive)
{
    BOOST_CHECK_NO_THROW(CallRPC("getexcessiveblock"));

    BOOST_CHECK_NO_THROW(CallRPC("getminingmaxblock"));

    BOOST_CHECK_THROW(CallRPC("setexcessiveblock not_uint"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("setexcessiveblock 1000000 not_uint"), boost::bad_lexical_cast);
    BOOST_CHECK_THROW(CallRPC("setexcessiveblock 1000000 -1"), boost::bad_lexical_cast);
    BOOST_CHECK_THROW(CallRPC("setexcessiveblock -1 0"), boost::bad_lexical_cast);

    BOOST_CHECK_THROW(CallRPC("setexcessiveblock 1000 1"), runtime_error);
    BOOST_CHECK_NO_THROW(CallRPC("setminingmaxblock 1000"));
    BOOST_CHECK_NO_THROW(CallRPC("setexcessiveblock 1000 1"));

    BOOST_CHECK_THROW(CallRPC("setexcessiveblock 1000 0 0"), runtime_error);

    BOOST_CHECK_THROW(CallRPC("setminingmaxblock"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("setminingmaxblock 100000"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("setminingmaxblock not_uint"),  boost::bad_lexical_cast);
    BOOST_CHECK_THROW(CallRPC("setminingmaxblock -1"),  boost::bad_lexical_cast);
    BOOST_CHECK_THROW(CallRPC("setminingmaxblock 0"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("setminingmaxblock 0 0"), runtime_error);
    BOOST_CHECK_NO_THROW(CallRPC("setminingmaxblock 1000"));
    BOOST_CHECK_NO_THROW(CallRPC("setminingmaxblock 101"));

}

BOOST_AUTO_TEST_CASE(buip005)
{
    string exceptedEB;
    string exceptedAD;
    excessiveBlockSize = 1000000;
    excessiveAcceptDepth = 9999999;
    exceptedEB = "EB1";
    exceptedAD = "AD9999999";
    settingsToUserAgentString();
    BOOST_CHECK_MESSAGE(BUComments.front() == exceptedEB,
                        "EB ought to have been " << exceptedEB << " when excessiveBlockSize = "
                        << excessiveBlockSize << " but was " << BUComments.front());
    BOOST_CHECK_MESSAGE(BUComments.back() == exceptedAD,
                        "AD ought to have been " << exceptedAD << " when excessiveBlockSize = " << excessiveAcceptDepth);
    excessiveBlockSize = 100000;
    excessiveAcceptDepth = 9999999 + 1;
    exceptedEB = "EB0.1";
    exceptedAD = "AD9999999";
    settingsToUserAgentString();
    BOOST_CHECK_MESSAGE(BUComments.front() == exceptedEB,
                        "EB ought to have been " << exceptedEB << " when excessiveBlockSize = "
                        << excessiveBlockSize << " but was " << BUComments.front());
    BOOST_CHECK_MESSAGE(BUComments.back() == exceptedAD,
                        "AD ought to have been " << exceptedAD << " when excessiveBlockSize = " << excessiveAcceptDepth);
    excessiveBlockSize = 10000;
    exceptedEB = "EB0";
    settingsToUserAgentString();
    BOOST_CHECK_MESSAGE(BUComments.front() == exceptedEB,
                        "EB ought to have been " << exceptedEB << " when excessiveBlockSize = "
                        << excessiveBlockSize << " but was " << BUComments.front());
    excessiveBlockSize = 150000;
    exceptedEB = "EB0.1";
    settingsToUserAgentString();
    BOOST_CHECK_MESSAGE(BUComments.front() == exceptedEB,
                        "EB ought to have been rounded to " << exceptedEB << " when excessiveBlockSize = "
                        << excessiveBlockSize << " but was " << BUComments.front());
    excessiveBlockSize = 150000;
    exceptedEB = "EB0.1";
    settingsToUserAgentString();
    BOOST_CHECK_MESSAGE(BUComments.front() == exceptedEB,
                        "EB ought to have been rounded to " << exceptedEB << " when excessiveBlockSize = "
                        << excessiveBlockSize << " but was " << BUComments.front());

    // set back to defaults
    excessiveBlockSize = 1000000;
    excessiveAcceptDepth = 4;
}

BOOST_AUTO_TEST_CASE(excessiveChecks)
{
  CBlock block;

  excessiveBlockSize = 16000000;  // Ignore excessive block size when checking sigops and block effort

  // Check sigops values

  // Maintain compatibility with the old sigops calculator for blocks <= 1MB
  BOOST_CHECK_MESSAGE(false == CheckExcessive(block,BLOCKSTREAM_CORE_MAX_BLOCK_SIZE-1,BLOCKSTREAM_CORE_MAX_BLOCK_SIGOPS,100,100), "improper sigops");
  BOOST_CHECK_MESSAGE(false == CheckExcessive(block,BLOCKSTREAM_CORE_MAX_BLOCK_SIZE-1,BLOCKSTREAM_CORE_MAX_BLOCK_SIGOPS,100,100), "improper sigops");
  BOOST_CHECK_MESSAGE(false == CheckExcessive(block,BLOCKSTREAM_CORE_MAX_BLOCK_SIZE,BLOCKSTREAM_CORE_MAX_BLOCK_SIGOPS,100,100), "improper sigops");

  BOOST_CHECK_MESSAGE(true == CheckExcessive(block,BLOCKSTREAM_CORE_MAX_BLOCK_SIZE-1,BLOCKSTREAM_CORE_MAX_BLOCK_SIGOPS+1,100,100), "improper sigops");
  BOOST_CHECK_MESSAGE(true == CheckExcessive(block,BLOCKSTREAM_CORE_MAX_BLOCK_SIZE,BLOCKSTREAM_CORE_MAX_BLOCK_SIGOPS+1,100,100), "improper sigops");

  // Check sigops > 1MB.
  BOOST_CHECK_MESSAGE(false == CheckExcessive(block,1000000+1,(blockSigopsPerMb.value*2),100,100), "improper sigops");
  BOOST_CHECK_MESSAGE(true == CheckExcessive(block,1000000+1,(blockSigopsPerMb.value*2)+1,100,100), "improper sigops");
  BOOST_CHECK_MESSAGE(true == CheckExcessive(block,(2*1000000),(blockSigopsPerMb.value*2)+1,100,100), "improper sigops");
  BOOST_CHECK_MESSAGE(false == CheckExcessive(block,(2*1000000)+1,(blockSigopsPerMb.value*2)+1,100,100), "improper sigops");

  // Check tx size values
  maxTxSize.value = DEFAULT_LARGEST_TRANSACTION;

  // Within a 1 MB block, a 1MB transaction is not excessive
  BOOST_CHECK_MESSAGE(false == CheckExcessive(block,BLOCKSTREAM_CORE_MAX_BLOCK_SIZE,1,1,BLOCKSTREAM_CORE_MAX_BLOCK_SIZE), "improper max tx");

  // With a > 1 MB block, use the maxTxSize to determine
  BOOST_CHECK_MESSAGE(false == CheckExcessive(block,BLOCKSTREAM_CORE_MAX_BLOCK_SIZE+1,1,1,maxTxSize.value), "improper max tx");
  BOOST_CHECK_MESSAGE(true == CheckExcessive(block,BLOCKSTREAM_CORE_MAX_BLOCK_SIZE+1,1,1,maxTxSize.value+1), "improper max tx");

}

BOOST_AUTO_TEST_CASE(check_validator_rule)
{
    BOOST_CHECK( MiningAndExcessiveBlockValidatorRule(1000000, 1000000));
    BOOST_CHECK( MiningAndExcessiveBlockValidatorRule(16000000, 1000000));
    BOOST_CHECK( MiningAndExcessiveBlockValidatorRule(1000001, 1000000));

    BOOST_CHECK( ! MiningAndExcessiveBlockValidatorRule(1000000, 1000001));
    BOOST_CHECK( ! MiningAndExcessiveBlockValidatorRule(1000000, 16000000));

    BOOST_CHECK( MiningAndExcessiveBlockValidatorRule(1357, 1357));
    BOOST_CHECK( MiningAndExcessiveBlockValidatorRule(161616, 2222));
    BOOST_CHECK( MiningAndExcessiveBlockValidatorRule(88889, 88888));

    BOOST_CHECK( ! MiningAndExcessiveBlockValidatorRule(929292, 929293));
    BOOST_CHECK( ! MiningAndExcessiveBlockValidatorRule(4, 234245));
}

BOOST_AUTO_TEST_CASE(check_excessive_validator)
{
    // fudge global variables....
    maxGeneratedBlock = 1000000;
    excessiveBlockSize = 888;

    unsigned int tmpExcessive = 1000000;
    std::string str;

    str = ExcessiveBlockValidator(tmpExcessive, NULL, true);
    BOOST_CHECK(str.empty());

    excessiveBlockSize = 888;
    str = ExcessiveBlockValidator(tmpExcessive, NULL, false);
    BOOST_CHECK(str.empty());

    str = ExcessiveBlockValidator(tmpExcessive, (unsigned int *) 42, true);
    BOOST_CHECK(str.empty());

    tmpExcessive = maxGeneratedBlock + 1;

    str = ExcessiveBlockValidator(tmpExcessive, NULL, true);
    BOOST_CHECK(str.empty());

    excessiveBlockSize = 888;
    str = ExcessiveBlockValidator(tmpExcessive, NULL, false);
    BOOST_CHECK(str.empty());

    str = ExcessiveBlockValidator(tmpExcessive, (unsigned int *) 42, true);
    BOOST_CHECK(str.empty());

    tmpExcessive = maxGeneratedBlock - 1;

    str = ExcessiveBlockValidator(tmpExcessive, NULL, true);
    BOOST_CHECK(! str.empty());

    str = ExcessiveBlockValidator(tmpExcessive, NULL, false);
    BOOST_CHECK(str.empty());

    str = ExcessiveBlockValidator(tmpExcessive, (unsigned int *) 42, true);
    BOOST_CHECK(! str.empty());
}

BOOST_AUTO_TEST_CASE(check_generated_block_validator)
{
    // fudge global variables....
    maxGeneratedBlock = 888;
    excessiveBlockSize = 1000000;

    uint64_t tmpMGB = 1000000;
    std::string str;

    str = MiningBlockSizeValidator(tmpMGB, NULL, true);
    BOOST_CHECK(str.empty());

    maxGeneratedBlock = 8888881;
    str = MiningBlockSizeValidator(tmpMGB, NULL, false);
    BOOST_CHECK(str.empty());

    str = MiningBlockSizeValidator(tmpMGB, (uint64_t *) 42, true);
    BOOST_CHECK(str.empty());

    tmpMGB = excessiveBlockSize - 1;

    str = MiningBlockSizeValidator(tmpMGB, NULL, true);
    BOOST_CHECK(str.empty());

    maxGeneratedBlock = 8888881;
    str = MiningBlockSizeValidator(tmpMGB, NULL, false);
    BOOST_CHECK(str.empty());

    str = MiningBlockSizeValidator(tmpMGB, (uint64_t *) 42, true);
    BOOST_CHECK(str.empty());

    tmpMGB = excessiveBlockSize + 1;

    str = MiningBlockSizeValidator(tmpMGB, NULL, true);
    BOOST_CHECK(! str.empty());

    str = MiningBlockSizeValidator(tmpMGB, NULL, false);
    BOOST_CHECK(str.empty());

    str = MiningBlockSizeValidator(tmpMGB, (uint64_t *) 42, true);
    BOOST_CHECK(! str.empty());
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Made the unit test clean up after itself so as to not interfere with other test cases.<commit_after>#include "unlimited.h"

#include "test/test_bitcoin.h"
#include "../consensus/consensus.h"

#include <boost/algorithm/string.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/lexical_cast.hpp>

using namespace std;

// Defined in rpc_tests.cpp not bitcoin-cli.cpp
extern UniValue CallRPC(string strMethod);

BOOST_FIXTURE_TEST_SUITE(excessiveblock_test, TestingSetup)

BOOST_AUTO_TEST_CASE(rpc_excessive)
{
    BOOST_CHECK_NO_THROW(CallRPC("getexcessiveblock"));

    BOOST_CHECK_NO_THROW(CallRPC("getminingmaxblock"));

    BOOST_CHECK_THROW(CallRPC("setexcessiveblock not_uint"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("setexcessiveblock 1000000 not_uint"), boost::bad_lexical_cast);
    BOOST_CHECK_THROW(CallRPC("setexcessiveblock 1000000 -1"), boost::bad_lexical_cast);
    BOOST_CHECK_THROW(CallRPC("setexcessiveblock -1 0"), boost::bad_lexical_cast);

    BOOST_CHECK_THROW(CallRPC("setexcessiveblock 1000 1"), runtime_error);
    BOOST_CHECK_NO_THROW(CallRPC("setminingmaxblock 1000"));
    BOOST_CHECK_NO_THROW(CallRPC("setexcessiveblock 1000 1"));

    BOOST_CHECK_THROW(CallRPC("setexcessiveblock 1000 0 0"), runtime_error);

    BOOST_CHECK_THROW(CallRPC("setminingmaxblock"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("setminingmaxblock 100000"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("setminingmaxblock not_uint"),  boost::bad_lexical_cast);
    BOOST_CHECK_THROW(CallRPC("setminingmaxblock -1"),  boost::bad_lexical_cast);
    BOOST_CHECK_THROW(CallRPC("setminingmaxblock 0"), runtime_error);
    BOOST_CHECK_THROW(CallRPC("setminingmaxblock 0 0"), runtime_error);
    BOOST_CHECK_NO_THROW(CallRPC("setminingmaxblock 1000"));
    BOOST_CHECK_NO_THROW(CallRPC("setminingmaxblock 101"));

}

BOOST_AUTO_TEST_CASE(buip005)
{
    string exceptedEB;
    string exceptedAD;
    excessiveBlockSize = 1000000;
    excessiveAcceptDepth = 9999999;
    exceptedEB = "EB1";
    exceptedAD = "AD9999999";
    settingsToUserAgentString();
    BOOST_CHECK_MESSAGE(BUComments.front() == exceptedEB,
                        "EB ought to have been " << exceptedEB << " when excessiveBlockSize = "
                        << excessiveBlockSize << " but was " << BUComments.front());
    BOOST_CHECK_MESSAGE(BUComments.back() == exceptedAD,
                        "AD ought to have been " << exceptedAD << " when excessiveBlockSize = " << excessiveAcceptDepth);
    excessiveBlockSize = 100000;
    excessiveAcceptDepth = 9999999 + 1;
    exceptedEB = "EB0.1";
    exceptedAD = "AD9999999";
    settingsToUserAgentString();
    BOOST_CHECK_MESSAGE(BUComments.front() == exceptedEB,
                        "EB ought to have been " << exceptedEB << " when excessiveBlockSize = "
                        << excessiveBlockSize << " but was " << BUComments.front());
    BOOST_CHECK_MESSAGE(BUComments.back() == exceptedAD,
                        "AD ought to have been " << exceptedAD << " when excessiveBlockSize = " << excessiveAcceptDepth);
    excessiveBlockSize = 10000;
    exceptedEB = "EB0";
    settingsToUserAgentString();
    BOOST_CHECK_MESSAGE(BUComments.front() == exceptedEB,
                        "EB ought to have been " << exceptedEB << " when excessiveBlockSize = "
                        << excessiveBlockSize << " but was " << BUComments.front());
    excessiveBlockSize = 150000;
    exceptedEB = "EB0.1";
    settingsToUserAgentString();
    BOOST_CHECK_MESSAGE(BUComments.front() == exceptedEB,
                        "EB ought to have been rounded to " << exceptedEB << " when excessiveBlockSize = "
                        << excessiveBlockSize << " but was " << BUComments.front());
    excessiveBlockSize = 150000;
    exceptedEB = "EB0.1";
    settingsToUserAgentString();
    BOOST_CHECK_MESSAGE(BUComments.front() == exceptedEB,
                        "EB ought to have been rounded to " << exceptedEB << " when excessiveBlockSize = "
                        << excessiveBlockSize << " but was " << BUComments.front());

    // set back to defaults
    excessiveBlockSize = 1000000;
    excessiveAcceptDepth = 4;
}

BOOST_AUTO_TEST_CASE(excessiveChecks)
{
  CBlock block;

  excessiveBlockSize = 16000000;  // Ignore excessive block size when checking sigops and block effort

  // Check sigops values

  // Maintain compatibility with the old sigops calculator for blocks <= 1MB
  BOOST_CHECK_MESSAGE(false == CheckExcessive(block,BLOCKSTREAM_CORE_MAX_BLOCK_SIZE-1,BLOCKSTREAM_CORE_MAX_BLOCK_SIGOPS,100,100), "improper sigops");
  BOOST_CHECK_MESSAGE(false == CheckExcessive(block,BLOCKSTREAM_CORE_MAX_BLOCK_SIZE-1,BLOCKSTREAM_CORE_MAX_BLOCK_SIGOPS,100,100), "improper sigops");
  BOOST_CHECK_MESSAGE(false == CheckExcessive(block,BLOCKSTREAM_CORE_MAX_BLOCK_SIZE,BLOCKSTREAM_CORE_MAX_BLOCK_SIGOPS,100,100), "improper sigops");

  BOOST_CHECK_MESSAGE(true == CheckExcessive(block,BLOCKSTREAM_CORE_MAX_BLOCK_SIZE-1,BLOCKSTREAM_CORE_MAX_BLOCK_SIGOPS+1,100,100), "improper sigops");
  BOOST_CHECK_MESSAGE(true == CheckExcessive(block,BLOCKSTREAM_CORE_MAX_BLOCK_SIZE,BLOCKSTREAM_CORE_MAX_BLOCK_SIGOPS+1,100,100), "improper sigops");

  // Check sigops > 1MB.
  BOOST_CHECK_MESSAGE(false == CheckExcessive(block,1000000+1,(blockSigopsPerMb.value*2),100,100), "improper sigops");
  BOOST_CHECK_MESSAGE(true == CheckExcessive(block,1000000+1,(blockSigopsPerMb.value*2)+1,100,100), "improper sigops");
  BOOST_CHECK_MESSAGE(true == CheckExcessive(block,(2*1000000),(blockSigopsPerMb.value*2)+1,100,100), "improper sigops");
  BOOST_CHECK_MESSAGE(false == CheckExcessive(block,(2*1000000)+1,(blockSigopsPerMb.value*2)+1,100,100), "improper sigops");

  // Check tx size values
  maxTxSize.value = DEFAULT_LARGEST_TRANSACTION;

  // Within a 1 MB block, a 1MB transaction is not excessive
  BOOST_CHECK_MESSAGE(false == CheckExcessive(block,BLOCKSTREAM_CORE_MAX_BLOCK_SIZE,1,1,BLOCKSTREAM_CORE_MAX_BLOCK_SIZE), "improper max tx");

  // With a > 1 MB block, use the maxTxSize to determine
  BOOST_CHECK_MESSAGE(false == CheckExcessive(block,BLOCKSTREAM_CORE_MAX_BLOCK_SIZE+1,1,1,maxTxSize.value), "improper max tx");
  BOOST_CHECK_MESSAGE(true == CheckExcessive(block,BLOCKSTREAM_CORE_MAX_BLOCK_SIZE+1,1,1,maxTxSize.value+1), "improper max tx");

}

BOOST_AUTO_TEST_CASE(check_validator_rule)
{
    BOOST_CHECK( MiningAndExcessiveBlockValidatorRule(1000000, 1000000));
    BOOST_CHECK( MiningAndExcessiveBlockValidatorRule(16000000, 1000000));
    BOOST_CHECK( MiningAndExcessiveBlockValidatorRule(1000001, 1000000));

    BOOST_CHECK( ! MiningAndExcessiveBlockValidatorRule(1000000, 1000001));
    BOOST_CHECK( ! MiningAndExcessiveBlockValidatorRule(1000000, 16000000));

    BOOST_CHECK( MiningAndExcessiveBlockValidatorRule(1357, 1357));
    BOOST_CHECK( MiningAndExcessiveBlockValidatorRule(161616, 2222));
    BOOST_CHECK( MiningAndExcessiveBlockValidatorRule(88889, 88888));

    BOOST_CHECK( ! MiningAndExcessiveBlockValidatorRule(929292, 929293));
    BOOST_CHECK( ! MiningAndExcessiveBlockValidatorRule(4, 234245));
}

BOOST_AUTO_TEST_CASE(check_excessive_validator)
{
    unsigned int c_mgb = maxGeneratedBlock;
    unsigned int c_ebs = excessiveBlockSize;

    // fudge global variables....
    maxGeneratedBlock = 1000000;
    excessiveBlockSize = 888;

    unsigned int tmpExcessive = 1000000;
    std::string str;

    str = ExcessiveBlockValidator(tmpExcessive, NULL, true);
    BOOST_CHECK(str.empty());

    excessiveBlockSize = 888;
    str = ExcessiveBlockValidator(tmpExcessive, NULL, false);
    BOOST_CHECK(str.empty());

    str = ExcessiveBlockValidator(tmpExcessive, (unsigned int *) 42, true);
    BOOST_CHECK(str.empty());

    tmpExcessive = maxGeneratedBlock + 1;

    str = ExcessiveBlockValidator(tmpExcessive, NULL, true);
    BOOST_CHECK(str.empty());

    excessiveBlockSize = 888;
    str = ExcessiveBlockValidator(tmpExcessive, NULL, false);
    BOOST_CHECK(str.empty());

    str = ExcessiveBlockValidator(tmpExcessive, (unsigned int *) 42, true);
    BOOST_CHECK(str.empty());

    tmpExcessive = maxGeneratedBlock - 1;

    str = ExcessiveBlockValidator(tmpExcessive, NULL, true);
    BOOST_CHECK(! str.empty());

    str = ExcessiveBlockValidator(tmpExcessive, NULL, false);
    BOOST_CHECK(str.empty());

    str = ExcessiveBlockValidator(tmpExcessive, (unsigned int *) 42, true);
    BOOST_CHECK(! str.empty());

    maxGeneratedBlock = c_mgb;
    excessiveBlockSize = c_ebs;
}

BOOST_AUTO_TEST_CASE(check_generated_block_validator)
{
    unsigned int c_mgb = maxGeneratedBlock;
    unsigned int c_ebs = excessiveBlockSize;

    // fudge global variables....
    maxGeneratedBlock = 888;
    excessiveBlockSize = 1000000;

    uint64_t tmpMGB = 1000000;
    std::string str;

    str = MiningBlockSizeValidator(tmpMGB, NULL, true);
    BOOST_CHECK(str.empty());

    maxGeneratedBlock = 8888881;
    str = MiningBlockSizeValidator(tmpMGB, NULL, false);
    BOOST_CHECK(str.empty());

    str = MiningBlockSizeValidator(tmpMGB, (uint64_t *) 42, true);
    BOOST_CHECK(str.empty());

    tmpMGB = excessiveBlockSize - 1;

    str = MiningBlockSizeValidator(tmpMGB, NULL, true);
    BOOST_CHECK(str.empty());

    maxGeneratedBlock = 8888881;
    str = MiningBlockSizeValidator(tmpMGB, NULL, false);
    BOOST_CHECK(str.empty());

    str = MiningBlockSizeValidator(tmpMGB, (uint64_t *) 42, true);
    BOOST_CHECK(str.empty());

    tmpMGB = excessiveBlockSize + 1;

    str = MiningBlockSizeValidator(tmpMGB, NULL, true);
    BOOST_CHECK(! str.empty());

    str = MiningBlockSizeValidator(tmpMGB, NULL, false);
    BOOST_CHECK(str.empty());

    str = MiningBlockSizeValidator(tmpMGB, (uint64_t *) 42, true);
    BOOST_CHECK(! str.empty());

    maxGeneratedBlock = c_mgb;
    excessiveBlockSize = c_ebs;
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#include "Mocks.hpp"

#include <ctime>

using namespace blackhole;

class base_frontend_t {
public:
    virtual void handle(log::record_t&& record) = 0;
};

template<class Formatter, class Sink>
class frontend_t : public base_frontend_t {
    const std::unique_ptr<Formatter> m_formatter;
    const std::unique_ptr<Sink> m_sink;
public:
    frontend_t(std::unique_ptr<Formatter> formatter, std::unique_ptr<Sink> sink) :
        m_formatter(std::move(formatter)),
        m_sink(std::move(sink))
    {}

    void handle(log::record_t&& record) {
        auto msg = std::move(m_formatter->format(record));
        m_sink->consume(msg);
     }
};

typedef std::function<bool(const log::attributes_t& attributes)> filter_t;

struct default_filter_t {
    static default_filter_t& instance() {
        static default_filter_t filter;
        return filter;
    }

    bool operator()(const log::attributes_t&) {
        return true;
    }

private:
    default_filter_t() {}
};

namespace helper {

struct LessEqThan {
    template<typename L, typename R>
    static bool execute(const L& left, const R& right) {
        return left <= right;
    }
};

struct Eq {
    template<typename L, typename R>
    static bool execute(const L& left, const R& right) {
        return left == right;
    }
};

} // namespace helper

log::attributes_t merge(const std::initializer_list<log::attributes_t>& args) {
    log::attributes_t summary;
    for (auto it = args.begin(); it != args.end(); ++it) {
        summary.insert(it->begin(), it->end());
    }

    return summary;
}

namespace expr {

template<typename T>
struct has_attr_action_t {
    bool operator()(const log::attributes_t& attributes) const {
        return attributes.find(T::name()) != attributes.end();
    }
};

template<typename T>
has_attr_action_t<T> has_attr(const T&) {
    return has_attr_action_t<T>();
}

} // namespace expr

namespace keyword {

template<typename T, class = void>
struct traits {
    static inline void pack(log::attributes_t& attributes, const std::string& name, const T& value) {
        attributes[name] = value;
    }

    static inline T pack(const T& value) {
        return value;
    }

    static inline T extract(const log::attributes_t& attributes, const std::string& name) {
        return boost::get<T>(attributes.at(name));
    }
};

template<typename T>
struct traits<T, typename std::enable_if<std::is_enum<T>::value>::type> {
    typedef typename std::underlying_type<T>::type underlying_type;

    static inline void pack(log::attributes_t& attributes, const std::string& name, const T& value) {
        attributes[name] = static_cast<underlying_type>(value);
    }

    static inline underlying_type pack(const T& value) {
        return static_cast<underlying_type>(value);
    }

    static inline T extract(const log::attributes_t& attributes, const std::string& name) {
        return static_cast<T>(boost::get<underlying_type>(attributes.at(name)));
    }
};

//!@todo: Need testing.
template<typename T, typename NameProvider>
struct keyword_t {
    static const char* name() {
        return NameProvider::name();
    }

    log::attribute_pair_t operator =(T value) const {
        return std::make_pair(name(), traits<T>::pack(value));
    }

    filter_t operator >=(T value) const {
        return action_t<helper::LessEqThan>({ value });
    }

    filter_t operator ==(T value) const {
        return action_t<helper::Eq>({ value });
    }

    template<typename Action>
    struct action_t {
        T value;

        bool operator()(const log::attributes_t& attributes) const {
            return Action::execute(value, traits<T>::extract(attributes, name()));
        }
    };
};

namespace tag {

struct severity_t {
    static const char* name() { return "severity"; }
};

} // namespace tag

template<typename T>
static keyword_t<T, tag::severity_t>& severity() {
    static keyword_t<T, tag::severity_t> self;
    return self;
}

#define DECLARE_KEYWORD(Name, T) \
    namespace tag { \
        struct Name##_t { \
            static const char* name() { return #Name; } \
        }; \
    } \
    static keyword_t<T, tag::Name##_t>& Name() { \
        static keyword_t<T, tag::Name##_t> self; \
        return self; \
    }

DECLARE_KEYWORD(timestamp_id, std::time_t)

} // namespace keyword

class logger_base_t {
    bool m_enabled;

protected:
    filter_t m_filter;
    std::unique_ptr<base_frontend_t> m_frontend;
    log::attributes_t m_global_attributes;

public:
    logger_base_t() :
        m_enabled(true),
        m_filter(default_filter_t::instance())
    {}

    bool enabled() const {
        return m_enabled;
    }

    void enable() {
        m_enabled = true;
    }

    void disable() {
        m_enabled = false;
    }

    void set_filter(filter_t&& filter) {
        m_filter = filter;
    }

    void add_attribute(const log::attribute_pair_t& attr) {
        m_global_attributes.insert(attr);
    }

    void add_frontend(std::unique_ptr<base_frontend_t> frontend) {
        m_frontend = std::move(frontend);
    }

    log::record_t open_record() const {
        return open_record(log::attributes_t());
    }

    log::record_t open_record(log::attributes_t&& local_attributes) const {
        if (enabled()) {
            log::attributes_t attributes = merge({
                // universe_attributes              // Program global.
                // thread_attributes                // Thread local.
                m_global_attributes,                // Logger object specific.
                std::move(get_scoped_attributes()), // Depending on event scope, e.g. timestamp.
                std::move(local_attributes)         // Any user attributes.
            });

            if (m_filter(attributes)) {
                log::record_t record;
                record.attributes = std::move(attributes);
                return record;
            }
        }

        return log::record_t();
    }

    void push(log::record_t&& record) {
        m_frontend->handle(std::move(record));
    }

private:
    log::attributes_t get_scoped_attributes() const {
        log::attributes_t attributes;
        attributes["timestamp_id"] = std::time(nullptr);
        return attributes;
    }
};

template<typename Level>
class verbose_logger_t : public logger_base_t {
    typedef typename std::underlying_type<Level>::type level_type;

public:
    log::record_t open_record(Level level) const {
        return logger_base_t::open_record({ keyword::severity<Level>() = level }); //!@todo: Неправильно, нужно во-первых уметь генерировать мапу аттрибутов из вариадика, а во-вторых - оставлять operator= для создания одного аттрибута!
    }
};

TEST(logger_base_t, CanBeEnabled) {
    logger_base_t log;
    log.enable();
    EXPECT_TRUE(log.enabled());
}

TEST(logger_base_t, CanBeDisabled) {
    logger_base_t log;
    log.disable();
    EXPECT_FALSE(log.enabled());
}

TEST(logger_base_t, EnabledByDefault) {
    logger_base_t log;
    EXPECT_TRUE(log.enabled());
}

TEST(logger_base_t, OpenRecordByDefault) {
    logger_base_t log;
    EXPECT_TRUE(log.open_record().valid());
}

TEST(logger_base_t, DoNotOpenRecordIfDisabled) {
    logger_base_t log;
    log.disable();
    EXPECT_FALSE(log.open_record().valid());
}

TEST(verbose_logger_t, Class) {
    enum level : std::uint64_t { debug, info, warn, error };
    verbose_logger_t<level> log;
    UNUSED(log);
}

TEST(verbose_logger_t, OpenRecordByDefault) {
    enum level : std::uint64_t { debug, info, warn, error };
    verbose_logger_t<level> log;
    log::record_t record = log.open_record(level::debug);
    EXPECT_TRUE(record.valid());
}

TEST(verbose_logger_t, OpenRecordForValidVerbosityLevel) {
    enum class level : std::uint64_t { debug, info, warn, error };
    verbose_logger_t<level> log;
    log.set_filter(keyword::severity<level>() >= level::info);
    EXPECT_FALSE(log.open_record(level::debug).valid());
    EXPECT_TRUE(log.open_record(level::info).valid());
    EXPECT_TRUE(log.open_record(level::warn).valid());
    EXPECT_TRUE(log.open_record(level::error).valid());
}

namespace keyword { DECLARE_KEYWORD(urgent, std::uint8_t) }

TEST(logger_base_t, OpensRecordWhenAttributeFilterSucceeded) {
    logger_base_t log;
    log.set_filter(expr::has_attr(keyword::urgent()));
    log.add_attribute(keyword::urgent() = 1);
    EXPECT_TRUE(log.open_record().valid());
}

TEST(logger_base_t, DoNotOpenRecordWhenAttributeFilterFailed) {
    logger_base_t log;
    log.set_filter(expr::has_attr(keyword::urgent()));
    EXPECT_FALSE(log.open_record().valid());
}

//TEST(logger_base_t, ComplexFilter) {
//    logger_base_t log;
//    log.set_filter(expr::has_attr(keyword::urgent()));// && keyword::urgent() == 1);
//    log.set_attribute(keyword::urgent() = 1);
//    EXPECT_FALSE(log.open_record());
//}

// Allow to make custom filters. severity() >= warning || has_tag(urgent()) && urgent() == 1
//                                         bool(attr)  ||      bool(attr)   && bool(attr)

TEST(verbose_logger_t, Manual) {
    enum level : std::uint64_t { debug, info, warn, error };
    verbose_logger_t<level> log;

    //!@note: Factory starts here...
    auto formatter = std::make_unique<formatter::string_t>("[]: %(message)s");
    auto sink = std::make_unique<sink::file_t<>>("/dev/stdout");
    auto frontend = std::make_unique<frontend_t<formatter::string_t, sink::file_t<>>>(std::move(formatter), std::move(sink));
    //!@note ... till here.
    log.add_frontend(std::move(frontend));

    //!@note: Next lines can be hided via macro: LOG(log, debug, "Message %s", "Hell", keyword::answer = 42);
    log::record_t record = log.open_record(level::error);
    if (record.valid()) {
        record.attributes["message"] = utils::format("Some message from: '%s'!", "Hell");
        // Add another attributes.
        log.push(std::move(record));
    }
}
<commit_msg>Complex filtering has been improved.<commit_after>#include "Mocks.hpp"

#include <ctime>

using namespace blackhole;

class base_frontend_t {
public:
    virtual void handle(log::record_t&& record) = 0;
};

template<class Formatter, class Sink>
class frontend_t : public base_frontend_t {
    const std::unique_ptr<Formatter> m_formatter;
    const std::unique_ptr<Sink> m_sink;
public:
    frontend_t(std::unique_ptr<Formatter> formatter, std::unique_ptr<Sink> sink) :
        m_formatter(std::move(formatter)),
        m_sink(std::move(sink))
    {}

    void handle(log::record_t&& record) {
        auto msg = std::move(m_formatter->format(record));
        m_sink->consume(msg);
     }
};

typedef std::function<bool(const log::attributes_t& attributes)> filter_t;

struct default_filter_t {
    static default_filter_t& instance() {
        static default_filter_t filter;
        return filter;
    }

    bool operator()(const log::attributes_t&) {
        return true;
    }

private:
    default_filter_t() {}
};

namespace helper {

struct LessEqThan {
    template<typename L, typename R>
    static bool execute(const L& left, const R& right) {
        return left <= right;
    }
};

struct Eq {
    template<typename L, typename R>
    static bool execute(const L& left, const R& right) {
        return left == right;
    }
};

} // namespace helper

log::attributes_t merge(const std::initializer_list<log::attributes_t>& args) {
    log::attributes_t summary;
    for (auto it = args.begin(); it != args.end(); ++it) {
        summary.insert(it->begin(), it->end());
    }

    return summary;
}

namespace expr {

struct And {
    filter_t first;
    filter_t second;

    bool operator ()(const log::attributes_t& attributes) const {
        return first(attributes) && second(attributes);
    }
};

template<typename T>
struct has_attr_action_t {
    bool operator()(const log::attributes_t& attributes) const {
        return attributes.find(T::name()) != attributes.end();
    }

    filter_t operator &&(filter_t other) const {
        return And { *this, other };
    }
};

template<typename T>
has_attr_action_t<T> has_attr(const T&) {
    return has_attr_action_t<T>();
}

} // namespace expr

namespace keyword {

template<typename T, class = void>
struct traits {
    static inline void pack(log::attributes_t& attributes, const std::string& name, const T& value) {
        attributes[name] = value;
    }

    static inline T pack(const T& value) {
        return value;
    }

    static inline T extract(const log::attributes_t& attributes, const std::string& name) {
        return boost::get<T>(attributes.at(name));
    }
};

template<typename T>
struct traits<T, typename std::enable_if<std::is_enum<T>::value>::type> {
    typedef typename std::underlying_type<T>::type underlying_type;

    static inline void pack(log::attributes_t& attributes, const std::string& name, const T& value) {
        attributes[name] = static_cast<underlying_type>(value);
    }

    static inline underlying_type pack(const T& value) {
        return static_cast<underlying_type>(value);
    }

    static inline T extract(const log::attributes_t& attributes, const std::string& name) {
        return static_cast<T>(boost::get<underlying_type>(attributes.at(name)));
    }
};

//!@todo: Need testing.
template<typename T, typename NameProvider>
struct keyword_t {
    static const char* name() {
        return NameProvider::name();
    }

    log::attribute_pair_t operator =(T value) const {
        return std::make_pair(name(), traits<T>::pack(value));
    }

    filter_t operator >=(T value) const {
        return action_t<helper::LessEqThan>({ value });
    }

    filter_t operator ==(T value) const {
        return action_t<helper::Eq>({ value });
    }

    template<typename Action>
    struct action_t {
        T value;

        bool operator()(const log::attributes_t& attributes) const {
            return Action::execute(value, traits<T>::extract(attributes, name()));
        }
    };
};

namespace tag {

struct severity_t {
    static const char* name() { return "severity"; }
};

} // namespace tag

template<typename T>
static keyword_t<T, tag::severity_t>& severity() {
    static keyword_t<T, tag::severity_t> self;
    return self;
}

#define DECLARE_KEYWORD(Name, T) \
    namespace tag { \
        struct Name##_t { \
            static const char* name() { return #Name; } \
        }; \
    } \
    static keyword_t<T, tag::Name##_t>& Name() { \
        static keyword_t<T, tag::Name##_t> self; \
        return self; \
    }

DECLARE_KEYWORD(timestamp_id, std::time_t)

} // namespace keyword

class logger_base_t {
    bool m_enabled;

protected:
    filter_t m_filter;
    std::unique_ptr<base_frontend_t> m_frontend;
    log::attributes_t m_global_attributes;

public:
    logger_base_t() :
        m_enabled(true),
        m_filter(default_filter_t::instance())
    {}

    bool enabled() const {
        return m_enabled;
    }

    void enable() {
        m_enabled = true;
    }

    void disable() {
        m_enabled = false;
    }

    void set_filter(filter_t&& filter) {
        m_filter = filter;
    }

    void add_attribute(const log::attribute_pair_t& attr) {
        m_global_attributes.insert(attr);
    }

    void add_frontend(std::unique_ptr<base_frontend_t> frontend) {
        m_frontend = std::move(frontend);
    }

    log::record_t open_record() const {
        return open_record(log::attributes_t());
    }

    log::record_t open_record(log::attributes_t&& local_attributes) const {
        if (enabled()) {
            log::attributes_t attributes = merge({
                // universe_attributes              // Program global.
                // thread_attributes                // Thread local.
                m_global_attributes,                // Logger object specific.
                std::move(get_scoped_attributes()), // Depending on event scope, e.g. timestamp.
                std::move(local_attributes)         // Any user attributes.
            });

            if (m_filter(attributes)) {
                log::record_t record;
                record.attributes = std::move(attributes);
                return record;
            }
        }

        return log::record_t();
    }

    void push(log::record_t&& record) {
        m_frontend->handle(std::move(record));
    }

private:
    log::attributes_t get_scoped_attributes() const {
        log::attributes_t attributes;
        attributes["timestamp_id"] = std::time(nullptr);
        return attributes;
    }
};

template<typename Level>
class verbose_logger_t : public logger_base_t {
    typedef typename std::underlying_type<Level>::type level_type;

public:
    log::record_t open_record(Level level) const {
        return logger_base_t::open_record({ keyword::severity<Level>() = level }); //!@todo: Неправильно, нужно во-первых уметь генерировать мапу аттрибутов из вариадика, а во-вторых - оставлять operator= для создания одного аттрибута!
    }
};

TEST(logger_base_t, CanBeEnabled) {
    logger_base_t log;
    log.enable();
    EXPECT_TRUE(log.enabled());
}

TEST(logger_base_t, CanBeDisabled) {
    logger_base_t log;
    log.disable();
    EXPECT_FALSE(log.enabled());
}

TEST(logger_base_t, EnabledByDefault) {
    logger_base_t log;
    EXPECT_TRUE(log.enabled());
}

TEST(logger_base_t, OpenRecordByDefault) {
    logger_base_t log;
    EXPECT_TRUE(log.open_record().valid());
}

TEST(logger_base_t, DoNotOpenRecordIfDisabled) {
    logger_base_t log;
    log.disable();
    EXPECT_FALSE(log.open_record().valid());
}

TEST(verbose_logger_t, Class) {
    enum level : std::uint64_t { debug, info, warn, error };
    verbose_logger_t<level> log;
    UNUSED(log);
}

TEST(verbose_logger_t, OpenRecordByDefault) {
    enum level : std::uint64_t { debug, info, warn, error };
    verbose_logger_t<level> log;
    log::record_t record = log.open_record(level::debug);
    EXPECT_TRUE(record.valid());
}

TEST(verbose_logger_t, OpenRecordForValidVerbosityLevel) {
    enum class level : std::uint64_t { debug, info, warn, error };
    verbose_logger_t<level> log;
    log.set_filter(keyword::severity<level>() >= level::info);
    EXPECT_FALSE(log.open_record(level::debug).valid());
    EXPECT_TRUE(log.open_record(level::info).valid());
    EXPECT_TRUE(log.open_record(level::warn).valid());
    EXPECT_TRUE(log.open_record(level::error).valid());
}

namespace keyword { DECLARE_KEYWORD(urgent, std::uint8_t) }

TEST(logger_base_t, OpensRecordWhenAttributeFilterSucceed) {
    logger_base_t log;
    log.set_filter(expr::has_attr(keyword::urgent()));
    log.add_attribute(keyword::urgent() = 1);
    EXPECT_TRUE(log.open_record().valid());
}

TEST(logger_base_t, DoNotOpenRecordWhenAttributeFilterFailed) {
    logger_base_t log;
    log.set_filter(expr::has_attr(keyword::urgent()));
    EXPECT_FALSE(log.open_record().valid());
}

TEST(logger_base_t, OpenRecordWhenComplexFilterSucceed) {
    logger_base_t log;
    log.set_filter(expr::has_attr(keyword::urgent()) && keyword::urgent() == 1);
    log.add_attribute(keyword::urgent() = 1);
    EXPECT_TRUE(log.open_record().valid());
}

TEST(logger_base_t, DoNotOpenRecordWhenComplexFilterFailed) {
    logger_base_t log;
    log.set_filter(expr::has_attr(keyword::urgent()) && keyword::urgent() == 1);
    log.add_attribute(keyword::urgent() = 2);
    EXPECT_FALSE(log.open_record().valid());
}

// Allow to make custom filters. severity() >= warning || has_tag(urgent()) && urgent() == 1
//                                         bool(attr)  ||      bool(attr)   && bool(attr)

TEST(verbose_logger_t, Manual) {
    enum level : std::uint64_t { debug, info, warn, error };
    verbose_logger_t<level> log;

    //!@note: Factory starts here...
    auto formatter = std::make_unique<formatter::string_t>("[]: %(message)s");
    auto sink = std::make_unique<sink::file_t<>>("/dev/stdout");
    auto frontend = std::make_unique<frontend_t<formatter::string_t, sink::file_t<>>>(std::move(formatter), std::move(sink));
    //!@note ... till here.
    log.add_frontend(std::move(frontend));

    //!@note: Next lines can be hided via macro: LOG(log, debug, "Message %s", "Hell", keyword::answer = 42);
    log::record_t record = log.open_record(level::error);
    if (record.valid()) {
        record.attributes["message"] = utils::format("Some message from: '%s'!", "Hell");
        // Add another attributes.
        log.push(std::move(record));
    }
}
<|endoftext|>


<commit_before>#include "audio/audio.hpp"
#include "main/main.hpp"
#include "world/world.hpp"
#include "graphics/graphics.hpp"

namespace Polarity {

AudioFile *audioTest;
AudioChannelPlayer *audioPlayer;

bool loaded = false;

void loadAssets() {
    test_image = loadImage("assets/helloworld.png");
    audioPlayer = new AudioChannelPlayer(16);
    if (audioPlayer->addChannel("white", "assets/audio/frozen_star.mp3", 0) != AudioFileError::OK) {
        std::cerr << "Couldn't load white track" << std::endl;
    }
    if (audioPlayer->addChannel("black", "assets/audio/lightless_dawn.mp3", 1) != AudioFileError::OK) {
        std::cerr << "Couldn't load black track" << std::endl;
    }
}

bool loopIter(SDL_Surface *screen) {
    SDL_Event event;
    std::vector<int> keyUps;
    while (SDL_PollEvent(&event)) {
      if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) {
        if (event.type == SDL_KEYDOWN) {
	  world->keyEvent(event.key.keysym.sym, true);
	} else {
	  keyUps.push_back(event.key.keysym.sym);
	}
        if (event.key.keysym.sym == SDLK_SPACE) {
            audioPlayer->playChannel("white");
            audioPlayer->playChannel("black");
        } else if (event.key.keysym.sym == SDLK_ESCAPE) {
            audioPlayer->stopChannel("white");
            audioPlayer->stopChannel("black");
        } else if (event.key.keysym.sym == SDLK_w) {
            audioPlayer->setChannelVolume("white", 1.0);
            audioPlayer->setChannelVolume("black", 0.0);
        } else if (event.key.keysym.sym == SDLK_b) {
            audioPlayer->setChannelVolume("white", 0.0);
            audioPlayer->setChannelVolume("black", 1.0);
        }
      }
    }
    world->tick();
    // all key up have to happen after key downs so we get a full tick of downs
    for (auto &key : keyUps) {
      world->keyEvent(key, false);
    }
    return true;
}
}
<commit_msg>fix build error<commit_after>#include "audio/audio.hpp"
#include "main/main.hpp"
#include "world/world.hpp"
#include "graphics/graphics.hpp"

namespace Polarity {

AudioFile *audioTest;
AudioChannelPlayer *audioPlayer;

bool loaded = false;

void loadAssets() {
    audioPlayer = new AudioChannelPlayer(16);
    if (audioPlayer->addChannel("white", "assets/audio/frozen_star.mp3", 0) != AudioFileError::OK) {
        std::cerr << "Couldn't load white track" << std::endl;
    }
    if (audioPlayer->addChannel("black", "assets/audio/lightless_dawn.mp3", 1) != AudioFileError::OK) {
        std::cerr << "Couldn't load black track" << std::endl;
    }
}

bool loopIter(SDL_Surface *screen) {
    SDL_Event event;
    std::vector<int> keyUps;
    while (SDL_PollEvent(&event)) {
      if (event.type == SDL_KEYDOWN || event.type == SDL_KEYUP) {
        if (event.type == SDL_KEYDOWN) {
	  world->keyEvent(event.key.keysym.sym, true);
	} else {
	  keyUps.push_back(event.key.keysym.sym);
	}
        if (event.key.keysym.sym == SDLK_SPACE) {
            audioPlayer->playChannel("white");
            audioPlayer->playChannel("black");
        } else if (event.key.keysym.sym == SDLK_ESCAPE) {
            audioPlayer->stopChannel("white");
            audioPlayer->stopChannel("black");
        } else if (event.key.keysym.sym == SDLK_w) {
            audioPlayer->setChannelVolume("white", 1.0);
            audioPlayer->setChannelVolume("black", 0.0);
        } else if (event.key.keysym.sym == SDLK_b) {
            audioPlayer->setChannelVolume("white", 0.0);
            audioPlayer->setChannelVolume("black", 1.0);
        }
      }
    }
    world->tick();
    // all key up have to happen after key downs so we get a full tick of downs
    for (auto &key : keyUps) {
      world->keyEvent(key, false);
    }
    return true;
}
}
<|endoftext|>


<commit_before>#include <iostream>
#include "Configuration.h"
#include "Extensions.h"
#include "ObjectsActivator.h"
#include "PassiveLProcessor.h"

// -----------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
using namespace UniSetExtensions;
// -----------------------------------------------------------------------------
int main(int argc, const char **argv)
{
	try
	{
		string confile=UniSetTypes::getArgParam("--confile",argc,argv,"configure.xml");
		conf = new Configuration( argc, argv, confile );

		string logfilename(conf->getArgParam("--logicproc-logfile"));
		if( logfilename.empty() )
			logfilename = "logicproc.log";

		conf->initDebug(dlog,"dlog");

		std::ostringstream logname;
		string dir(conf->getLogDir());
		logname << dir << logfilename;
		unideb.logFile( logname.str().c_str() );
		dlog.logFile( logname.str().c_str() );

		string schema = conf->getArgParam("--schema");
		if( schema.empty() )
		{
			cerr << "schema-file not defined. Use --schema" << endl;
			return 1;
		}

		ObjectId shmID = DefaultObjectId;
		string sID = conf->getArgParam("--smemory-id");
		if( !sID.empty() )
			shmID = conf->getControllerID(sID);
		else
			shmID = getSharedMemoryID();

		if( shmID == DefaultObjectId )
		{
			cerr << sID << "? SharedMemoryID not found in " << conf->getControllersSection() << " section" << endl;
			return 1;
		}

		cout << "init smemory: " << sID << " ID: " << shmID << endl;

		string name = conf->getArgParam("--name","LProcessor");
		if( name.empty() )
		{
			cerr << "(plogicproc):   name'" << endl;
			return 1;
		}

		ObjectId ID = conf->getObjectID(name);
		if( ID == UniSetTypes::DefaultObjectId )
		{
			cerr << "(plogicproc):  '" << name
				<< "'    . !"
				<< "   " << conf->getObjectsSection() << endl;
			return 1;
		}

		cout << "init name: " << name << " ID: " << ID << endl;

		PassiveLProcessor plc(schema,ID,shmID);

		ObjectsActivator act;
		act.addObject(static_cast<class UniSetObject*>(&plc));

		SystemMessage sm(SystemMessage::StartUp);
		act.broadcast( sm.transport_msg() );

		unideb(Debug::ANY) << "\n\n\n";
		unideb[Debug::ANY] << "(main): -------------- IOControl START -------------------------\n\n";
		dlog(Debug::ANY) << "\n\n\n";
		dlog[Debug::ANY] << "(main): -------------- IOControl START -------------------------\n\n";
		act.run(false);
		pause();
	}
	catch( LogicException& ex )
	{
		cerr << ex << endl;
	}
	catch( Exception& ex )
	{
		cerr << ex << endl;
	}
	catch( ... )
	{
		cerr << " catch ... " << endl;
	}

	return 0;
}
// -----------------------------------------------------------------------------
<commit_msg>use updated logFile<commit_after>#include <iostream>
#include "Configuration.h"
#include "Extensions.h"
#include "ObjectsActivator.h"
#include "PassiveLProcessor.h"

// -----------------------------------------------------------------------------
using namespace std;
using namespace UniSetTypes;
using namespace UniSetExtensions;
// -----------------------------------------------------------------------------
int main(int argc, const char **argv)
{
	try
	{
		string confile=UniSetTypes::getArgParam("--confile",argc,argv,"configure.xml");
		conf = new Configuration( argc, argv, confile );

		string logfilename(conf->getArgParam("--logicproc-logfile"));
		if( logfilename.empty() )
			logfilename = "logicproc.log";

		conf->initDebug(dlog,"dlog");

		std::ostringstream logname;
		string dir(conf->getLogDir());
		logname << dir << logfilename;
		unideb.logFile( logname.str() );
		dlog.logFile( logname.str() );

		string schema = conf->getArgParam("--schema");
		if( schema.empty() )
		{
			cerr << "schema-file not defined. Use --schema" << endl;
			return 1;
		}

		ObjectId shmID = DefaultObjectId;
		string sID = conf->getArgParam("--smemory-id");
		if( !sID.empty() )
			shmID = conf->getControllerID(sID);
		else
			shmID = getSharedMemoryID();

		if( shmID == DefaultObjectId )
		{
			cerr << sID << "? SharedMemoryID not found in " << conf->getControllersSection() << " section" << endl;
			return 1;
		}

		cout << "init smemory: " << sID << " ID: " << shmID << endl;

		string name = conf->getArgParam("--name","LProcessor");
		if( name.empty() )
		{
			cerr << "(plogicproc):   name'" << endl;
			return 1;
		}

		ObjectId ID = conf->getObjectID(name);
		if( ID == UniSetTypes::DefaultObjectId )
		{
			cerr << "(plogicproc):  '" << name
				<< "'    . !"
				<< "   " << conf->getObjectsSection() << endl;
			return 1;
		}

		cout << "init name: " << name << " ID: " << ID << endl;

		PassiveLProcessor plc(schema,ID,shmID);

		ObjectsActivator act;
		act.addObject(static_cast<class UniSetObject*>(&plc));

		SystemMessage sm(SystemMessage::StartUp);
		act.broadcast( sm.transport_msg() );

		unideb(Debug::ANY) << "\n\n\n";
		unideb[Debug::ANY] << "(main): -------------- IOControl START -------------------------\n\n";
		dlog(Debug::ANY) << "\n\n\n";
		dlog[Debug::ANY] << "(main): -------------- IOControl START -------------------------\n\n";
		act.run(false);
		pause();
	}
	catch( LogicException& ex )
	{
		cerr << ex << endl;
	}
	catch( Exception& ex )
	{
		cerr << ex << endl;
	}
	catch( ... )
	{
		cerr << " catch ... " << endl;
	}

	return 0;
}
// -----------------------------------------------------------------------------
<|endoftext|>


<commit_before>/**
 * Copyright 2014 Open Connectome Project (http://openconnecto.me)
 * Written by Disa Mhembere (disa)
 *
 * This file is part of FlashGraph.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include "matrix/kmeans_thread.h"
#include "matrix/kmeans_thread.cpp"
#include "libgraph-algs/sem_kmeans_util.h"

void test_thread_creation(const unsigned NTHREADS, const unsigned nnodes) {
    std::vector<kmeans_thread::ptr> thds;

    // Always: Build state alone
    for (unsigned i = 0; i < NTHREADS; i++)
        thds.push_back(kmeans_thread::create
                (i%nnodes, i, 69, 200, 2, nullptr, NULL, "/dev/null"));

    // Always: Start threads alone
    for (unsigned i = 0; i < NTHREADS; i++)
        thds[i]->start(TEST);

    unsigned sum = 0;
    unsigned verification = 0;
    for (unsigned i = 0; i < thds.size(); i++) {
        thds[i]->join();
        sum += thds[i]->get_val(); // OK to do together
        verification += i;
    }
    BOOST_VERIFY(sum == verification);
    std::cout << "SUCCESS: The sum is: " << sum << "\n";
}

void test_numa_populate_data() {
    constexpr unsigned NTHREADS = 10;
    constexpr unsigned nnodes = 4;
    constexpr unsigned nrow = 50;
    const unsigned nprocrows = nrow/NTHREADS;
    constexpr unsigned ncol = 5;
    const std::string fn = "/mnt/nfs/disa/data/tiny/matrix_r50_c5_rrw.bin";

    std::vector<kmeans_thread::ptr> thds;

    // Always: Build state alone
    for (unsigned i = 0; i < NTHREADS; i++)
        thds.push_back(kmeans_thread::create
                (i%nnodes, i, i*nprocrows*ncol, nprocrows, ncol, nullptr, NULL, fn));

    bin_reader<double> br(fn, nrow, ncol);
    double* data = new double [nrow*ncol];
    printf("Bin read data\n");
    br.read(data);

    // Allocate & move
    std::vector<kmeans_thread::ptr>::iterator it = thds.begin();
    for (; it != thds.end(); ++it)
        (*it)->start(ALLOC_DATA);

    for (it = thds.begin(); it != thds.end(); ++it)
        (*it)->join();

    // Print it back
    for (it = thds.begin(); it != thds.end(); ++it) {
        double *dp = &data[(*it)->get_thd_id()*ncol*nprocrows];
        BOOST_VERIFY(eq_all(dp, (*it)->get_local_data(), nprocrows*ncol));
        printf("Thread %u PASSED numa_mem_alloc()\n", (*it)->get_thd_id());
    }
    delete [] data;
}

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

    if (argc < 2) {
        fprintf(stderr, "usage: ./test_kmeans_thread nthreads nnodes\n");
        exit(EXIT_FAILURE);
    }

    test_thread_creation(atoi(argv[1]), atoi(argv[2]));
    test_numa_populate_data();

    return (EXIT_SUCCESS);
}
<commit_msg>[Test]: Added dummy clusters obj & assertion if KM_TEST not defined<commit_after>/**
 * Copyright 2014 Open Connectome Project (http://openconnecto.me)
 * Written by Disa Mhembere (disa)
 *
 * This file is part of FlashGraph.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include "matrix/kmeans_thread.h"
#include "matrix/kmeans_thread.cpp"
#include "libgraph-algs/sem_kmeans_util.h"

void test_thread_creation(const unsigned NTHREADS, const unsigned nnodes) {
    std::vector<kmeans_thread::ptr> thds;

    // Always: Build state alone
    for (unsigned i = 0; i < NTHREADS; i++) {
        clusters::ptr cl = clusters::create(2,2);
        thds.push_back(kmeans_thread::create
                (i%nnodes, i, 69, 200, 2, cl, NULL, "/dev/null"));
    }

    // Always: Start threads alone
    for (unsigned i = 0; i < NTHREADS; i++)
        thds[i]->start(TEST);

    unsigned sum = 0;
    unsigned verification = 0;
    for (unsigned i = 0; i < thds.size(); i++) {
        thds[i]->join();
        sum += thds[i]->get_val(); // OK to do together
        verification += i;
    }
    BOOST_VERIFY(sum == verification);
    std::cout << "SUCCESS: The sum is: " << sum << "\n";
}

void test_numa_populate_data() {
    constexpr unsigned NTHREADS = 10;
    constexpr unsigned nnodes = 4;
    constexpr unsigned nrow = 50;
    const unsigned nprocrows = nrow/NTHREADS;
    constexpr unsigned ncol = 5;
    const std::string fn = "/mnt/nfs/disa/data/tiny/matrix_r50_c5_rrw.bin";

    std::vector<kmeans_thread::ptr> thds;

    // Always: Build state alone
    for (unsigned i = 0; i < NTHREADS; i++) {
        clusters::ptr cl = clusters::create(2,2);
        thds.push_back(kmeans_thread::create
                (i%nnodes, i, i*nprocrows*ncol, nprocrows, ncol,
                 cl, NULL, fn));
    }

    bin_reader<double> br(fn, nrow, ncol);
    double* data = new double [nrow*ncol];
    printf("Bin read data\n");
    br.read(data);

    // Allocate & move
    std::vector<kmeans_thread::ptr>::iterator it = thds.begin();
    for (; it != thds.end(); ++it)
        (*it)->start(ALLOC_DATA);

    for (it = thds.begin(); it != thds.end(); ++it)
        (*it)->join();

    // Print it back
    for (it = thds.begin(); it != thds.end(); ++it) {
        double *dp = &data[(*it)->get_thd_id()*ncol*nprocrows];
        BOOST_VERIFY(eq_all(dp, (*it)->get_local_data(), nprocrows*ncol));
        printf("Thread %u PASSED numa_mem_alloc()\n", (*it)->get_thd_id());
    }
    delete [] data;
}

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

    if (argc < 2) {
        fprintf(stderr, "usage: ./test_kmeans_thread nthreads nnodes\n");
        exit(EXIT_FAILURE);
    }

#if KM_TEST
    test_thread_creation(atoi(argv[1]), atoi(argv[2]));
#else
    printf("[FATAL]: Set KM_TEST 1 in kmeans.h\n");
    exit(EXIT_FAILURE);
#endif
    test_numa_populate_data();

    return (EXIT_SUCCESS);
}
<|endoftext|>