<commit_before>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Kaveh Vahedipour
////////////////////////////////////////////////////////////////////////////////

#include "AgencyFeature.h"

#include "Agency/Agent.h"
#include "Logger/Logger.h"
#include "ProgramOptions/ProgramOptions.h"
#include "ProgramOptions/Section.h"
#include "RestServer/EndpointFeature.h"

using namespace arangodb;
using namespace arangodb::application_features;
using namespace arangodb::basics;
using namespace arangodb::options;
using namespace arangodb::rest;

AgencyFeature::AgencyFeature(application_features::ApplicationServer* server)
    : ApplicationFeature(server, "Agency"),
      _size(1),
      _agentId((std::numeric_limits<uint32_t>::max)()),
      _minElectionTimeout(0.15),
      _maxElectionTimeout(2.0),
      _notify(false),
      _supervision(false),
      _waitForSync(true),
      _supervisionFrequency(5.0),
      _compactionStepSize(1000) {
  setOptional(true);
  requiresElevatedPrivileges(false);
  startsAfter("Database");
  startsAfter("Dispatcher");
  startsAfter("Endpoint");
  startsAfter("QueryRegistry");
  startsAfter("Random");
  startsAfter("Recovery");
  startsAfter("Scheduler");
  startsAfter("Server");
}

AgencyFeature::~AgencyFeature() {}

void AgencyFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
  options->addSection("agency", "Configure the agency");

  options->addOption("--agency.size", "number of agents",
                     new UInt64Parameter(&_size));

  options->addOption("--agency.id", "this agent's id",
                     new UInt32Parameter(&_agentId));

  options->addOption(
      "--agency.election-timeout-min",
      "minimum timeout before an agent calls for new election [s]",
      new DoubleParameter(&_minElectionTimeout));

  options->addOption(
      "--agency.election-timeout-max",
      "maximum timeout before an agent calls for new election [s]",
      new DoubleParameter(&_maxElectionTimeout));

  options->addOption("--agency.endpoint", "agency endpoints",
                     new VectorParameter<StringParameter>(&_agencyEndpoints));

  options->addOption("--agency.notify", "notify others",
                     new BooleanParameter(&_notify));

  options->addOption("--agency.supervision",
                     "perform arangodb cluster supervision",
                     new BooleanParameter(&_supervision));

  options->addOption("--agency.supervision-frequency",
                     "arangodb cluster supervision frequency [s]",
                     new DoubleParameter(&_supervisionFrequency));

  options->addOption("--agency.compaction-step-size",
                     "step size between state machine compactions",
                     new UInt64Parameter(&_compactionStepSize));

  options->addHiddenOption("--agency.wait-for-sync",
                           "wait for hard disk syncs on every persistence call "
                           "(required in production)",
                           new BooleanParameter(&_waitForSync));
}

void AgencyFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {
  if (_agentId == (std::numeric_limits<uint32_t>::max)()) {
    disable();
    return;
  }

  // Agency size
  if (_size < 1) {
    LOG_TOPIC(FATAL, Logger::AGENCY)
        << "AGENCY: agency must have size greater 0";
    FATAL_ERROR_EXIT();
  }

  // Size needs to be odd
  if (_size % 2 == 0) {
    LOG_TOPIC(FATAL, Logger::AGENCY)
        << "AGENCY: agency must have odd number of members";
    FATAL_ERROR_EXIT();
  }

  // Id out of range
  if (_agentId >= _size) {
    LOG_TOPIC(FATAL, Logger::AGENCY) << "agency.id must not be larger than or "
                                     << "equal to agency.size";
    FATAL_ERROR_EXIT();
  }

  // Timeouts sanity
  if (_minElectionTimeout <= 0.) {
    LOG_TOPIC(FATAL, Logger::AGENCY)
        << "agency.election-timeout-min must not be negative!";
    FATAL_ERROR_EXIT();
  } else if (_minElectionTimeout < 0.15) {
    LOG_TOPIC(WARN, Logger::AGENCY)
        << "very short agency.election-timeout-min!";
  }

  if (_maxElectionTimeout <= _minElectionTimeout) {
    LOG_TOPIC(FATAL, Logger::AGENCY)
        << "agency.election-timeout-max must not be shorter than or"
        << "equal to agency.election-timeout-min.";
    FATAL_ERROR_EXIT();
  }

  if (_maxElectionTimeout <= 2 * _minElectionTimeout) {
    LOG_TOPIC(WARN, Logger::AGENCY)
        << "agency.election-timeout-max should probably be chosen longer!";
  }
}

void AgencyFeature::prepare() {
  _agencyEndpoints.resize(static_cast<size_t>(_size));
}

void AgencyFeature::start() {
  if (!isEnabled()) {
    return;
  }

  // TODO: Port this to new options handling
  std::string endpoint;
  std::string port = "8529";

  EndpointFeature* endpointFeature =
      ApplicationServer::getFeature<EndpointFeature>("Endpoint");
  auto endpoints = endpointFeature->httpEndpoints();

  if (!endpoints.empty()) {
    size_t pos = endpoint.find(':', 10);

    if (pos != std::string::npos) {
      port = endpoint.substr(pos + 1, endpoint.size() - pos);
    }
  }

  endpoint = std::string("tcp://localhost:" + port);

  _agent.reset(new consensus::Agent(consensus::config_t(
      _agentId, _minElectionTimeout, _maxElectionTimeout, endpoint,
      _agencyEndpoints, _notify, _supervision, _waitForSync,
      _supervisionFrequency, _compactionStepSize)));

  _agent->start();
  _agent->load();
}

void AgencyFeature::stop() {
  if (!isEnabled()) {
    return;
  }

  _agent->beginShutdown();
}
<commit_msg>Start AgencyFeature only after BootstrapFeature.<commit_after>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// 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.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author Kaveh Vahedipour
////////////////////////////////////////////////////////////////////////////////

#include "AgencyFeature.h"

#include "Agency/Agent.h"
#include "Logger/Logger.h"
#include "ProgramOptions/ProgramOptions.h"
#include "ProgramOptions/Section.h"
#include "RestServer/EndpointFeature.h"

using namespace arangodb;
using namespace arangodb::application_features;
using namespace arangodb::basics;
using namespace arangodb::options;
using namespace arangodb::rest;

AgencyFeature::AgencyFeature(application_features::ApplicationServer* server)
    : ApplicationFeature(server, "Agency"),
      _size(1),
      _agentId((std::numeric_limits<uint32_t>::max)()),
      _minElectionTimeout(0.15),
      _maxElectionTimeout(2.0),
      _notify(false),
      _supervision(false),
      _waitForSync(true),
      _supervisionFrequency(5.0),
      _compactionStepSize(1000) {
  setOptional(true);
  requiresElevatedPrivileges(false);
  startsAfter("Database");
  startsAfter("Dispatcher");
  startsAfter("Endpoint");
  startsAfter("QueryRegistry");
  startsAfter("Random");
  startsAfter("Recovery");
  startsAfter("Scheduler");
  startsAfter("Server");
  startsAfter("Bootstrap");
}

AgencyFeature::~AgencyFeature() {}

void AgencyFeature::collectOptions(std::shared_ptr<ProgramOptions> options) {
  options->addSection("agency", "Configure the agency");

  options->addOption("--agency.size", "number of agents",
                     new UInt64Parameter(&_size));

  options->addOption("--agency.id", "this agent's id",
                     new UInt32Parameter(&_agentId));

  options->addOption(
      "--agency.election-timeout-min",
      "minimum timeout before an agent calls for new election [s]",
      new DoubleParameter(&_minElectionTimeout));

  options->addOption(
      "--agency.election-timeout-max",
      "maximum timeout before an agent calls for new election [s]",
      new DoubleParameter(&_maxElectionTimeout));

  options->addOption("--agency.endpoint", "agency endpoints",
                     new VectorParameter<StringParameter>(&_agencyEndpoints));

  options->addOption("--agency.notify", "notify others",
                     new BooleanParameter(&_notify));

  options->addOption("--agency.supervision",
                     "perform arangodb cluster supervision",
                     new BooleanParameter(&_supervision));

  options->addOption("--agency.supervision-frequency",
                     "arangodb cluster supervision frequency [s]",
                     new DoubleParameter(&_supervisionFrequency));

  options->addOption("--agency.compaction-step-size",
                     "step size between state machine compactions",
                     new UInt64Parameter(&_compactionStepSize));

  options->addHiddenOption("--agency.wait-for-sync",
                           "wait for hard disk syncs on every persistence call "
                           "(required in production)",
                           new BooleanParameter(&_waitForSync));
}

void AgencyFeature::validateOptions(std::shared_ptr<ProgramOptions> options) {
  if (_agentId == (std::numeric_limits<uint32_t>::max)()) {
    disable();
    return;
  }

  // Agency size
  if (_size < 1) {
    LOG_TOPIC(FATAL, Logger::AGENCY)
        << "AGENCY: agency must have size greater 0";
    FATAL_ERROR_EXIT();
  }

  // Size needs to be odd
  if (_size % 2 == 0) {
    LOG_TOPIC(FATAL, Logger::AGENCY)
        << "AGENCY: agency must have odd number of members";
    FATAL_ERROR_EXIT();
  }

  // Id out of range
  if (_agentId >= _size) {
    LOG_TOPIC(FATAL, Logger::AGENCY) << "agency.id must not be larger than or "
                                     << "equal to agency.size";
    FATAL_ERROR_EXIT();
  }

  // Timeouts sanity
  if (_minElectionTimeout <= 0.) {
    LOG_TOPIC(FATAL, Logger::AGENCY)
        << "agency.election-timeout-min must not be negative!";
    FATAL_ERROR_EXIT();
  } else if (_minElectionTimeout < 0.15) {
    LOG_TOPIC(WARN, Logger::AGENCY)
        << "very short agency.election-timeout-min!";
  }

  if (_maxElectionTimeout <= _minElectionTimeout) {
    LOG_TOPIC(FATAL, Logger::AGENCY)
        << "agency.election-timeout-max must not be shorter than or"
        << "equal to agency.election-timeout-min.";
    FATAL_ERROR_EXIT();
  }

  if (_maxElectionTimeout <= 2 * _minElectionTimeout) {
    LOG_TOPIC(WARN, Logger::AGENCY)
        << "agency.election-timeout-max should probably be chosen longer!";
  }
}

void AgencyFeature::prepare() {
  _agencyEndpoints.resize(static_cast<size_t>(_size));
}

void AgencyFeature::start() {
  if (!isEnabled()) {
    return;
  }

  // TODO: Port this to new options handling
  std::string endpoint;
  std::string port = "8529";

  EndpointFeature* endpointFeature =
      ApplicationServer::getFeature<EndpointFeature>("Endpoint");
  auto endpoints = endpointFeature->httpEndpoints();

  if (!endpoints.empty()) {
    size_t pos = endpoint.find(':', 10);

    if (pos != std::string::npos) {
      port = endpoint.substr(pos + 1, endpoint.size() - pos);
    }
  }

  endpoint = std::string("tcp://localhost:" + port);

  _agent.reset(new consensus::Agent(consensus::config_t(
      _agentId, _minElectionTimeout, _maxElectionTimeout, endpoint,
      _agencyEndpoints, _notify, _supervision, _waitForSync,
      _supervisionFrequency, _compactionStepSize)));

  _agent->start();
  _agent->load();
}

void AgencyFeature::stop() {
  if (!isEnabled()) {
    return;
  }

  _agent->beginShutdown();
}
<|endoftext|>


<commit_before>/*******************************************************************************
* Copyright 2009-2015 Juan Francisco Crespo Galán
*
* 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 "fx/PlaybackManager.h"
#include "fx/VolumeSound.h"

#include <stdexcept>

AUD_NAMESPACE_BEGIN
PlaybackManager::PlaybackManager(std::shared_ptr<IDevice> device) :
	m_device(device), m_currentKey(0)
{
}

unsigned int PlaybackManager::addCategory(std::shared_ptr<PlaybackCategory> category)
{
	bool flag = true;
	unsigned int k = -1;
	do {
		auto iter = m_categories.find(m_currentKey);
		if(iter == m_categories.end())
		{
			m_categories[m_currentKey] = category;
			k = m_currentKey;
			m_currentKey++;
			flag = false;
		}
		else
			m_currentKey++;
	} while(flag);

	return k;
}

unsigned int PlaybackManager::addCategory(float volume)
{
	std::shared_ptr<PlaybackCategory> category = std::make_shared<PlaybackCategory>(m_device);
	bool flag = true;
	unsigned int k = -1;
	do {
		auto iter = m_categories.find(m_currentKey);
		if(iter == m_categories.end())
		{
			m_categories[m_currentKey] = category;
			k = m_currentKey;
			m_currentKey++;
			flag = false;
		}
		else
			m_currentKey++;
	} while(flag);

	return k;
}

std::shared_ptr<IHandle> PlaybackManager::play(std::shared_ptr<ISound> sound, unsigned int catKey)
{
	auto iter = m_categories.find(catKey);
	std::shared_ptr<PlaybackCategory> category;

	if(iter != m_categories.end())
	{
		category = iter->second;
	}
	else
	{
		category = std::make_shared<PlaybackCategory>(m_device);
		m_categories[catKey] = category;
	}
	return category->play(sound);
}

bool PlaybackManager::resume(unsigned int catKey)
{
	auto iter = m_categories.find(catKey);

	if(iter != m_categories.end())
	{
		iter->second->resume();
		return true;
	}
	else
	{
		return false;
	}
}

bool PlaybackManager::pause(unsigned int catKey)
{
	auto iter = m_categories.find(catKey);

	if(iter != m_categories.end())
	{
		iter->second->pause();
		return true;
	}
	else
	{
		return false;
	}
}

float PlaybackManager::getVolume(unsigned int catKey)
{
	auto iter = m_categories.find(catKey);

	if(iter != m_categories.end())
	{
		return iter->second->getVolume();
	}
	else
	{
		return -1.0;
	}
}

bool PlaybackManager::setVolume(float volume, unsigned int catKey)
{
	auto iter = m_categories.find(catKey);

	if(iter != m_categories.end())
	{
		iter->second->setVolume(volume);
		return true;
	}
	else
	{
		return false;
	}
}

bool PlaybackManager::stop(unsigned int catKey)
{
	auto iter = m_categories.find(catKey);

	if(iter != m_categories.end())
	{
		iter->second->stop();
		return true;
	}
	else
	{
		return false;
	}
}

void PlaybackManager::clean()
{
	for(auto cat : m_categories)
		cat.second->cleanHandles();
}

bool PlaybackManager::clean(unsigned int catKey)
{
	auto iter = m_categories.find(catKey);

	if(iter != m_categories.end())
	{
		iter->second->cleanHandles();
		return true;
	}
	else
	{
		return false;
	}
}

std::shared_ptr<IDevice> PlaybackManager::getDevice()
{
	return m_device;
}
AUD_NAMESPACE_END
<commit_msg>Fixed addCategory(volume) overload. It sets the volume correctly now.<commit_after>/*******************************************************************************
* Copyright 2009-2015 Juan Francisco Crespo Galán
*
* 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 "fx/PlaybackManager.h"
#include "fx/VolumeSound.h"

#include <stdexcept>

AUD_NAMESPACE_BEGIN
PlaybackManager::PlaybackManager(std::shared_ptr<IDevice> device) :
	m_device(device), m_currentKey(0)
{
}

unsigned int PlaybackManager::addCategory(std::shared_ptr<PlaybackCategory> category)
{
	bool flag = true;
	unsigned int k = -1;
	do {
		auto iter = m_categories.find(m_currentKey);
		if(iter == m_categories.end())
		{
			m_categories[m_currentKey] = category;
			k = m_currentKey;
			m_currentKey++;
			flag = false;
		}
		else
			m_currentKey++;
	} while(flag);

	return k;
}

unsigned int PlaybackManager::addCategory(float volume)
{
	std::shared_ptr<PlaybackCategory> category = std::make_shared<PlaybackCategory>(m_device);
	category->setVolume(volume);
	bool flag = true;
	unsigned int k = -1;
	do {
		auto iter = m_categories.find(m_currentKey);
		if(iter == m_categories.end())
		{
			m_categories[m_currentKey] = category;
			k = m_currentKey;
			m_currentKey++;
			flag = false;
		}
		else
			m_currentKey++;
	} while(flag);

	return k;
}

std::shared_ptr<IHandle> PlaybackManager::play(std::shared_ptr<ISound> sound, unsigned int catKey)
{
	auto iter = m_categories.find(catKey);
	std::shared_ptr<PlaybackCategory> category;

	if(iter != m_categories.end())
	{
		category = iter->second;
	}
	else
	{
		category = std::make_shared<PlaybackCategory>(m_device);
		m_categories[catKey] = category;
	}
	return category->play(sound);
}

bool PlaybackManager::resume(unsigned int catKey)
{
	auto iter = m_categories.find(catKey);

	if(iter != m_categories.end())
	{
		iter->second->resume();
		return true;
	}
	else
	{
		return false;
	}
}

bool PlaybackManager::pause(unsigned int catKey)
{
	auto iter = m_categories.find(catKey);

	if(iter != m_categories.end())
	{
		iter->second->pause();
		return true;
	}
	else
	{
		return false;
	}
}

float PlaybackManager::getVolume(unsigned int catKey)
{
	auto iter = m_categories.find(catKey);

	if(iter != m_categories.end())
	{
		return iter->second->getVolume();
	}
	else
	{
		return -1.0;
	}
}

bool PlaybackManager::setVolume(float volume, unsigned int catKey)
{
	auto iter = m_categories.find(catKey);

	if(iter != m_categories.end())
	{
		iter->second->setVolume(volume);
		return true;
	}
	else
	{
		return false;
	}
}

bool PlaybackManager::stop(unsigned int catKey)
{
	auto iter = m_categories.find(catKey);

	if(iter != m_categories.end())
	{
		iter->second->stop();
		return true;
	}
	else
	{
		return false;
	}
}

void PlaybackManager::clean()
{
	for(auto cat : m_categories)
		cat.second->cleanHandles();
}

bool PlaybackManager::clean(unsigned int catKey)
{
	auto iter = m_categories.find(catKey);

	if(iter != m_categories.end())
	{
		iter->second->cleanHandles();
		return true;
	}
	else
	{
		return false;
	}
}

std::shared_ptr<IDevice> PlaybackManager::getDevice()
{
	return m_device;
}
AUD_NAMESPACE_END
<|endoftext|>


<commit_before>#ifdef ENABLE_MPI

#include <stddef.h>
#include <sstream>

#include "Tools/Exception/exception.hpp"

#include "Monitor_BFER_reduction_mpi.hpp"

using namespace aff3ct;
using namespace aff3ct::module;

struct monitor_vals
{
	unsigned long long n_be;
	unsigned long long n_fe;
	unsigned long long n_fra;
	unsigned long long n_tri;
//	float              MI_sum;
};

void MPI_SUM_monitor_vals_func(void *in, void *inout, int *len, MPI_Datatype *datatype)
{
	auto    in_cvt = static_cast<monitor_vals*>(in   );
	auto inout_cvt = static_cast<monitor_vals*>(inout);

	for (auto i = 0; i < *len; i++)
	{
		inout_cvt[i].n_be  += in_cvt[i].n_be;
		inout_cvt[i].n_fe  += in_cvt[i].n_fe;

		inout_cvt[i].n_fra += in_cvt[i].n_fra;
		inout_cvt[i].n_tri += in_cvt[i].n_tri;
//		inout_cvt[i].MI    += in_cvt[i].MI;
	}
}

template <typename B, typename R>
Monitor_BFER_reduction_mpi<B,R>
::Monitor_BFER_reduction_mpi(const std::vector<Monitor_BFER<B,R>*> &monitors,
                             const std::thread::id master_thread_id,
                             const std::chrono::nanoseconds d_mpi_comm_frequency)
: Monitor_BFER_reduction<B,R>(monitors),
  master_thread_id(master_thread_id),
  is_fe_limit_achieved(false),
  t_last_mpi_comm(std::chrono::steady_clock::now()),
  d_mpi_comm_frequency(d_mpi_comm_frequency)
{
	const std::string name = "Monitor_BFER_reduction_mpi";
	this->set_name(name);

	constexpr n_vals = 4;
	int blen[n_vals];
	MPI_Aint displacements[n_vals];
	MPI_Datatype oldtypes[n_vals];

	blen[0] = 1; displacements[0] = offsetof(monitor_vals, n_be  ); oldtypes[0] = MPI_UNSIGNED_LONG_LONG;
	blen[1] = 1; displacements[1] = offsetof(monitor_vals, n_fe  ); oldtypes[1] = MPI_UNSIGNED_LONG_LONG;
	blen[2] = 1; displacements[2] = offsetof(monitor_vals, n_fra ); oldtypes[2] = MPI_UNSIGNED_LONG_LONG;
	blen[3] = 1; displacements[3] = offsetof(monitor_vals, n_tri ); oldtypes[3] = MPI_UNSIGNED_LONG_LONG;
	//	blen[4] = 1; displacements[4] = offsetof(monitor_vals, MI    ); oldtypes[4] = MPI_FLOAT;

	if (auto ret = MPI_Type_create_struct(n_vals, blen, displacements, oldtypes, &MPI_monitor_vals))
	{
		std::stringstream message;
		message << "'MPI_Type_create_struct' returned '" << ret << "' error code.";
		throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (auto ret = MPI_Type_commit(&MPI_monitor_vals))
	{
		std::stringstream message;
		message << "'MPI_Type_commit' returned '" << ret << "' error code.";
		throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (auto ret = MPI_Op_create(MPI_SUM_monitor_vals_func, true, &MPI_SUM_monitor_vals))
	{
		std::stringstream message;
		message << "'MPI_Op_create' returned '" << ret << "' error code.";
		throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
	}
}

template <typename B, typename R>
Monitor_BFER_reduction_mpi<B,R>
::~Monitor_BFER_reduction_mpi()
{
}

template <typename B, typename R>
bool Monitor_BFER_reduction_mpi<B,R>
::fe_limit_achieved()
{
	// only the master thread can do this
	if (std::this_thread::get_id() == this->master_thread_id &&
	    ((std::chrono::steady_clock::now() - t_last_mpi_comm) >= d_mpi_comm_frequency))
	{
		monitor_vals mvals_recv;
		monitor_vals mvals_send = { this->get_n_be()           - this->n_bit_errors,
		                            this->get_n_fe()           - this->n_frame_errors,
		                            this->get_n_analyzed_fra() - this->n_analyzed_frames,
		                            this->get_n_MI_trials()    - this->n_MI_trials};
		                            //(float)(this->get_MI()     - this->MI) };

		MPI_Allreduce(&mvals_send, &mvals_recv, 1, MPI_monitor_vals, MPI_SUM_monitor_vals, MPI_COMM_WORLD);

		this->n_bit_errors      = mvals_recv.n_be   - mvals_send.n_be;
		this->n_frame_errors    = mvals_recv.n_fe   - mvals_send.n_fe;
		this->n_analyzed_frames = mvals_recv.n_fra  - mvals_send.n_fra;
		this->n_MI_trials       = mvals_recv.n_tri  - mvals_send.n_tri;
		//this->MI                = mvals_recv.MI     - mvals_send.MI;

		t_last_mpi_comm = std::chrono::steady_clock::now();

		is_fe_limit_achieved = mvals_recv.n_fe >= this->get_fe_limit();
	}

	return is_fe_limit_achieved;
}

template <typename B, typename R>
void Monitor_BFER_reduction_mpi<B,R>
::reset()
{
	Monitor_BFER_reduction<B,R>::reset();
	is_fe_limit_achieved = false;
}

// ==================================================================================== explicit template instantiation
#include "Tools/types.h"
#ifdef MULTI_PREC
template class aff3ct::module::Monitor_BFER_reduction_mpi<B_8, R_8>;
template class aff3ct::module::Monitor_BFER_reduction_mpi<B_16,R_16>;
template class aff3ct::module::Monitor_BFER_reduction_mpi<B_32,R_32>;
template class aff3ct::module::Monitor_BFER_reduction_mpi<B_64,R_64>;
#else
template class aff3ct::module::Monitor_BFER_reduction_mpi<B,R>;
#endif
// ==================================================================================== explicit template instantiation

#endif
<commit_msg>Update Monitor_BFER_reduction_mpi.cpp<commit_after>#ifdef ENABLE_MPI

#include <stddef.h>
#include <sstream>

#include "Tools/Exception/exception.hpp"

#include "Monitor_BFER_reduction_mpi.hpp"

using namespace aff3ct;
using namespace aff3ct::module;

struct monitor_vals
{
	unsigned long long n_be;
	unsigned long long n_fe;
	unsigned long long n_fra;
	unsigned long long n_tri;
//	float              MI_sum;
};

void MPI_SUM_monitor_vals_func(void *in, void *inout, int *len, MPI_Datatype *datatype)
{
	auto    in_cvt = static_cast<monitor_vals*>(in   );
	auto inout_cvt = static_cast<monitor_vals*>(inout);

	for (auto i = 0; i < *len; i++)
	{
		inout_cvt[i].n_be  += in_cvt[i].n_be;
		inout_cvt[i].n_fe  += in_cvt[i].n_fe;

		inout_cvt[i].n_fra += in_cvt[i].n_fra;
		inout_cvt[i].n_tri += in_cvt[i].n_tri;
//		inout_cvt[i].MI    += in_cvt[i].MI;
	}
}

template <typename B, typename R>
Monitor_BFER_reduction_mpi<B,R>
::Monitor_BFER_reduction_mpi(const std::vector<Monitor_BFER<B,R>*> &monitors,
                             const std::thread::id master_thread_id,
                             const std::chrono::nanoseconds d_mpi_comm_frequency)
: Monitor_BFER_reduction<B,R>(monitors),
  master_thread_id(master_thread_id),
  is_fe_limit_achieved(false),
  t_last_mpi_comm(std::chrono::steady_clock::now()),
  d_mpi_comm_frequency(d_mpi_comm_frequency)
{
	const std::string name = "Monitor_BFER_reduction_mpi";
	this->set_name(name);

	constexpr int n_vals = 4;
	int blen[n_vals];
	MPI_Aint displacements[n_vals];
	MPI_Datatype oldtypes[n_vals];

	blen[0] = 1; displacements[0] = offsetof(monitor_vals, n_be  ); oldtypes[0] = MPI_UNSIGNED_LONG_LONG;
	blen[1] = 1; displacements[1] = offsetof(monitor_vals, n_fe  ); oldtypes[1] = MPI_UNSIGNED_LONG_LONG;
	blen[2] = 1; displacements[2] = offsetof(monitor_vals, n_fra ); oldtypes[2] = MPI_UNSIGNED_LONG_LONG;
	blen[3] = 1; displacements[3] = offsetof(monitor_vals, n_tri ); oldtypes[3] = MPI_UNSIGNED_LONG_LONG;
	//	blen[4] = 1; displacements[4] = offsetof(monitor_vals, MI    ); oldtypes[4] = MPI_FLOAT;

	if (auto ret = MPI_Type_create_struct(n_vals, blen, displacements, oldtypes, &MPI_monitor_vals))
	{
		std::stringstream message;
		message << "'MPI_Type_create_struct' returned '" << ret << "' error code.";
		throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (auto ret = MPI_Type_commit(&MPI_monitor_vals))
	{
		std::stringstream message;
		message << "'MPI_Type_commit' returned '" << ret << "' error code.";
		throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
	}

	if (auto ret = MPI_Op_create(MPI_SUM_monitor_vals_func, true, &MPI_SUM_monitor_vals))
	{
		std::stringstream message;
		message << "'MPI_Op_create' returned '" << ret << "' error code.";
		throw tools::runtime_error(__FILE__, __LINE__, __func__, message.str());
	}
}

template <typename B, typename R>
Monitor_BFER_reduction_mpi<B,R>
::~Monitor_BFER_reduction_mpi()
{
}

template <typename B, typename R>
bool Monitor_BFER_reduction_mpi<B,R>
::fe_limit_achieved()
{
	// only the master thread can do this
	if (std::this_thread::get_id() == this->master_thread_id &&
	    ((std::chrono::steady_clock::now() - t_last_mpi_comm) >= d_mpi_comm_frequency))
	{
		monitor_vals mvals_recv;
		monitor_vals mvals_send = { this->get_n_be()           - this->n_bit_errors,
		                            this->get_n_fe()           - this->n_frame_errors,
		                            this->get_n_analyzed_fra() - this->n_analyzed_frames,
		                            this->get_n_MI_trials()    - this->n_MI_trials};
		                            //(float)(this->get_MI()     - this->MI) };

		MPI_Allreduce(&mvals_send, &mvals_recv, 1, MPI_monitor_vals, MPI_SUM_monitor_vals, MPI_COMM_WORLD);

		this->n_bit_errors      = mvals_recv.n_be   - mvals_send.n_be;
		this->n_frame_errors    = mvals_recv.n_fe   - mvals_send.n_fe;
		this->n_analyzed_frames = mvals_recv.n_fra  - mvals_send.n_fra;
		this->n_MI_trials       = mvals_recv.n_tri  - mvals_send.n_tri;
		//this->MI                = mvals_recv.MI     - mvals_send.MI;

		t_last_mpi_comm = std::chrono::steady_clock::now();

		is_fe_limit_achieved = mvals_recv.n_fe >= this->get_fe_limit();
	}

	return is_fe_limit_achieved;
}

template <typename B, typename R>
void Monitor_BFER_reduction_mpi<B,R>
::reset()
{
	Monitor_BFER_reduction<B,R>::reset();
	is_fe_limit_achieved = false;
}

// ==================================================================================== explicit template instantiation
#include "Tools/types.h"
#ifdef MULTI_PREC
template class aff3ct::module::Monitor_BFER_reduction_mpi<B_8, R_8>;
template class aff3ct::module::Monitor_BFER_reduction_mpi<B_16,R_16>;
template class aff3ct::module::Monitor_BFER_reduction_mpi<B_32,R_32>;
template class aff3ct::module::Monitor_BFER_reduction_mpi<B_64,R_64>;
#else
template class aff3ct::module::Monitor_BFER_reduction_mpi<B,R>;
#endif
// ==================================================================================== explicit template instantiation

#endif
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/nest/p9_throttle_sync.H $  */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/// ----------------------------------------------------------------------------
/// @file  p9_throttle_sync.H
///
/// @brief p9_throttle_sync HWP
///
/// The purpose of this procedure is to triggers sync command from MC to
/// actually load the throttle values into the Centaurs.
///
/// ----------------------------------------------------------------------------
/// *HWP HWP Owner   : Joe McGill <jmcgill@us.ibm.com>
/// *HWP FW Owner    : Thi Tran <thi@us.ibm.com>
/// *HWP Team        : Nest
/// *HWP Level       : 1
/// *HWP Consumed by : HB
/// ----------------------------------------------------------------------------

#ifndef _P9_THROTTLE_SYNC_H_
#define _P9_THROTTLE_SYNC_H_

//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include <fapi2.H>

// Function pointer typedef definition for HWP call support
typedef fapi2::ReturnCode (*p9_throttle_sync_FP_t)(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&);

//----------------------------------------------------------------------------
// Constant definitions
//----------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Function prototypes
//------------------------------------------------------------------------------
///
/// @brief p9_throttle_sync procedure
///
/// This HWP is to triggers sync command from MC to actually load the
//  throttle values into the Centaurs.
///
/// @param[in]    i_target   Reference to TARGET_TYPE_PROC_CHIP target
///
/// @return FAPI2_RC_SUCCESS if success, else error code.
///
extern "C"
{

    fapi2::ReturnCode p9_throttle_sync(
        const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);

} // extern "C"

#endif  // _P9_THROTTLE_SYNC_H_
<commit_msg>L2 HWPs - p9_throttle_sync<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/nest/p9_throttle_sync.H $  */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* Licensed under the Apache License, Version 2.0 (the "License");        */
/* you may not use this file except in compliance with the License.       */
/* You may obtain a copy of the License at                                */
/*                                                                        */
/*     http://www.apache.org/licenses/LICENSE-2.0                         */
/*                                                                        */
/* Unless required by applicable law or agreed to in writing, software    */
/* distributed under the License is distributed on an "AS IS" BASIS,      */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or        */
/* implied. See the License for the specific language governing           */
/* permissions and limitations under the License.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/// ----------------------------------------------------------------------------
/// @file  p9_throttle_sync.H
///
/// @brief p9_throttle_sync HWP
///
/// The purpose of this procedure is to triggers sync command from a 'master'
/// MC to other MCs that have attached memory in a processor.
///
/// ----------------------------------------------------------------------------
/// *HWP HWP Owner   : Joe McGill <jmcgill@us.ibm.com>
/// *HWP FW Owner    : Thi Tran <thi@us.ibm.com>
/// *HWP Team        : Nest
/// *HWP Level       : 2
/// *HWP Consumed by : HB
/// ----------------------------------------------------------------------------
#ifndef _P9_THROTTLE_SYNC_H_
#define _P9_THROTTLE_SYNC_H_

//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include <fapi2.H>
#include <p9_nest_common_mc_def.H>
#include <p9_mc_scom_addresses.H>
#include <p9_mc_scom_addresses_fld.H>

// Function pointer typedef definition for HWP call support
typedef fapi2::ReturnCode (*p9_throttle_sync_FP_t)(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&);

//------------------------------------------------------------------------------
// Function prototypes
//------------------------------------------------------------------------------
///
/// @brief p9_throttle_sync procedure
///
/// The purpose of this procedure is to triggers sync command from a 'master'
/// MC to other MCs that have attached memory in a processor.
///
/// @param[in]    i_target   Reference to TARGET_TYPE_PROC_CHIP target
///
/// @return FAPI2_RC_SUCCESS if success, else error code.
///
extern "C"
{

    fapi2::ReturnCode p9_throttle_sync(
        const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);

} // extern "C"

#endif  // _P9_THROTTLE_SYNC_H_
<|endoftext|>


<commit_before>/**
  * Touhou Community Reliant Automatic Patcher
  * Main DLL
  *
  * ----
  *
  * Steam integration for games that are available through Steam, but don't
  * come with Steam integration themselves. Requires Valve's `steam_api.dll`,
  * which can be deleted to disable this feature.
  *
  * Initially, this was just meant to show the logged-in Steam user playing
  * the current game, but this also gives us the Steam overlay for free.
  * Doesn't seem to have any drawbacks either.
  *
  * To support Steam integration a patch needs to provide a "steam_appid"
  *	in it's GAMENAME.VERSION.js, GAMENAME.js or global.js file
  */

#include "thcrap.h"

#ifdef _AMD64_
const char *STEAM_API_DLL_FN = "steam_api64.dll";
#else
const char *STEAM_API_DLL_FN = "steam_api.dll";
#endif

typedef const char* TH_CDECL steam_appid_func_t(void);

// Steam API
// ---------
HMODULE hSteamAPI;
HKEY hSteamProcess;

typedef bool TH_CDECL DLL_FUNC_TYPE(SteamAPI, Init)();
typedef bool TH_CDECL DLL_FUNC_TYPE(SteamAPI, Shutdown)();

DLL_FUNC_DEF(SteamAPI, Init);
DLL_FUNC_DEF(SteamAPI, Shutdown);

#define STEAM_GET_PROC_ADDRESS(func) \
	SteamAPI_##func = (SteamAPI_##func##_t*)GetProcAddress(hSteamAPI, "SteamAPI_"#func);
// ---------

extern "C" TH_EXPORT void steam_mod_post_init(void)
{
	std::string appid = "";

	json_t *appid_obj = json_object_get(runconfig_json_get(), "steam_appid");
	if (appid_obj) {
		switch (json_typeof(appid_obj)) {
		case JSON_STRING:
			appid = json_string_value(appid_obj);
			break;
		case JSON_INTEGER:
			appid = std::to_string(json_integer_value(appid_obj));
			break;
		case JSON_REAL:
			appid = std::to_string(json_real_value(appid_obj));
			break;
		}
	}

	// Got AppID?
	if (appid == "") {
		return;
	}

	// Got Steam?
	if(RegOpenKeyExA(HKEY_CURRENT_USER,
		"Software\\Valve\\Steam\\ActiveProcess", 0, KEY_READ, &hSteamProcess
	)) {
		log_printf("[Steam] Not installed\n");
		return;
	}

	// Got steam_api.dll?
	const char *thcrap_dir = runconfig_thcrap_dir_get();

	size_t dll_fn_len = strlen(thcrap_dir) + strlen("\\bin\\") + strlen(STEAM_API_DLL_FN) + 1;
	VLA(char, dll_fn, dll_fn_len);
	defer(VLA_FREE(dll_fn));
	strcpy(dll_fn, thcrap_dir);
	strcat(dll_fn, "\\bin\\");
	strcat(dll_fn, STEAM_API_DLL_FN);

	hSteamAPI = LoadLibraryExU(dll_fn, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH);
	if(!hSteamAPI) {
		log_printf(
			"[Steam] Couldn't load %s (%s), no integration possible\n",
			dll_fn, lasterror_str()
		);
		return;
	}

	STEAM_GET_PROC_ADDRESS(Init);
	STEAM_GET_PROC_ADDRESS(Shutdown);
	if(!SteamAPI_Init || !SteamAPI_Shutdown) {
		log_printf("[Steam] %s corrupt, no integration possible\n", dll_fn);
		return;
	}

	SetEnvironmentVariableU("SteamAppId", appid.c_str());
	if(!SteamAPI_Init()) {
		// TODO: Figure out why?
		log_printf("[Steam] Initialization for AppID %s failed\n", appid);
		return;
	}

	log_printf("[Steam] Initialized for AppID %s\n", appid);
}

extern "C" TH_EXPORT void steam_mod_exit(void)
{
	RegCloseKey(hSteamProcess);
	if(!SteamAPI_Shutdown) {
		return;
	}
	SteamAPI_Shutdown();
	SteamAPI_Init = nullptr;
	SteamAPI_Shutdown = nullptr;
	FreeLibrary(hSteamAPI);
}
<commit_msg>thcrap: fix crash in Steam AppID logging<commit_after>/**
  * Touhou Community Reliant Automatic Patcher
  * Main DLL
  *
  * ----
  *
  * Steam integration for games that are available through Steam, but don't
  * come with Steam integration themselves. Requires Valve's `steam_api.dll`,
  * which can be deleted to disable this feature.
  *
  * Initially, this was just meant to show the logged-in Steam user playing
  * the current game, but this also gives us the Steam overlay for free.
  * Doesn't seem to have any drawbacks either.
  *
  * To support Steam integration a patch needs to provide a "steam_appid"
  *	in it's GAMENAME.VERSION.js, GAMENAME.js or global.js file
  */

#include "thcrap.h"

#ifdef _AMD64_
const char *STEAM_API_DLL_FN = "steam_api64.dll";
#else
const char *STEAM_API_DLL_FN = "steam_api.dll";
#endif

typedef const char* TH_CDECL steam_appid_func_t(void);

// Steam API
// ---------
HMODULE hSteamAPI;
HKEY hSteamProcess;

typedef bool TH_CDECL DLL_FUNC_TYPE(SteamAPI, Init)();
typedef bool TH_CDECL DLL_FUNC_TYPE(SteamAPI, Shutdown)();

DLL_FUNC_DEF(SteamAPI, Init);
DLL_FUNC_DEF(SteamAPI, Shutdown);

#define STEAM_GET_PROC_ADDRESS(func) \
	SteamAPI_##func = (SteamAPI_##func##_t*)GetProcAddress(hSteamAPI, "SteamAPI_"#func);
// ---------

extern "C" TH_EXPORT void steam_mod_post_init(void)
{
	std::string appid = "";

	json_t *appid_obj = json_object_get(runconfig_json_get(), "steam_appid");
	if (appid_obj) {
		switch (json_typeof(appid_obj)) {
		case JSON_STRING:
			appid = json_string_value(appid_obj);
			break;
		case JSON_INTEGER:
			appid = std::to_string(json_integer_value(appid_obj));
			break;
		case JSON_REAL:
			appid = std::to_string(json_real_value(appid_obj));
			break;
		}
	}

	// Got AppID?
	if (appid == "") {
		return;
	}

	// Got Steam?
	if(RegOpenKeyExA(HKEY_CURRENT_USER,
		"Software\\Valve\\Steam\\ActiveProcess", 0, KEY_READ, &hSteamProcess
	)) {
		log_printf("[Steam] Not installed\n");
		return;
	}

	// Got steam_api.dll?
	const char *thcrap_dir = runconfig_thcrap_dir_get();

	size_t dll_fn_len = strlen(thcrap_dir) + strlen("\\bin\\") + strlen(STEAM_API_DLL_FN) + 1;
	VLA(char, dll_fn, dll_fn_len);
	defer(VLA_FREE(dll_fn));
	strcpy(dll_fn, thcrap_dir);
	strcat(dll_fn, "\\bin\\");
	strcat(dll_fn, STEAM_API_DLL_FN);

	hSteamAPI = LoadLibraryExU(dll_fn, nullptr, LOAD_WITH_ALTERED_SEARCH_PATH);
	if(!hSteamAPI) {
		log_printf(
			"[Steam] Couldn't load %s (%s), no integration possible\n",
			dll_fn, lasterror_str()
		);
		return;
	}

	STEAM_GET_PROC_ADDRESS(Init);
	STEAM_GET_PROC_ADDRESS(Shutdown);
	if(!SteamAPI_Init || !SteamAPI_Shutdown) {
		log_printf("[Steam] %s corrupt, no integration possible\n", dll_fn);
		return;
	}

	SetEnvironmentVariableU("SteamAppId", appid.c_str());
	if(!SteamAPI_Init()) {
		// TODO: Figure out why?
		log_printf("[Steam] Initialization for AppID %s failed\n", appid);
		return;
	}

	log_printf("[Steam] Initialized for AppID %s\n", appid.c_str());
}

extern "C" TH_EXPORT void steam_mod_exit(void)
{
	RegCloseKey(hSteamProcess);
	if(!SteamAPI_Shutdown) {
		return;
	}
	SteamAPI_Shutdown();
	SteamAPI_Init = nullptr;
	SteamAPI_Shutdown = nullptr;
	FreeLibrary(hSteamAPI);
}
<|endoftext|>


<commit_before>#include "iteration/updater/angular_fixed_updater.h"
#include "formulation/tests/angular_stamper_mock.h"
#include "quadrature/tests/quadrature_set_mock.h"

#include "test_helpers/gmock_wrapper.h"

namespace  {

using namespace bart;

template <typename DimensionWrapper>
class IterationUpdaterAngularFixedUpdaterTest : public ::testing::Test {
 public:
  static constexpr int dim = DimensionWrapper::value;
  using StamperType = formulation::AngularStamperMock<dim>;
  using QuadratureSetType = quadrature::QuadratureSetMock<dim>;
  using FixedUpdaterType = iteration::updater::AngularFixedUpdater<formulation::AngularStamperI<dim>>;

  std::shared_ptr<StamperType> stamper_ptr_;
  std::shared_ptr<QuadratureSetType> quadrature_set_ptr_;
  std::unique_ptr<FixedUpdaterType> test_updater_ptr_;

  void SetUp() override;
};

template <typename DimensionWrapper>
void IterationUpdaterAngularFixedUpdaterTest<DimensionWrapper>::SetUp() {
  stamper_ptr_ = std::make_shared<StamperType>();
  quadrature_set_ptr_ = std::make_shared<QuadratureSetType>();

  test_updater_ptr_ = std::make_unique<FixedUpdaterType>(
      stamper_ptr_, quadrature_set_ptr_);
}

TYPED_TEST_SUITE(IterationUpdaterAngularFixedUpdaterTest,
                 bart::testing::AllDimensions);

TYPED_TEST(IterationUpdaterAngularFixedUpdaterTest, Constructor) {
  constexpr int dim = this->dim;
  using StamperType = formulation::AngularStamperMock<dim>;
  using QuadratureSetType = quadrature::QuadratureSetMock<dim>;
  using FixedUpdaterType =
      iteration::updater::AngularFixedUpdater<formulation::AngularStamperI<dim>>;

  auto stamper_ptr = std::make_shared<StamperType>();
  auto quadrature_set_ptr = std::make_shared<QuadratureSetType>();

  EXPECT_NO_THROW({
    FixedUpdaterType test_updater(stamper_ptr, quadrature_set_ptr);
  });

  EXPECT_ANY_THROW({
    FixedUpdaterType test_updater(nullptr, quadrature_set_ptr);
  });

  EXPECT_ANY_THROW({
    FixedUpdaterType test_updater(nullptr, nullptr);
  });

  EXPECT_ANY_THROW({
    FixedUpdaterType test_updater(nullptr, quadrature_set_ptr);
  });
}

TYPED_TEST(IterationUpdaterAngularFixedUpdaterTest, Getters) {
  auto stamper_ptr = this->test_updater_ptr_->stamper_ptr();
  auto quadrature_set_ptr = this->test_updater_ptr_->quadrature_set_ptr();

  ASSERT_NE(nullptr, stamper_ptr);
  EXPECT_EQ(stamper_ptr, this->stamper_ptr_.get());

  ASSERT_NE(nullptr, quadrature_set_ptr);
  EXPECT_EQ(quadrature_set_ptr, this->quadrature_set_ptr_.get());
}

} // namespace
<commit_msg>initial commit of domain tests for AngularFixedUpdater test<commit_after>#include <numeric>

#include "iteration/updater/angular_fixed_updater.h"
#include "formulation/tests/angular_stamper_mock.h"
#include "quadrature/tests/quadrature_set_mock.h"
#include "system/system.h"
#include "system/terms/tests/bilinear_term_mock.h"
#include "test_helpers/dealii_test_domain.h"
#include "test_helpers/test_helper_functions.h"

#include "test_helpers/gmock_wrapper.h"

namespace  {

using namespace bart;

using ::testing::Return;

/*
 * ===== BASIC TESTS ===========================================================
 * Tests operation of the constructor, provides mock stamper and observing ptr
 * to stamper.
 *
 */

template <typename DimensionWrapper>
class IterationUpdaterAngularFixedUpdaterTest : public ::testing::Test {
 public:
  static constexpr int dim = DimensionWrapper::value;
  using StamperType = formulation::AngularStamperMock<dim>;
  using QuadratureSetType = quadrature::QuadratureSetMock<dim>;
  using FixedUpdaterType = iteration::updater::AngularFixedUpdater<formulation::AngularStamperI<dim>>;

  std::shared_ptr<StamperType> stamper_ptr_;
  std::shared_ptr<QuadratureSetType> quadrature_set_ptr_;
  std::unique_ptr<FixedUpdaterType> test_updater_ptr_;

  void SetUp() override;
};

template <typename DimensionWrapper>
void IterationUpdaterAngularFixedUpdaterTest<DimensionWrapper>::SetUp() {
  stamper_ptr_ = std::make_shared<StamperType>();
  quadrature_set_ptr_ = std::make_shared<QuadratureSetType>();

  test_updater_ptr_ = std::make_unique<FixedUpdaterType>(
      stamper_ptr_, quadrature_set_ptr_);
}

TYPED_TEST_SUITE(IterationUpdaterAngularFixedUpdaterTest,
                 bart::testing::AllDimensions);

TYPED_TEST(IterationUpdaterAngularFixedUpdaterTest, Constructor) {
  constexpr int dim = this->dim;
  using StamperType = formulation::AngularStamperMock<dim>;
  using QuadratureSetType = quadrature::QuadratureSetMock<dim>;
  using FixedUpdaterType =
      iteration::updater::AngularFixedUpdater<formulation::AngularStamperI<dim>>;

  auto stamper_ptr = std::make_shared<StamperType>();
  auto quadrature_set_ptr = std::make_shared<QuadratureSetType>();

  EXPECT_NO_THROW({
    FixedUpdaterType test_updater(stamper_ptr, quadrature_set_ptr);
  });

  EXPECT_ANY_THROW({
    FixedUpdaterType test_updater(nullptr, quadrature_set_ptr);
  });

  EXPECT_ANY_THROW({
    FixedUpdaterType test_updater(nullptr, nullptr);
  });

  EXPECT_ANY_THROW({
    FixedUpdaterType test_updater(nullptr, quadrature_set_ptr);
  });
}

TYPED_TEST(IterationUpdaterAngularFixedUpdaterTest, Getters) {
  auto stamper_ptr = this->test_updater_ptr_->stamper_ptr();
  auto quadrature_set_ptr = this->test_updater_ptr_->quadrature_set_ptr();

  ASSERT_NE(nullptr, stamper_ptr);
  EXPECT_EQ(stamper_ptr, this->stamper_ptr_.get());

  ASSERT_NE(nullptr, quadrature_set_ptr);
  EXPECT_EQ(quadrature_set_ptr, this->quadrature_set_ptr_.get());
}

/* ===== DOMAIN TESTS ==========================================================
 * Tests updating of system matrices. DealiiTestDomain is used to provide
 * matrices with sparsity patterns that can be stamped properly. A test system
 * struct will be instantiated (populated with mock classes) and passed to
 * the updater to verify it mediates actions between the system and the
 * stamper correctly.
 */

template <typename DimensionWrapper>
class IterationUpdaterAngularFixedUpdaterDomainTest :
    public IterationUpdaterAngularFixedUpdaterTest<DimensionWrapper>,
    public bart::testing::DealiiTestDomain<DimensionWrapper::value> {
 public:
  IterationUpdaterAngularFixedUpdaterDomainTest()
      : group_number_(btest::RandomDouble(0, 10)),
        angle_index_(btest::RandomDouble(0, 10)),
        index_({group_number_, angle_index_}) {};

  bart::system::System test_system_;
  std::shared_ptr<system::MPISparseMatrix> matrix_ptr_;
  bart::system::terms::BilinearTermMock* mock_lhs_obs_ptr_;

  const system::GroupNumber group_number_;
  const system::AngleIndex angle_index_;
  const system::Index index_;

  void SetUp() override;
};

template <typename DimensionWrapper>
void IterationUpdaterAngularFixedUpdaterDomainTest<DimensionWrapper>::SetUp() {
  IterationUpdaterAngularFixedUpdaterTest<DimensionWrapper>::SetUp();
  bart::testing::DealiiTestDomain<DimensionWrapper::value>::SetUpDealii();

  auto mock_lhs_ptr = std::make_unique<system::terms::BilinearTermMock>();
  mock_lhs_obs_ptr_ = mock_lhs_ptr.get();

  matrix_ptr_ = std::make_shared<system::MPISparseMatrix>();
  matrix_ptr_->reinit(this->matrix_1);

  test_system_.left_hand_side_ptr_ = std::move(mock_lhs_ptr);
}

TYPED_TEST_SUITE(IterationUpdaterAngularFixedUpdaterDomainTest,
                 bart::testing::AllDimensions);

TYPED_TEST(IterationUpdaterAngularFixedUpdaterDomainTest,
    UpdateFixedNullptrMPI) {
  EXPECT_CALL(*this->mock_lhs_obs_ptr_, GetFixedTermPtr(this->index_))
      .WillOnce(Return(nullptr));
  EXPECT_ANY_THROW(this->test_updater_ptr_->UpdateFixedTerms(
      this->test_system_,
      this->group_number_,
      this->angle_index_));
}

TYPED_TEST(IterationUpdaterAngularFixedUpdaterDomainTest,
    UpdateFixedMPI) {

  // Get three random values to stamp
  auto double_vector = btest::RandomVector(3, 1, 10);
  double sum = std::accumulate(double_vector.begin(), double_vector.end(), 0);
  // Set the value of our expected result
  this->matrix_1 = 0;
  this->StampMatrix(this->matrix_1, sum);

  // Matrix we'll stamp
  *this->matrix_ptr_ = 0;
  EXPECT_CALL(*this->mock_lhs_obs_ptr_, GetFixedTermPtr(this->index_))
      .WillOnce(Return(this->matrix_ptr_));

}

} // namespace
<|endoftext|>


<commit_before>#include "JPetAnalysisModule.h"

ClassImp(JPetAnalysisModule);

JPetAnalysisModule::JPetAnalysisModule(const char* name, const char* title, TTree * shared_tree = NULL)
  : TNamed(name, title)
  , fSuperSharedTree( shared_tree )
{ }

JPetAnalysisModule::JPetAnalysisModule()
{ }

JPetAnalysisModule::~JPetAnalysisModule()
{
	for (int i = 0; i < fSubmodules.size(); i++)
		delete fSubmodules[i];

}

<commit_msg>minor fix<commit_after>#include "JPetAnalysisModule.h"

ClassImp(JPetAnalysisModule);

JPetAnalysisModule::JPetAnalysisModule(const char* name, const char* title, TTree * shared_tree)
  : TNamed(name, title)
  , fSuperSharedTree( shared_tree )
{ }

JPetAnalysisModule::JPetAnalysisModule()
{ }

JPetAnalysisModule::~JPetAnalysisModule()
{
	for (int i = 0; i < fSubmodules.size(); i++)
		delete fSubmodules[i];

}

<|endoftext|>


<commit_before>/*
 * DISTRHO Plugin Framework (DPF)
 * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
 *
 * Permission to use, copy, modify, and/or distribute this software for any purpose with
 * or without fee is hereby granted, provided that the above copyright notice and this
 * permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef DGL_WIDGET_HPP_INCLUDED
#define DGL_WIDGET_HPP_INCLUDED

#include "Geometry.hpp"

START_NAMESPACE_DGL

// --------------------------------------------------------------------------------------------------------------------
// Forward class names

class Application;
class SubWidget;
class TopLevelWidget;
class Window;

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

/**
   Base DGL Widget class.

   This is the base Widget class, from which all widgets are built.

   All widgets have a parent widget where they'll be drawn, this can be the top-level widget or a group widget.
   This parent is never changed during a widget's lifetime.

   Widgets receive events in relative coordinates. (0, 0) means its top-left position.

   The top-level widget will draw subwidgets in the order they are constructed.
   Early subwidgets are drawn first, at the bottom, then newer ones on top.
   Events are sent in the inverse order so that the top-most widgets get
   a chance to catch the event and stop its propagation.

   All widget event callbacks do nothing by default and onDisplay MUST be reimplemented by subclasses.

   @note It is not possible to subclass this Widget class directly, you must use SubWidget or TopLevelWidget instead.
 */
class Widget
{
public:
   /**
      Base event data.
      These are the fields present on all Widget events.

      @a mod  Currently active keyboard modifiers, @see Modifier.
      @a mod  Event flags, @see EventFlag.
      @a time Event timestamp (if any).
    */
    struct BaseEvent {
        uint mod;
        uint flags;
        uint time;

        /** Constructor */
        BaseEvent() noexcept : mod(0x0), flags(0x0), time(0) {}
        /** Destuctor */
        virtual ~BaseEvent() noexcept {}
    };

   /**
      Keyboard event.

      This event represents low-level key presses and releases.
      This can be used for "direct" keyboard handing like key bindings, but must not be interpreted as text input.

      Keys are represented portably as Unicode code points, using the "natural" code point for the key.
      The @a key field is the code for the pressed key, without any modifiers applied.
      For example, a press or release of the 'A' key will have `key` 97 ('a')
      regardless of whether shift or control are being held.

      Alternatively, the raw @a keycode can be used to work directly with physical keys,
      but note that this value is not portable and differs between platforms and hardware.

      @a press   True if the key was pressed, false if released.
      @a key     Unicode point of the key pressed.
      @a keycode Raw keycode.
      @see onKeyboard
    */
    struct KeyboardEvent : BaseEvent {
        bool press;
        uint key;
        uint keycode;

        /** Constructor */
        KeyboardEvent() noexcept
            : BaseEvent(),
              press(false),
              key(0),
              keycode(0) {}
    };

   /**
      Special keyboard event.

      DEPRECATED This used to be part of DPF due to pugl, but now deprecated and simply non-functional.
      All events go through KeyboardEvent or CharacterInputEvent, use those instead.
    */
    struct DISTRHO_DEPRECATED_BY("KeyboardEvent") SpecialEvent : BaseEvent {
        bool press;
        Key  key;

        /** Constructor */
        SpecialEvent() noexcept
            : BaseEvent(),
              press(false),
              key(Key(0)) {}
    };

   /**
      Character input event.

      This event represents text input, usually as the result of a key press.
      The text is given both as a Unicode character code and a UTF-8 string.

      Note that this event is generated by the platform's input system,
      so there is not necessarily a direct correspondence between text events and physical key presses.
      For example, with some input methods a sequence of several key presses will generate a single character.

      @a keycode   Raw key code.
      @a character Unicode character code.
      @a string    UTF-8 string.
      @see onCharacterInput
    */
    struct CharacterInputEvent : BaseEvent {
        uint keycode;
        uint character;
        char string[8];

        /** Constructor */
        CharacterInputEvent() noexcept
            : BaseEvent(),
              keycode(0),
              character(0),
#ifdef DISTRHO_PROPER_CPP11_SUPPORT
              string{'\0','\0','\0','\0','\0','\0','\0','\0'} {}
#else
              string() { std::memset(string, 0, sizeof(string)); }
#endif
    };

   /**
      Mouse press or release event.

      @a button      The button number starting from 1 (1 = left, 2 = middle, 3 = right).
      @a press       True if the button was pressed, false if released.
      @a pos         The widget-relative coordinates of the pointer.
      @a absolutePos The absolute coordinates of the pointer.
      @see onMouse
    */
    struct MouseEvent : BaseEvent {
        uint button;
        bool press;
        Point<double> pos;
        Point<double> absolutePos;

        /** Constructor */
        MouseEvent() noexcept
            : BaseEvent(),
              button(0),
              press(false),
              pos(0.0, 0.0),
              absolutePos(0.0, 0.0) {}
    };

   /**
      Mouse motion event.

      @a pos         The widget-relative coordinates of the pointer.
      @a absolutePos The absolute coordinates of the pointer.
      @see onMotion
    */
    struct MotionEvent : BaseEvent {
        Point<double> pos;
        Point<double> absolutePos;

        /** Constructor */
        MotionEvent() noexcept
            : BaseEvent(),
              pos(0.0, 0.0),
              absolutePos(0.0, 0.0) {}
    };

   /**
      Mouse scroll event.

      The scroll distance is expressed in "lines",
      an arbitrary unit that corresponds to a single tick of a detented mouse wheel.
      For example, `delta.y` = 1.0 scrolls 1 line up.
      Some systems and devices support finer resolution and/or higher values for fast scrolls,
      so programs should handle any value gracefully.

      @a pos         The widget-relative coordinates of the pointer.
      @a absolutePos The absolute coordinates of the pointer.
      @a delta       The scroll distance.
      @a direction   The direction of the scroll or "smooth".
      @see onScroll
    */
    struct ScrollEvent : BaseEvent {
        Point<double> pos;
        Point<double> absolutePos;
        Point<double> delta;
        ScrollDirection direction;

        /** Constructor */
        ScrollEvent() noexcept
            : BaseEvent(),
              pos(0.0, 0.0),
              absolutePos(0.0, 0.0),
              delta(0.0, 0.0),
              direction(kScrollSmooth) {}
    };

   /**
      Resize event.
      @a size    The new widget size.
      @a oldSize The previous size, may be null.
      @see onResize
    */
    struct ResizeEvent {
        Size<uint> size;
        Size<uint> oldSize;

        /** Constructor */
        ResizeEvent() noexcept
            : size(0, 0),
              oldSize(0, 0) {}
    };

   /**
      Widget position changed event.
      @a pos    The new absolute position of the widget.
      @a oldPos The previous absolute position of the widget.
      @see onPositionChanged
    */
    struct PositionChangedEvent {
        Point<int> pos;
        Point<int> oldPos;

        /** Constructor */
        PositionChangedEvent() noexcept
            : pos(0, 0),
              oldPos(0, 0) {}
    };

private:
   /**
      Private constructor, reserved for TopLevelWidget class.
    */
    explicit Widget(TopLevelWidget* topLevelWidget);

   /**
      Private constructor, reserved for SubWidget class.
    */
    explicit Widget(Widget* widgetToGroupTo);

public:
   /**
      Destructor.
    */
    virtual ~Widget();

   /**
      Check if this widget is visible within its parent window.
      Invisible widgets do not receive events except resize.
    */
    bool isVisible() const noexcept;

   /**
      Set widget visible (or not) according to @a visible.
    */
    void setVisible(bool visible);

   /**
      Show widget.
      This is the same as calling setVisible(true).
    */
    void show();

   /**
      Hide widget.
      This is the same as calling setVisible(false).
    */
    void hide();

   /**
      Get width.
    */
    uint getWidth() const noexcept;

   /**
      Get height.
    */
    uint getHeight() const noexcept;

   /**
      Get size.
    */
    const Size<uint> getSize() const noexcept;

   /**
      Set width.
    */
    void setWidth(uint width) noexcept;

   /**
      Set height.
    */
    void setHeight(uint height) noexcept;

   /**
      Set size using @a width and @a height values.
    */
    void setSize(uint width, uint height) noexcept;

   /**
      Set size.
    */
    void setSize(const Size<uint>& size) noexcept;

   /**
      Get the Id associated with this widget.
      @see setId
    */
    uint getId() const noexcept;

   /**
      Set an Id to be associated with this widget.
      @see getId
    */
    void setId(uint id) noexcept;

   /**
      Get the application associated with this widget's window.
      This is the same as calling `getTopLevelWidget()->getApp()`.
    */
    Application& getApp() const noexcept;

   /**
      Get the window associated with this widget.
      This is the same as calling `getTopLevelWidget()->getWindow()`.
    */
    Window& getWindow() const noexcept;

   /**
      Get the graphics context associated with this widget's window.
      GraphicsContext is an empty struct and needs to be casted into a different type in order to be usable,
      for example GraphicsContext.
      @see CairoSubWidget, CairoTopLevelWidget
    */
    const GraphicsContext& getGraphicsContext() const noexcept;

   /**
      Get top-level widget, as passed directly in the constructor
      or going up the chain of group widgets until it finds the top-level one.
    */
    TopLevelWidget* getTopLevelWidget() const noexcept;

   /**
      Request repaint of this widget's area to the window this widget belongs to.
      On the raw Widget class this function does nothing.
    */
    virtual void repaint() noexcept;

    DISTRHO_DEPRECATED_BY("getApp()")
    Application& getParentApp() const noexcept { return getApp(); }

    DISTRHO_DEPRECATED_BY("getWindow()")
    Window& getParentWindow() const noexcept { return getWindow(); }

protected:
   /**
      A function called to draw the widget contents.
    */
    virtual void onDisplay() = 0;

   /**
      A function called when a key is pressed or released.
      @return True to stop event propagation, false otherwise.
    */
    virtual bool onKeyboard(const KeyboardEvent&);

   /**
      A function called when an UTF-8 character is received.
      @return True to stop event propagation, false otherwise.
    */
    virtual bool onCharacterInput(const CharacterInputEvent&);

   /**
      A function called when a mouse button is pressed or released.
      @return True to stop event propagation, false otherwise.
    */
    virtual bool onMouse(const MouseEvent&);

   /**
      A function called when the pointer moves.
      @return True to stop event propagation, false otherwise.
    */
    virtual bool onMotion(const MotionEvent&);

   /**
      A function called on scrolling (e.g. mouse wheel or track pad).
      @return True to stop event propagation, false otherwise.
    */
    virtual bool onScroll(const ScrollEvent&);

   /**
      A function called when the widget is resized.
    */
    virtual void onResize(const ResizeEvent&);

   /**
      A function called when a special key is pressed or released.
      DEPRECATED use onKeyboard or onCharacterInput
    */
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 460
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
    virtual bool onSpecial(const SpecialEvent&) { return false; }
#if defined(__clang__)
# pragma clang diagnostic pop
#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 460
# pragma GCC diagnostic pop
#endif

private:
    struct PrivateData;
    PrivateData* const pData;
    friend class SubWidget;
    friend class TopLevelWidget;

    DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Widget)
};

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

END_NAMESPACE_DGL

#endif // DGL_WIDGET_HPP_INCLUDED
<commit_msg>Reorder/organize the Widget event docs<commit_after>/*
 * DISTRHO Plugin Framework (DPF)
 * Copyright (C) 2012-2021 Filipe Coelho <falktx@falktx.com>
 *
 * Permission to use, copy, modify, and/or distribute this software for any purpose with
 * or without fee is hereby granted, provided that the above copyright notice and this
 * permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD
 * TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN
 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#ifndef DGL_WIDGET_HPP_INCLUDED
#define DGL_WIDGET_HPP_INCLUDED

#include "Geometry.hpp"

START_NAMESPACE_DGL

// --------------------------------------------------------------------------------------------------------------------
// Forward class names

class Application;
class SubWidget;
class TopLevelWidget;
class Window;

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

/**
   Base DGL Widget class.

   This is the base Widget class, from which all widgets are built.

   All widgets have a parent widget where they'll be drawn, this can be the top-level widget or a group widget.
   This parent is never changed during a widget's lifetime.

   Widgets receive events in relative coordinates. (0, 0) means its top-left position.

   The top-level widget will draw subwidgets in the order they are constructed.
   Early subwidgets are drawn first, at the bottom, then newer ones on top.
   Events are sent in the inverse order so that the top-most widgets get
   a chance to catch the event and stop its propagation.

   All widget event callbacks do nothing by default and onDisplay MUST be reimplemented by subclasses.

   @note It is not possible to subclass this Widget class directly, you must use SubWidget or TopLevelWidget instead.
 */
class Widget
{
public:
   /**
      Base event data.
      These are the fields present on all Widget events.
    */
    struct BaseEvent {
        /** Currently active keyboard modifiers. @see Modifier */
        uint mod;
        /** Event flags. @see EventFlag */
        uint flags;
        /** Event timestamp (if any). */
        uint time;

        /** Constructor for default/null values */
        BaseEvent() noexcept : mod(0x0), flags(0x0), time(0) {}
        /** Destuctor */
        virtual ~BaseEvent() noexcept {}
    };

   /**
      Keyboard event.

      This event represents low-level key presses and releases.
      This can be used for "direct" keyboard handing like key bindings, but must not be interpreted as text input.

      Keys are represented portably as Unicode code points, using the "natural" code point for the key.
      The @a key field is the code for the pressed key, without any modifiers applied.
      For example, a press or release of the 'A' key will have `key` 97 ('a')
      regardless of whether shift or control are being held.

      Alternatively, the raw @a keycode can be used to work directly with physical keys,
      but note that this value is not portable and differs between platforms and hardware.

      @see onKeyboard
    */
    struct KeyboardEvent : BaseEvent {
        /** True if the key was pressed, false if released. */
        bool press;
        /** Unicode point of the key pressed. */
        uint key;
        /** Raw keycode. */
        uint keycode;

        /** Constructor for default/null values */
        KeyboardEvent() noexcept
            : BaseEvent(),
              press(false),
              key(0),
              keycode(0) {}
    };

   /**
      Special keyboard event.

      DEPRECATED This used to be part of DPF due to pugl, but now deprecated and simply non-functional.
      All events go through KeyboardEvent or CharacterInputEvent, use those instead.
    */
    struct DISTRHO_DEPRECATED_BY("KeyboardEvent") SpecialEvent : BaseEvent {
        bool press;
        Key key;

        /** Constructor for default/null values */
        SpecialEvent() noexcept
            : BaseEvent(),
              press(false),
              key(Key(0)) {}
    };

   /**
      Character input event.

      This event represents text input, usually as the result of a key press.
      The text is given both as a Unicode character code and a UTF-8 string.

      Note that this event is generated by the platform's input system,
      so there is not necessarily a direct correspondence between text events and physical key presses.
      For example, with some input methods a sequence of several key presses will generate a single character.

      @see onCharacterInput
    */
    struct CharacterInputEvent : BaseEvent {
        /** Raw key code. */
        uint keycode;
        /** Unicode character code. */
        uint character;
        /** UTF-8 string. */
        char string[8];

        /** Constructor for default/null values */
        CharacterInputEvent() noexcept
            : BaseEvent(),
              keycode(0),
              character(0),
#ifdef DISTRHO_PROPER_CPP11_SUPPORT
              string{'\0','\0','\0','\0','\0','\0','\0','\0'} {}
#else
              string() { std::memset(string, 0, sizeof(string)); }
#endif
    };

   /**
      Mouse press or release event.
      @see onMouse
    */
    struct MouseEvent : BaseEvent {
        /** The button number starting from 1. @see MouseButton */
        uint button;
        /** True if the button was pressed, false if released. */
        bool press;
        /** The widget-relative coordinates of the pointer. */
        Point<double> pos;
        /** The absolute coordinates of the pointer. */
        Point<double> absolutePos;

        /** Constructor for default/null values */
        MouseEvent() noexcept
            : BaseEvent(),
              button(0),
              press(false),
              pos(0.0, 0.0),
              absolutePos(0.0, 0.0) {}
    };

   /**
      Mouse motion event.
      @see onMotion
    */
    struct MotionEvent : BaseEvent {
        /** The widget-relative coordinates of the pointer. */
        Point<double> pos;
        /** The absolute coordinates of the pointer. */
        Point<double> absolutePos;

        /** Constructor for default/null values */
        MotionEvent() noexcept
            : BaseEvent(),
              pos(0.0, 0.0),
              absolutePos(0.0, 0.0) {}
    };

   /**
      Mouse scroll event.

      The scroll distance is expressed in "lines",
      an arbitrary unit that corresponds to a single tick of a detented mouse wheel.
      For example, `delta.y` = 1.0 scrolls 1 line up.
      Some systems and devices support finer resolution and/or higher values for fast scrolls,
      so programs should handle any value gracefully.

      @see onScroll
    */
    struct ScrollEvent : BaseEvent {
        /** The widget-relative coordinates of the pointer. */
        Point<double> pos;
        /** The absolute coordinates of the pointer. */
        Point<double> absolutePos;
        /** The scroll distance. */
        Point<double> delta;
        /** The direction of the scroll or "smooth". */
        ScrollDirection direction;

        /** Constructor for default/null values */
        ScrollEvent() noexcept
            : BaseEvent(),
              pos(0.0, 0.0),
              absolutePos(0.0, 0.0),
              delta(0.0, 0.0),
              direction(kScrollSmooth) {}
    };

   /**
      Resize event.
      @see onResize
    */
    struct ResizeEvent {
        /** The new widget size. */
        Size<uint> size;
        /** The previous size, can be null. */
        Size<uint> oldSize;

        /** Constructor for default/null values */
        ResizeEvent() noexcept
            : size(0, 0),
              oldSize(0, 0) {}
    };

   /**
      Widget position changed event.
      @see onPositionChanged
    */
    struct PositionChangedEvent {
        /** The new absolute position of the widget. */
        Point<int> pos;
        /** The previous absolute position of the widget. */
        Point<int> oldPos;

        /** Constructor for default/null values */
        PositionChangedEvent() noexcept
            : pos(0, 0),
              oldPos(0, 0) {}
    };

private:
   /**
      Private constructor, reserved for TopLevelWidget class.
    */
    explicit Widget(TopLevelWidget* topLevelWidget);

   /**
      Private constructor, reserved for SubWidget class.
    */
    explicit Widget(Widget* widgetToGroupTo);

public:
   /**
      Destructor.
    */
    virtual ~Widget();

   /**
      Check if this widget is visible within its parent window.
      Invisible widgets do not receive events except resize.
    */
    bool isVisible() const noexcept;

   /**
      Set widget visible (or not) according to @a visible.
    */
    void setVisible(bool visible);

   /**
      Show widget.
      This is the same as calling setVisible(true).
    */
    void show();

   /**
      Hide widget.
      This is the same as calling setVisible(false).
    */
    void hide();

   /**
      Get width.
    */
    uint getWidth() const noexcept;

   /**
      Get height.
    */
    uint getHeight() const noexcept;

   /**
      Get size.
    */
    const Size<uint> getSize() const noexcept;

   /**
      Set width.
    */
    void setWidth(uint width) noexcept;

   /**
      Set height.
    */
    void setHeight(uint height) noexcept;

   /**
      Set size using @a width and @a height values.
    */
    void setSize(uint width, uint height) noexcept;

   /**
      Set size.
    */
    void setSize(const Size<uint>& size) noexcept;

   /**
      Get the Id associated with this widget.
      @see setId
    */
    uint getId() const noexcept;

   /**
      Set an Id to be associated with this widget.
      @see getId
    */
    void setId(uint id) noexcept;

   /**
      Get the application associated with this widget's window.
      This is the same as calling `getTopLevelWidget()->getApp()`.
    */
    Application& getApp() const noexcept;

   /**
      Get the window associated with this widget.
      This is the same as calling `getTopLevelWidget()->getWindow()`.
    */
    Window& getWindow() const noexcept;

   /**
      Get the graphics context associated with this widget's window.
      GraphicsContext is an empty struct and needs to be casted into a different type in order to be usable,
      for example GraphicsContext.
      @see CairoSubWidget, CairoTopLevelWidget
    */
    const GraphicsContext& getGraphicsContext() const noexcept;

   /**
      Get top-level widget, as passed directly in the constructor
      or going up the chain of group widgets until it finds the top-level one.
    */
    TopLevelWidget* getTopLevelWidget() const noexcept;

   /**
      Request repaint of this widget's area to the window this widget belongs to.
      On the raw Widget class this function does nothing.
    */
    virtual void repaint() noexcept;

    DISTRHO_DEPRECATED_BY("getApp()")
    Application& getParentApp() const noexcept { return getApp(); }

    DISTRHO_DEPRECATED_BY("getWindow()")
    Window& getParentWindow() const noexcept { return getWindow(); }

protected:
   /**
      A function called to draw the widget contents.
    */
    virtual void onDisplay() = 0;

   /**
      A function called when a key is pressed or released.
      @return True to stop event propagation, false otherwise.
    */
    virtual bool onKeyboard(const KeyboardEvent&);

   /**
      A function called when an UTF-8 character is received.
      @return True to stop event propagation, false otherwise.
    */
    virtual bool onCharacterInput(const CharacterInputEvent&);

   /**
      A function called when a mouse button is pressed or released.
      @return True to stop event propagation, false otherwise.
    */
    virtual bool onMouse(const MouseEvent&);

   /**
      A function called when the pointer moves.
      @return True to stop event propagation, false otherwise.
    */
    virtual bool onMotion(const MotionEvent&);

   /**
      A function called on scrolling (e.g. mouse wheel or track pad).
      @return True to stop event propagation, false otherwise.
    */
    virtual bool onScroll(const ScrollEvent&);

   /**
      A function called when the widget is resized.
    */
    virtual void onResize(const ResizeEvent&);

   /**
      A function called when a special key is pressed or released.
      DEPRECATED use onKeyboard or onCharacterInput
    */
#if defined(__clang__)
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wdeprecated-declarations"
#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 460
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
    virtual bool onSpecial(const SpecialEvent&) { return false; }
#if defined(__clang__)
# pragma clang diagnostic pop
#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__) >= 460
# pragma GCC diagnostic pop
#endif

private:
    struct PrivateData;
    PrivateData* const pData;
    friend class SubWidget;
    friend class TopLevelWidget;

    DISTRHO_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Widget)
};

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

END_NAMESPACE_DGL

#endif // DGL_WIDGET_HPP_INCLUDED
<|endoftext|>


<commit_before>/*
* Dataset_opencvTest.cpp
* Tests Dataset_opencv
*
Copyright 2017 Wojciech Wilgierz

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 <gtest/gtest.h>
#include <span.h>
#include <opencv2/core/mat.hpp>
#include "Spectre.libClassifier/Dataset_opencv.h"
#include "Spectre.libException/InconsistentArgumentSizesException.h"
#include "Spectre.libException/OutOfRangeException.h"

namespace
{
using namespace Spectre::libClassifier;
using namespace Spectre::libException;

class Dataset_opencvInitializationTest : public ::testing::Test
{
public:
protected:
	const std::vector<DataType> data_long{ 0.5f, 0.4f, 0.6f, 1.1f, 1.6f, 0.7f, 2.1f, 1.0f, 0.6f };
	const std::vector<DataType> data_short{ 0.5f, 0.4f, 0.6f };
	const std::vector<Label> labels{ 3, 7, 14 };
	const std::vector<Label> labels_too_long{ 3, 7, 14, 5 };
};

TEST_F(Dataset_opencvInitializationTest, correct_dataset_opencv_initialization_col_size_one)
{
	EXPECT_NO_THROW(Dataset_opencv(data_short, labels));
}

TEST_F(Dataset_opencvInitializationTest, correct_dataset_opencv_initialization)
{
	EXPECT_NO_THROW(Dataset_opencv(data_long, labels));
}

TEST_F(Dataset_opencvInitializationTest, throws_for_inconsistent_size)
{
	EXPECT_THROW(Dataset_opencv(data_short, labels_too_long), InconsistentArgumentSizesException);
}

TEST_F(Dataset_opencvInitializationTest, correct_dataset_opencv_initialization_from_mat_col_size_one)
{
	std::vector<DataType> tmp_data(data_short);
	std::vector<Label> tmp_labels(labels);
	cv::Mat mat_data(3, 1, CV_TYPE, tmp_data.data());
	cv::Mat mat_labels(3, 1, CV_LABEL_TYPE, tmp_labels.data());
	EXPECT_NO_THROW(Dataset_opencv(mat_data, mat_labels));
}

TEST_F(Dataset_opencvInitializationTest, correct_dataset_opencv_initialization_from_mat)
{
	std::vector<DataType> tmp_data(data_long);
	std::vector<Label> tmp_labels(labels);
	cv::Mat mat_data(3, 3, CV_TYPE, tmp_data.data());
	cv::Mat mat_labels(3, 1, CV_LABEL_TYPE, tmp_labels.data());
	EXPECT_NO_THROW(Dataset_opencv(mat_data, mat_labels));
}

TEST_F(Dataset_opencvInitializationTest, throws_for_inconsistent_size_from_mat)
{
	std::vector<DataType> tmp_data(data_long);
	std::vector<Label> tmp_labels(labels_too_long);
	cv::Mat mat_data(3, 3, CV_TYPE, tmp_data.data());
	cv::Mat mat_labels(4, 1, CV_LABEL_TYPE, tmp_labels.data());
	EXPECT_THROW(Dataset_opencv(mat_data, mat_labels), InconsistentArgumentSizesException);
}

class Dataset_opencvTest : public ::testing::Test
{
public:
	Dataset_opencvTest()
	{

	}

	bool compareCVMats(cv::Mat mat1, cv::Mat mat2)
	{
		if (mat1.rows != mat2.rows || mat1.cols != mat2.cols) return false;
		for (auto i = 0; i<(mat1.rows*mat1.cols); i++)
		{
			if (mat1.data[i] != mat2.data[i]) return false;
		}
		return true;
	}

protected:
	const std::vector<DataType> data{ 0.5f, 0.4f, 0.6f, 1.1f, 1.6f, 0.7f, 2.1f, 1.0f, 0.6f };
	const std::vector<Label> labels{ 3, 7, 14 };
	std::unique_ptr<Dataset_opencv> dataset;

	void SetUp() override
	{
		dataset = std::make_unique<Dataset_opencv>(data, labels);
	}
};

TEST_F(Dataset_opencvTest, throws_on_access_to_data_out_of_range)
{
	EXPECT_THROW((*dataset)[4], OutOfRangeException);
}

TEST_F(Dataset_opencvTest, check_getting_in_range_data)
{
	auto test = (*dataset)[1];
	std::vector<DataType> check({ 1.1f, 1.6f, 0.7f });
	for (auto i = 0u; i < check.size(); i++)
	{
		EXPECT_EQ(test[i], check[i]);
	}
}

TEST_F(Dataset_opencvTest, throws_on_access_to_label_out_of_range)
{
	EXPECT_THROW(dataset->GetSampleMetadata(4), OutOfRangeException);
}

TEST_F(Dataset_opencvTest, check_getting_in_range_label)
{
	auto test = dataset->GetSampleMetadata(1);
	Label check = 7;
	EXPECT_EQ(test, check);
}

TEST_F(Dataset_opencvTest, get_dataset_metadata)
{
	const auto& check = Empty::instance();
	EXPECT_EQ(&dataset->GetDatasetMetadata(), &check);
}

TEST_F(Dataset_opencvTest, get_data)
{
	gsl::span<const Observation> result = dataset->GetData();
	ASSERT_EQ(result.size(), data.size());
	for (auto i = 0u; i < data.size(); i++)
	{
        for (auto j = 0u; j < result[i].size(); ++j)
		    EXPECT_EQ(result[i][j], data[i * result[i].size() + j]) << i << " " << j;
	}
}

TEST_F(Dataset_opencvTest, get_labels)
{
	gsl::span<const Label> result = dataset->GetSampleMetadata();
	EXPECT_EQ(result.size(), labels.size());
	for (auto i = 0u; i < labels.size(); i++)
	{
		EXPECT_EQ(result[i], labels[i]);
	}
}

TEST_F(Dataset_opencvTest, check_correct_dataset_size)
{
	EXPECT_EQ(dataset->size(), labels.size());
}

TEST_F(Dataset_opencvTest, check_getting_data_to_mat)
{
	std::vector<DataType> mat_data{ 0.5f, 0.4f, 0.6f, 1.1f, 1.6f, 0.7f, 2.1f, 1.0f, 0.6f };
	cv::Mat check(3, 3, CV_TYPE, mat_data.data());
	cv::Mat result = dataset->getMatData();
	EXPECT_TRUE(compareCVMats(check, result));
}

TEST_F(Dataset_opencvTest, check_getting_labels_to_mat)
{
	std::vector<Label> mat_labels{ 3, 7, 14 };
	cv::Mat check(3, 1, CV_LABEL_TYPE, mat_labels.data());
	cv::Mat result = dataset->getMatLabels();
	EXPECT_TRUE(compareCVMats(check, result));
}

//advanced tests

TEST_F(Dataset_opencvTest, check_if_creating_copy)
{
	std::unique_ptr<Dataset_opencv> result = nullptr;
	// @gmrukwa: Opening new scope, so variables will get destroyed.
	{
		const std::vector<DataType> tmpData{ 0.5f, 0.4f, 0.6f, 1.1f, 1.6f, 0.7f, 2.1f, 1.0f, 0.6f };
		const std::vector<Label> tmpLabels{ 3, 7, 14 };

		result = std::make_unique<Dataset_opencv>(tmpData, tmpLabels);
	}

	EXPECT_EQ(data.size(), result->size());
}

}
<commit_msg>Fix libGenetic.Tests<commit_after>/*
* Dataset_opencvTest.cpp
* Tests Dataset_opencv
*
Copyright 2017 Wojciech Wilgierz

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 <gtest/gtest.h>
#include <span.h>
#include <opencv2/core/mat.hpp>
#include "Spectre.libClassifier/Dataset_opencv.h"
#include "Spectre.libException/InconsistentArgumentSizesException.h"
#include "Spectre.libException/OutOfRangeException.h"

namespace
{
using namespace Spectre::libClassifier;
using namespace Spectre::libException;

class Dataset_opencvInitializationTest : public ::testing::Test
{
public:
protected:
	const std::vector<DataType> data_long{ 0.5f, 0.4f, 0.6f, 1.1f, 1.6f, 0.7f, 2.1f, 1.0f, 0.6f };
	const std::vector<DataType> data_short{ 0.5f, 0.4f, 0.6f };
	const std::vector<Label> labels{ 3, 7, 14 };
	const std::vector<Label> labels_too_long{ 3, 7, 14, 5 };
};

TEST_F(Dataset_opencvInitializationTest, correct_dataset_opencv_initialization_col_size_one)
{
	EXPECT_NO_THROW(Dataset_opencv(data_short, labels));
}

TEST_F(Dataset_opencvInitializationTest, correct_dataset_opencv_initialization)
{
	EXPECT_NO_THROW(Dataset_opencv(data_long, labels));
}

TEST_F(Dataset_opencvInitializationTest, throws_for_inconsistent_size)
{
	EXPECT_THROW(Dataset_opencv(data_short, labels_too_long), InconsistentArgumentSizesException);
}

TEST_F(Dataset_opencvInitializationTest, correct_dataset_opencv_initialization_from_mat_col_size_one)
{
	std::vector<DataType> tmp_data(data_short);
	std::vector<Label> tmp_labels(labels);
	cv::Mat mat_data(3, 1, CV_TYPE, tmp_data.data());
	cv::Mat mat_labels(3, 1, CV_LABEL_TYPE, tmp_labels.data());
	EXPECT_NO_THROW(Dataset_opencv(mat_data, mat_labels));
}

TEST_F(Dataset_opencvInitializationTest, correct_dataset_opencv_initialization_from_mat)
{
	std::vector<DataType> tmp_data(data_long);
	std::vector<Label> tmp_labels(labels);
	cv::Mat mat_data(3, 3, CV_TYPE, tmp_data.data());
	cv::Mat mat_labels(3, 1, CV_LABEL_TYPE, tmp_labels.data());
	EXPECT_NO_THROW(Dataset_opencv(mat_data, mat_labels));
}

TEST_F(Dataset_opencvInitializationTest, throws_for_inconsistent_size_from_mat)
{
	std::vector<DataType> tmp_data(data_long);
	std::vector<Label> tmp_labels(labels_too_long);
	cv::Mat mat_data(3, 3, CV_TYPE, tmp_data.data());
	cv::Mat mat_labels(4, 1, CV_LABEL_TYPE, tmp_labels.data());
	EXPECT_THROW(Dataset_opencv(mat_data, mat_labels), InconsistentArgumentSizesException);
}

class Dataset_opencvTest : public ::testing::Test
{
public:
	Dataset_opencvTest()
	{

	}

	bool compareCVMats(cv::Mat mat1, cv::Mat mat2)
	{
		if (mat1.rows != mat2.rows || mat1.cols != mat2.cols) return false;
		for (auto i = 0; i<(mat1.rows*mat1.cols); i++)
		{
			if (mat1.data[i] != mat2.data[i]) return false;
		}
		return true;
	}

protected:
	const std::vector<DataType> data{ 0.5f, 0.4f, 0.6f, 1.1f, 1.6f, 0.7f, 2.1f, 1.0f, 0.6f };
	const std::vector<Label> labels{ 3, 7, 14 };
	std::unique_ptr<Dataset_opencv> dataset;

	void SetUp() override
	{
		dataset = std::make_unique<Dataset_opencv>(data, labels);
	}
};

TEST_F(Dataset_opencvTest, throws_on_access_to_data_out_of_range)
{
	EXPECT_THROW((*dataset)[4], OutOfRangeException);
}

TEST_F(Dataset_opencvTest, check_getting_in_range_data)
{
	auto test = (*dataset)[1];
	std::vector<DataType> check({ 1.1f, 1.6f, 0.7f });
	for (auto i = 0u; i < check.size(); i++)
	{
		EXPECT_EQ(test[i], check[i]);
	}
}

TEST_F(Dataset_opencvTest, throws_on_access_to_label_out_of_range)
{
	EXPECT_THROW(dataset->GetSampleMetadata(4), OutOfRangeException);
}

TEST_F(Dataset_opencvTest, check_getting_in_range_label)
{
	auto test = dataset->GetSampleMetadata(1);
	Label check = 7;
	EXPECT_EQ(test, check);
}

TEST_F(Dataset_opencvTest, get_dataset_metadata)
{
	const auto& check = Empty::instance();
	EXPECT_EQ(&dataset->GetDatasetMetadata(), &check);
}

TEST_F(Dataset_opencvTest, get_data)
{
    const auto& local_dataset = *dataset;
	gsl::span<const Observation> result = dataset->GetData();
    const auto numberOfObservations = local_dataset.size();
    const auto numberofColumns = local_dataset[0].size();

	ASSERT_EQ(result.size(), numberOfObservations);

    for (auto i = 0u; i < numberOfObservations; i++)
	{
        EXPECT_EQ(result[i].size(), numberofColumns) << i;
        for (auto j = 0u; j < numberofColumns; ++j)
        {
            EXPECT_EQ(result[i][j], local_dataset[i][j]) << i << " " << j;
        }
	}
}

TEST_F(Dataset_opencvTest, get_labels)
{
	gsl::span<const Label> result = dataset->GetSampleMetadata();
	EXPECT_EQ(result.size(), labels.size());
	for (auto i = 0u; i < labels.size(); i++)
	{
		EXPECT_EQ(result[i], labels[i]);
	}
}

TEST_F(Dataset_opencvTest, check_correct_dataset_size)
{
	EXPECT_EQ(dataset->size(), labels.size());
}

TEST_F(Dataset_opencvTest, check_getting_data_to_mat)
{
	std::vector<DataType> mat_data{ 0.5f, 0.4f, 0.6f, 1.1f, 1.6f, 0.7f, 2.1f, 1.0f, 0.6f };
	cv::Mat check(3, 3, CV_TYPE, mat_data.data());
	cv::Mat result = dataset->getMatData();
	EXPECT_TRUE(compareCVMats(check, result));
}

TEST_F(Dataset_opencvTest, check_getting_labels_to_mat)
{
	std::vector<Label> mat_labels{ 3, 7, 14 };
	cv::Mat check(3, 1, CV_LABEL_TYPE, mat_labels.data());
	cv::Mat result = dataset->getMatLabels();
	EXPECT_TRUE(compareCVMats(check, result));
}

//advanced tests

TEST_F(Dataset_opencvTest, check_if_creating_copy)
{
	std::unique_ptr<Dataset_opencv> result = nullptr;
    const std::vector<DataType> tmpData{ 0.5f, 0.4f, 0.6f, 1.1f, 1.6f, 0.7f, 2.1f, 1.0f, 0.6f };
    const std::vector<Label> tmpLabels{ 3, 7, 14 };
    const auto numberOfObservations = tmpLabels.size();
    const auto numberOfColumns = tmpData.size() / numberOfObservations;

	// @gmrukwa: Opening new scope, so variables will get destroyed.
	{
		const std::vector<DataType> tmpDataDestroyed(tmpData);
		const std::vector<Label> tmpLabelsDestroyed(tmpLabels);

		result = std::make_unique<Dataset_opencv>(tmpDataDestroyed, tmpLabelsDestroyed);
	}

	ASSERT_EQ(result->size(), numberOfObservations);

    const auto& result_dataset = *result;
    for(auto i = 0u; i < numberOfObservations; ++i)
    {
        for (auto j = 0u; j < result_dataset[i].size(); ++j)
        {
            EXPECT_EQ(result_dataset[i][j], tmpData[i * numberOfColumns + j]) << i << " " << j;
        }
    }
}

}
<|endoftext|>


<commit_before>#include "Layer/fully_connected_neural_network.hpp"

using namespace Convolutional;
using namespace Convolutional::Layer;

auto FullyConnectedNeuralNetwork::ProcessMultiMatrix(const MultiMatrix& multiMatrix) -> MultiMatrix {
	const auto inputCount = multiMatrix.GetDimensionCount() * multiMatrix.GetElementCount();

	inputNeurons = std::vector<Neuron>(inputCount, Neuron());
	inputNeurons.push_back(BiasNeuron());

	outputNeurons = std::vector<Neuron>(outputNeurons.size(), Neuron(inputCount + 1));

	for (auto& input : inputNeurons)
		for (auto& output : outputNeurons)
			output.AddConnection({input, output});

	std::size_t currentNeuron = 0;
	for (const auto& subMatrix : multiMatrix) {
		for (auto input : subMatrix) {
			inputNeurons[currentNeuron].lastActionPotential = input;
			currentNeuron++;
		}
	}

	for (auto& neuron : outputNeurons) {
		for (const auto& connection : neuron.connections) {
			neuron.lastActionPotential += connection.from.lastActionPotential * connection.weight;
		}

		neuron.lastActionPotential = tanh(neuron.lastActionPotential);
	}

	Matrix::Size size;
	size.width = outputNeurons.size();
	size.height = 1;

	Matrix outputs(size);

	for (std::size_t i = 0; i < outputNeurons.size(); i++) {
		outputs.ElementAt({i, 0}) = outputNeurons[i].lastActionPotential;
	}

	return MultiMatrix {{outputs}};
}
<commit_msg>Change while loop to iteration<commit_after>#include "Layer/fully_connected_neural_network.hpp"

using namespace Convolutional;
using namespace Convolutional::Layer;

auto FullyConnectedNeuralNetwork::ProcessMultiMatrix(const MultiMatrix& multiMatrix) -> MultiMatrix {
	const auto inputCount = multiMatrix.GetDimensionCount() * multiMatrix.GetElementCount();

	inputNeurons = std::vector<Neuron>(inputCount, Neuron());
	inputNeurons.push_back(BiasNeuron());

	outputNeurons = std::vector<Neuron>(outputNeurons.size(), Neuron(inputCount + 1));

	for (auto& input : inputNeurons)
		for (auto& output : outputNeurons)
			output.AddConnection({input, output});

	for (auto& input : inputNeurons)
		for (const auto& subMatrix : multiMatrix)
			for (const auto& element : subMatrix)
				input.lastActionPotential = element;

	for (auto& neuron : outputNeurons) {
		for (const auto& connection : neuron.connections) {
			neuron.lastActionPotential += connection.from.lastActionPotential * connection.weight;
		}

		neuron.lastActionPotential = tanh(neuron.lastActionPotential);
	}

	Matrix::Size size;
	size.width = outputNeurons.size();
	size.height = 1;

	Matrix outputs(size);

	for (std::size_t i = 0; i < outputNeurons.size(); i++) {
		outputs.ElementAt({i, 0}) = outputNeurons[i].lastActionPotential;
	}

	return MultiMatrix {{outputs}};
}
<|endoftext|>