<commit_before>/*
** Copyright 2011-2013 Merethis
**
** This file is part of Centreon Broker.
**
** Centreon Broker is free software: you can redistribute it and/or
** modify it under the terms of the GNU General Public License version 2
** as published by the Free Software Foundation.
**
** Centreon Broker is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Centreon Broker. If not, see
** <http://www.gnu.org/licenses/>.
*/

#include "com/centreon/broker/notification/utilities/qhash_func.hh"
#include <QRegExp>
#include <QStringList>
#include "com/centreon/broker/logging/logging.hh"
#include "com/centreon/broker/notification/objects/string.hh"
#include "com/centreon/broker/notification/objects/command.hh"
#include "com/centreon/broker/notification/state.hh"
#include "com/centreon/broker/notification/macro_generator.hh"

using namespace com::centreon::broker::notification;
using namespace com::centreon::broker::notification::objects;

const QRegExp command::_macro_regex("\\$(\\w+)\\$");

// Forward declaration.
static void single_pass_replace(
              std::string &str,
              macro_generator::macro_container const& macros);

/**
 *  Constructor from a base command string.
 *
 *  @param[in] base_command  The command from which to construct this object.
 */
command::command(std::string const& base_command) :
  _base_command(base_command) {}

/**
 *  Copy constructor.
 *
 *  @param[in] obj  The object to copy.
 */
command::command(command const& obj) {
  command::operator=(obj);
}

/**
 *  Assignment operator.
 *
 *  @param[in] obj  The object to copy.
 *
 *  @return         A reference to this object.
 */
command& command::operator=(command const& obj) {
  if (this != &obj) {
    _name = obj._name;
    _base_command = obj._base_command;
  }
  return (*this);
}

/**
 *  Get the name of this command.
 *
 *  @return  The name of this command.
 */
std::string const& command::get_name() const throw() {
  return (_name);
}

/**
 *  Set the name of this command.
 *
 *  @param[in] name  The new name of this command.
 */
void command::set_name(std::string const& name) {
  _name = name;
}

/**
 *  Resolve this command.
 *
 *  @return  A string containing the resolved command.
 */
std::string command::resolve(
                       contact::ptr const& cnt,
                       node::ptr const& n,
                       node_cache const& cache,
                       state const& st,
                       action const& act) {
  // Match all the macros with the wonderful magic of RegExp.
  if (_macro_regex.indexIn(
        QString::fromStdString(_base_command)) == -1)
    return (_base_command);
  QStringList macro_list = _macro_regex.capturedTexts();
  macro_list.removeDuplicates();
  if (!macro_list.empty())
    macro_list.pop_front();

  // Generate each macro.
  macro_generator::macro_container macros;
  macros.reserve(macro_list.size());
  for (QStringList::const_iterator it(macro_list.begin()),
                                   end(macro_list.end());
       it != end;
       ++it)
    macros.insert(it->toStdString(), "");
  try {
    macro_generator generator;
    generator.generate(macros, n->get_node_id(), *cnt, st, cache, act);
  }
  catch (std::exception const& e) {
    logging::error(logging::medium)
      << "notification: couldn't resolve the macro '" << _name
      << "' (content: <<'" << _base_command << "'): " << e.what();
  } catch(...) {}

  // Replace the macros by their values.
  std::string resolved_command = _base_command;
  single_pass_replace(resolved_command, macros);

  return (resolved_command);
}

/**
 *  @brief Replace all the macros of the string in a single pass.
 *
 *  Marginally faster, and don't mangle contents and values.
 *
 *  @param[in] str     The string.
 *  @param[in] macros  The macros to replace.
 */
static void single_pass_replace(
              std::string& str,
              macro_generator::macro_container const& macros) {
  size_t pos = 0;

  std::vector<std::pair<std::string, std::string> > macro_list;
  for (macro_generator::macro_container::iterator it(macros.begin()),
                                                  end(macros.end());
       it != end;
       ++it) {
    std::string key = it.key();
    key.append("$");
    key.insert(key.begin(), '$');
    macro_list.push_back(std::make_pair(key, *it));
  }

  while (true) {
    size_t newpos = std::string::npos;
    std::vector<std::pair<std::string, std::string> >::const_iterator
      first_resolved_macro = macro_list.end();
    for (std::vector<std::pair<std::string, std::string> >::const_iterator
           it(macro_list.begin()),
           end(macro_list.end());
         it != end;
        ++it) {
      size_t tmp = str.find(it->second, pos);
      if (tmp < newpos) {
        newpos = tmp;
        first_resolved_macro = it;
      }
    }
    if (newpos == std::string::npos)
      return ;
    str.replace(
          pos,
          first_resolved_macro->first.size(),
          first_resolved_macro->second);
    pos = newpos + first_resolved_macro->second.size();
  }
}
<commit_msg>Notification: Command<commit_after>/*
** Copyright 2011-2013 Merethis
**
** This file is part of Centreon Broker.
**
** Centreon Broker is free software: you can redistribute it and/or
** modify it under the terms of the GNU General Public License version 2
** as published by the Free Software Foundation.
**
** Centreon Broker is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
** General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with Centreon Broker. If not, see
** <http://www.gnu.org/licenses/>.
*/

#include "com/centreon/broker/notification/utilities/qhash_func.hh"
#include <QRegExp>
#include <QStringList>
#include "com/centreon/broker/logging/logging.hh"
#include "com/centreon/broker/notification/objects/string.hh"
#include "com/centreon/broker/notification/objects/command.hh"
#include "com/centreon/broker/notification/state.hh"
#include "com/centreon/broker/notification/macro_generator.hh"

using namespace com::centreon::broker::notification;
using namespace com::centreon::broker::notification::objects;

const QRegExp command::_macro_regex("\\$(\\w+)\\$");

// Forward declaration.
static void single_pass_replace(
              std::string &str,
              macro_generator::macro_container const& macros);

/**
 *  Constructor from a base command string.
 *
 *  @param[in] base_command  The command from which to construct this object.
 */
command::command(std::string const& base_command) :
  _base_command(base_command) {}

/**
 *  Copy constructor.
 *
 *  @param[in] obj  The object to copy.
 */
command::command(command const& obj) {
  command::operator=(obj);
}

/**
 *  Assignment operator.
 *
 *  @param[in] obj  The object to copy.
 *
 *  @return         A reference to this object.
 */
command& command::operator=(command const& obj) {
  if (this != &obj) {
    _name = obj._name;
    _base_command = obj._base_command;
  }
  return (*this);
}

/**
 *  Get the name of this command.
 *
 *  @return  The name of this command.
 */
std::string const& command::get_name() const throw() {
  return (_name);
}

/**
 *  Set the name of this command.
 *
 *  @param[in] name  The new name of this command.
 */
void command::set_name(std::string const& name) {
  _name = name;
}

/**
 *  Resolve this command.
 *
 *  @return  A string containing the resolved command.
 */
std::string command::resolve(
                       contact::ptr const& cnt,
                       node::ptr const& n,
                       node_cache const& cache,
                       state const& st,
                       action const& act) {
  // Match all the macros with the wonderful magic of RegExp.
  if (_macro_regex.indexIn(
        QString::fromStdString(_base_command)) == -1)
    return (_base_command);
  QStringList macro_list = _macro_regex.capturedTexts();
  macro_list.removeDuplicates();
  if (!macro_list.empty())
    macro_list.pop_front();

  // Generate each macro.
  macro_generator::macro_container macros;
  macros.reserve(macro_list.size());
  for (QStringList::const_iterator it(macro_list.begin()),
                                   end(macro_list.end());
       it != end;
       ++it)
    macros.insert(it->toStdString(), "");
  try {
    macro_generator generator;
    generator.generate(macros, n->get_node_id(), *cnt, st, cache, act);
  }
  catch (std::exception const& e) {
    logging::error(logging::medium)
      << "notification: couldn't resolve the macro '" << _name
      << "' (content: <<'" << _base_command << "'): " << e.what();
  } catch(...) {}

  // Replace the macros by their values.
  std::string resolved_command = _base_command;
  single_pass_replace(resolved_command, macros);

  return (resolved_command);
}

/**
 *  @brief Replace all the macros of the string in a single pass.
 *
 *  Marginally faster, and don't mangle contents and values.
 *
 *  @param[in] str     The string.
 *  @param[in] macros  The macros to replace.
 */
static void single_pass_replace(
              std::string& str,
              macro_generator::macro_container const& macros) {
  size_t pos = 0;

  std::vector<std::pair<std::string, std::string> > macro_list;
  for (macro_generator::macro_container::iterator it(macros.begin()),
                                                  end(macros.end());
       it != end;
       ++it) {
    std::string key("$");
    key.append(it.key());
    key.append("$");
    macro_list.push_back(std::make_pair(key, *it));
  }

  while (true) {
    size_t newpos = std::string::npos;
    std::vector<std::pair<std::string, std::string> >::const_iterator
      first_resolved_macro = macro_list.end();
    for (std::vector<std::pair<std::string, std::string> >::const_iterator
           it(macro_list.begin()),
           end(macro_list.end());
         it != end;
        ++it) {
      size_t tmp = str.find(it->second, pos);
      if (tmp < newpos) {
        newpos = tmp;
        first_resolved_macro = it;
      }
    }
    if (newpos == std::string::npos)
      return ;
    str.replace(
          pos,
          first_resolved_macro->first.size(),
          first_resolved_macro->second);
    pos = newpos + first_resolved_macro->second.size();
  }
}
<|endoftext|>


<commit_before>#ifndef __JSON_HPP__
#define __JSON_HPP__

#include <cctype>
#include <string>
#include <vector>
#include <array>
#include <regex>

namespace JSON {
	using namespace std;

	struct Error {};
	struct SyntaxError : public Error {};
	struct LoadError : public Error {};
	struct AccessError : public Error {};

	template<typename _Value, char const ..._szName>
	struct Field {
		static char const s_szName;
		typedef _Value Type;
	};

	template<char const ..._sz>
	struct FieldName {};

	template<typename _Name, typename ..._Fields>
	struct FieldType {};

	template<typename _Value, char const ..._szName, typename ..._OtherFields>
	struct FieldType<FieldName<_szName...>, Field<_Value, _szName...>, _OtherFields...> {
		typedef _Value Type;
	};

	template<char const ..._szFieldName, typename _FirstField, typename ..._OtherFields>
	struct FieldType<FieldName<_szFieldName...>, _FirstField, _OtherFields...> {
		typedef typename FieldType<FieldName<_szFieldName...>, _OtherFields...>::Type Type;
	};

	template<typename _Value, char const ..._szName>
	char const Field<_Value, _szName...>::s_szName = { _szName... };

	template<typename ..._Fields>
	struct Object {};

	template<typename _Field, typename ..._Fields>
	struct Getter {};

	template<typename _Value, char const ..._szName, typename ..._OtherFields>
	struct Getter<Field<_Value, _szName...>, Field<_Value, _szName...>, _OtherFields...> {
		static _Value &Get(Object<Field<_Value, _szName...>, _OtherFields...> &rObject) {
			return rObject.m_Value;
		}

		static _Value const &Get(Object<Field<_Value, _szName...>, _OtherFields...> const &rObject) {
			return rObject.m_Value;
		}
	};

	template<typename _Value, char const ..._szName, typename _FirstField, typename ..._OtherFields>
	struct Getter<Field<_Value, _szName...>, _FirstField, _OtherFields...> {
		static _Value &Get(Object<_FirstField, _OtherFields...> &rObject) {
			return Getter<Field<_Value, _szName...>, _OtherFields...>::Get(rObject);
		}

		static _Value const &Get(Object<_FirstField, _OtherFields...> const &rObject) {
			return Getter<Field<_Value, _szName...>, _FirstField, _OtherFields...>::Get(rObject);
		}
	};

	template<>
	struct Object<> {
		Object() {}
		virtual ~Object() {}
	};

	template<typename _Value, char const ..._szName, typename ..._OtherFields>
	struct Object<Field<_Value, _szName...>, _OtherFields...> :
		public Object<_OtherFields...>
	{
		static char const s_szName[];
		_Value m_Value;

		Object() {}

		virtual ~Object() {}

		template<char const ..._szFieldName>
		typename FieldType<FieldName<_szFieldName...>, Field<_Value, _szName...>, _OtherFields...>::Type &Get() {
			return Getter<
				Field<typename FieldType<
					FieldName<_szFieldName...>,
					Field<_Value, _szName...>,
					_OtherFields...
				>::Type, _szFieldName...>,
				Field<_Value, _szName...>,
				_OtherFields...
			>::Get(*this);
		}

		template<char const ..._szFieldName>
		typename FieldType<FieldName<_szFieldName...>, Field<_Value, _szName...>, _OtherFields...>::Type const &Get() const {
			return Getter<
				Field<typename FieldType<
					FieldName<_szFieldName...>,
					Field<_Value, _szName...>,
					_OtherFields...
				>::Type, _szFieldName...>,
				Field<_Value, _szName...>,
				_OtherFields...
			>::Get(*this);
		}
	};

	template<typename _Value, char const ..._szName, typename ..._OtherFields>
	char const Object<Field<_Value, _szName...>, _OtherFields...>::s_szName[] = { _szName... };

	template<typename _Type>
	struct Serializer {
		static _Type Load(istream &ris);
		static ostream &Store(ostream &ros, _Type const &r);
	};

	template<>
	struct Serializer<nullptr_t> {
		static nullptr_t Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, nullptr_t const &r) {
			return ros << "null";
		}
	};

	template<>
	struct Serializer<bool> {
		static bool Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, bool const &r) {
			if (r) {
				return ros << "true";
			} else {
				return ros << "false";
			}
		}
	};

	template<>
	struct Serializer<int> {
		static int Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, int const &r) {
			return ros << r;
		}
	};

	template<>
	struct Serializer<unsigned int> {
		static unsigned int Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, unsigned int const &r) {
			return ros << r;
		}
	};

	template<>
	struct Serializer<double> {
		static double Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, double const &r) {
			return ros << r;
		}
	};

	template<>
	struct Serializer<string> {
		static string Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, string const &r) {
			return ros << '\"' << r << '\"'; // FIXME escape special characters
		}
	};

	template<typename ..._Fields>
	struct Serializer<Object<_Fields...>> {
		static Object<_Fields...> Load(istream &ris) {
			// TODO
			throw Error();
		}
	};

	template<typename _Element>
	struct Serializer<vector<_Element>> {
		static vector<_Element> Load(istream &ris) {
			// TODO
			throw Error();
		}
	};

	template<typename _Element, unsigned int _c>
	struct Serializer<array<_Element, _c>> {
		static array<_Element, _c> Load(istream &ris) {
			// TODO
			throw Error();
		}
	};

	template<typename _Type>
	_Type Load(istream &ris) {
		return Serializer<_Type>::Load(ris);
	}

	template<typename _Type>
	ostream &Store(ostream &ros, _Type const &r) {
		return Serializer<_Type>::Store(ros, r);
	}
}

#define UNPACK(sz) (sz)[0], ((sz)[0] > 0) ? UNPACK((sz) + 1) : 0

#endif
<commit_msg>Inlining getters and other basic methods<commit_after>#ifndef __JSON_HPP__
#define __JSON_HPP__

#include <cctype>
#include <string>
#include <vector>
#include <array>
#include <regex>

namespace JSON {
	using namespace std;

	struct Error {};
	struct SyntaxError : public Error {};
	struct LoadError : public Error {};
	struct AccessError : public Error {};

	template<typename _Value, char const ..._szName>
	struct Field {
		static char const s_szName;
		typedef _Value Type;
	};

	template<char const ..._sz>
	struct FieldName {};

	template<typename _Name, typename ..._Fields>
	struct FieldType {};

	template<typename _Value, char const ..._szName, typename ..._OtherFields>
	struct FieldType<FieldName<_szName...>, Field<_Value, _szName...>, _OtherFields...> {
		typedef _Value Type;
	};

	template<char const ..._szFieldName, typename _FirstField, typename ..._OtherFields>
	struct FieldType<FieldName<_szFieldName...>, _FirstField, _OtherFields...> {
		typedef typename FieldType<FieldName<_szFieldName...>, _OtherFields...>::Type Type;
	};

	template<typename _Value, char const ..._szName>
	char const Field<_Value, _szName...>::s_szName = { _szName... };

	template<typename ..._Fields>
	struct Object {};

	template<typename _Field, typename ..._Fields>
	struct Getter {};

	template<typename _Value, char const ..._szName, typename ..._OtherFields>
	struct Getter<Field<_Value, _szName...>, Field<_Value, _szName...>, _OtherFields...> {
		inline static _Value &Get(Object<Field<_Value, _szName...>, _OtherFields...> &rObject) {
			return rObject.m_Value;
		}

		inline static _Value const &Get(Object<Field<_Value, _szName...>, _OtherFields...> const &rObject) {
			return rObject.m_Value;
		}
	};

	template<typename _Value, char const ..._szName, typename _FirstField, typename ..._OtherFields>
	struct Getter<Field<_Value, _szName...>, _FirstField, _OtherFields...> {
		inline static _Value &Get(Object<_FirstField, _OtherFields...> &rObject) {
			return Getter<Field<_Value, _szName...>, _OtherFields...>::Get(rObject);
		}

		inline static _Value const &Get(Object<_FirstField, _OtherFields...> const &rObject) {
			return Getter<Field<_Value, _szName...>, _FirstField, _OtherFields...>::Get(rObject);
		}
	};

	template<>
	struct Object<> {
		Object() {}
		virtual ~Object() {}
	};

	template<typename _Value, char const ..._szName, typename ..._OtherFields>
	struct Object<Field<_Value, _szName...>, _OtherFields...> :
		public Object<_OtherFields...>
	{
		static char const s_szName[];
		_Value m_Value;

		Object() {}

		virtual ~Object() {}

		template<char const ..._szFieldName>
		inline typename FieldType<FieldName<_szFieldName...>, Field<_Value, _szName...>, _OtherFields...>::Type &Get() {
			return Getter<
				Field<typename FieldType<
					FieldName<_szFieldName...>,
					Field<_Value, _szName...>,
					_OtherFields...
				>::Type, _szFieldName...>,
				Field<_Value, _szName...>,
				_OtherFields...
			>::Get(*this);
		}

		template<char const ..._szFieldName>
		inline typename FieldType<FieldName<_szFieldName...>, Field<_Value, _szName...>, _OtherFields...>::Type const &Get() const {
			return Getter<
				Field<typename FieldType<
					FieldName<_szFieldName...>,
					Field<_Value, _szName...>,
					_OtherFields...
				>::Type, _szFieldName...>,
				Field<_Value, _szName...>,
				_OtherFields...
			>::Get(*this);
		}
	};

	template<typename _Value, char const ..._szName, typename ..._OtherFields>
	char const Object<Field<_Value, _szName...>, _OtherFields...>::s_szName[] = { _szName... };

	template<typename _Type>
	struct Serializer {
		static _Type Load(istream &ris);
		static ostream &Store(ostream &ros, _Type const &r);
	};

	template<>
	struct Serializer<nullptr_t> {
		static nullptr_t Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, nullptr_t const &r) {
			return ros << "null";
		}
	};

	template<>
	struct Serializer<bool> {
		static bool Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, bool const &r) {
			if (r) {
				return ros << "true";
			} else {
				return ros << "false";
			}
		}
	};

	template<>
	struct Serializer<int> {
		static int Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, int const &r) {
			return ros << r;
		}
	};

	template<>
	struct Serializer<unsigned int> {
		static unsigned int Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, unsigned int const &r) {
			return ros << r;
		}
	};

	template<>
	struct Serializer<double> {
		static double Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, double const &r) {
			return ros << r;
		}
	};

	template<>
	struct Serializer<string> {
		static string Load(istream &ris) {
			// TODO
			throw Error();
		}

		static ostream &Store(ostream &ros, string const &r) {
			return ros << '\"' << r << '\"'; // FIXME escape special characters
		}
	};

	template<typename ..._Fields>
	struct Serializer<Object<_Fields...>> {
		static Object<_Fields...> Load(istream &ris) {
			// TODO
			throw Error();
		}
	};

	template<typename _Element>
	struct Serializer<vector<_Element>> {
		static vector<_Element> Load(istream &ris) {
			// TODO
			throw Error();
		}
	};

	template<typename _Element, unsigned int _c>
	struct Serializer<array<_Element, _c>> {
		static array<_Element, _c> Load(istream &ris) {
			// TODO
			throw Error();
		}
	};

	template<typename _Type>
	inline _Type Load(istream &ris) {
		return Serializer<_Type>::Load(ris);
	}

	template<typename _Type>
	inline ostream &Store(ostream &ros, _Type const &r) {
		return Serializer<_Type>::Store(ros, r);
	}
}

#define UNPACK(sz) (sz)[0], ((sz)[0] > 0) ? UNPACK((sz) + 1) : 0

#endif
<|endoftext|>


<commit_before>#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/perf_event.h>
#include <asm/unistd.h>

#include "perf.hpp"
#include "interference_mpi.h"

// Copy paste from man page
static long
perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
                int cpu, int group_fd, unsigned long flags)
{
  int ret;

  ret = syscall(__NR_perf_event_open, hw_event, pid, cpu,
                group_fd, flags);
  return ret;
}

void PerfCounter::build_perf_attr(struct perf_event_attr *attr,
                                  const std::string &event)
{
  memset(attr, 0, sizeof(struct perf_event_attr));

  if (event == "cpu_cycles") {
    attr->type   = PERF_TYPE_HARDWARE;
    attr->config = PERF_COUNT_HW_CPU_CYCLES;
  } else if (event == "instructions") {
    attr->type   = PERF_TYPE_HARDWARE;
    attr->config = PERF_COUNT_HW_INSTRUCTIONS;
  } else if (event == "cache_references") {
    attr->type   = PERF_TYPE_HARDWARE;
    attr->config = PERF_COUNT_HW_CACHE_REFERENCES;
  } else if (event == "cache_misses") {
    attr->type   = PERF_TYPE_HARDWARE;
    attr->config = PERF_COUNT_HW_CACHE_MISSES;
  } else if (event == "branch_instructions") {
    attr->type   = PERF_TYPE_HARDWARE;
    attr->config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
  } else if (event == "branch_misses") {
    attr->type   = PERF_TYPE_HARDWARE;
    attr->config = PERF_COUNT_HW_BRANCH_MISSES;
  } else if (event == "migrations") {
    attr->type   = PERF_TYPE_SOFTWARE;
    attr->config = PERF_COUNT_SW_CPU_MIGRATIONS;
  } else if (event == "page_faults") {
    attr->type   = PERF_TYPE_SOFTWARE;
    attr->config = PERF_COUNT_SW_PAGE_FAULTS;
  } else if (event == "context_switches") {
    attr->type   = PERF_TYPE_SOFTWARE;
    attr->config = PERF_COUNT_SW_CONTEXT_SWITCHES;
  } else {
    throw std::runtime_error("Unknown perf event requested " + event);
  }

  attr->disabled = 1;
  attr->exclude_kernel = 1;
  attr->exclude_hv = 1;
  attr->size = sizeof(struct perf_event_attr);
}

PerfCounter::PerfCounter(int ranks, std::string name) :
  SingleCounter(ranks, name)
{
  struct perf_event_attr event;
  build_perf_attr(&event, name);

  _fd = perf_event_open(&event, 0, -1, -1, 0);
}

void PerfCounter::start_accounting()
{
  ioctl(_fd, PERF_EVENT_IOC_RESET, 0);
  ioctl(_fd, PERF_EVENT_IOC_ENABLE, 0);
}

void PerfCounter::end_accounting()
{
  ioctl(_fd, PERF_EVENT_IOC_DISABLE, 0);
  auto ret = read(_fd, &_value, sizeof(_value));
  if (ret != sizeof(_value)) {
    throw std::runtime_error("Failed to read counter: " + _name);
  }
  exchange();
}
<commit_msg>Account kernel for software events<commit_after>#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/perf_event.h>
#include <asm/unistd.h>

#include "perf.hpp"
#include "interference_mpi.h"

// Copy paste from man page
static long
perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
                int cpu, int group_fd, unsigned long flags)
{
  int ret;

  ret = syscall(__NR_perf_event_open, hw_event, pid, cpu,
                group_fd, flags);
  return ret;
}

void PerfCounter::build_perf_attr(struct perf_event_attr *attr,
                                  const std::string &event)
{
  memset(attr, 0, sizeof(struct perf_event_attr));

  attr->disabled = 1;
  attr->exclude_hv = 1;
  // For some event we need to take kernel into account
  attr->exclude_kernel = 1;
  attr->size = sizeof(struct perf_event_attr);

  if (event == "cpu_cycles") {
    attr->type   = PERF_TYPE_HARDWARE;
    attr->config = PERF_COUNT_HW_CPU_CYCLES;
  } else if (event == "instructions") {
    attr->type   = PERF_TYPE_HARDWARE;
    attr->config = PERF_COUNT_HW_INSTRUCTIONS;
  } else if (event == "cache_references") {
    attr->type   = PERF_TYPE_HARDWARE;
    attr->config = PERF_COUNT_HW_CACHE_REFERENCES;
  } else if (event == "cache_misses") {
    attr->type   = PERF_TYPE_HARDWARE;
    attr->config = PERF_COUNT_HW_CACHE_MISSES;
  } else if (event == "branch_instructions") {
    attr->type   = PERF_TYPE_HARDWARE;
    attr->config = PERF_COUNT_HW_BRANCH_INSTRUCTIONS;
  } else if (event == "branch_misses") {
    attr->type   = PERF_TYPE_HARDWARE;
    attr->config = PERF_COUNT_HW_BRANCH_MISSES;
  } else if (event == "migrations") {
    attr->type   = PERF_TYPE_SOFTWARE;
    attr->config = PERF_COUNT_SW_CPU_MIGRATIONS;
    attr->exclude_kernel = 0;
  } else if (event == "page_faults") {
    attr->type   = PERF_TYPE_SOFTWARE;
    attr->config = PERF_COUNT_SW_PAGE_FAULTS;
    attr->exclude_kernel = 0;
  } else if (event == "context_switches") {
    attr->type   = PERF_TYPE_SOFTWARE;
    attr->config = PERF_COUNT_SW_CONTEXT_SWITCHES;
    attr->exclude_kernel = 0;
  } else {
    throw std::runtime_error("Unknown perf event requested " + event);
  }

}

PerfCounter::PerfCounter(int ranks, std::string name) :
  SingleCounter(ranks, name)
{
  struct perf_event_attr event;
  build_perf_attr(&event, name);

  _fd = perf_event_open(&event, 0, -1, -1, 0);
}

void PerfCounter::start_accounting()
{
  ioctl(_fd, PERF_EVENT_IOC_RESET, 0);
  ioctl(_fd, PERF_EVENT_IOC_ENABLE, 0);
}

void PerfCounter::end_accounting()
{
  ioctl(_fd, PERF_EVENT_IOC_DISABLE, 0);
  auto ret = read(_fd, &_value, sizeof(_value));
  if (ret != sizeof(_value)) {
    throw std::runtime_error("Failed to read counter: " + _name);
  }
  exchange();
}
<|endoftext|>


<commit_before>#pragma once
#ifndef LIGHTPTR_HPP
# define LIGHTPTR_HPP

#include <cassert>

#include <atomic>

#include <memory>

#include <utility>

#include <type_traits>

namespace detail
{
  using counter_type = ::std::size_t;

  using atomic_type = ::std::atomic<counter_type>;

  template <typename T>
  using deleter_type = void (*)(T*);

  template <typename U>
  struct ref_type
  {
    using type = U&;
  };

  template <>
  struct ref_type<void>
  {
    using type = void;
  };

  template <typename T>
  inline void dec_ref(atomic_type* const counter_ptr,
    T* const ptr, deleter_type<T> const deleter)
  {
    if (counter_ptr && (counter_type(1) ==
      counter_ptr->fetch_sub(counter_type(1), ::std::memory_order_relaxed)))
    {
      delete counter_ptr;

      deleter(ptr);
    }
    // else do nothing
  }

  inline void inc_ref(atomic_type* const counter_ptr)
  {
    assert(counter_ptr);
    counter_ptr->fetch_add(counter_type(1), ::std::memory_order_relaxed);
  }
}

template <typename T>
struct light_ptr
{
  template <typename U, typename V>
  struct deletion_type
  {
    using type = V;
  };

  template <typename U, typename V>
  struct deletion_type<U[], V>
  {
    using type = V[];
  };

  template <typename U, typename V, ::std::size_t N>
  struct deletion_type<U[N], V>
  {
    using type = V[];
  };

  template <typename U>
  struct remove_array
  {
    using type = U;
  };

  template <typename U>
  struct remove_array<U[]>
  {
    using type = U;
  };

  template <typename U, ::std::size_t N>
  struct remove_array<U[N]>
  {
    using type = U;
  };

  using element_type = typename remove_array<T>::type;

  using deleter_type = ::detail::deleter_type<element_type>;

  light_ptr() = default;

  template <typename U>
  explicit light_ptr(U* const p,
    deleter_type const d = default_deleter<U>)
  {
    reset(p, d);
  }

  ~light_ptr() { ::detail::dec_ref(counter_ptr_, ptr_, deleter_); }

  light_ptr(light_ptr const& other) { *this = other; }

  light_ptr(light_ptr&& other) noexcept { *this = ::std::move(other); }

  light_ptr& operator=(light_ptr const& rhs)
  {
    if (*this != rhs)
    {
      ::detail::dec_ref(counter_ptr_, ptr_, deleter_);

      counter_ptr_ = rhs.counter_ptr_;
      ptr_ = rhs.ptr_;

      deleter_ = rhs.deleter_;

      ::detail::inc_ref(counter_ptr_);
    }
    // else do nothing

    return *this;
  }

  light_ptr& operator=(light_ptr&& rhs) noexcept
  {
    if (*this != rhs)
    {
      counter_ptr_ = rhs.counter_ptr_;
      ptr_ = rhs.ptr_;

      deleter_ = rhs.deleter_;

      rhs.counter_ptr_ = nullptr;
      rhs.ptr_ = nullptr;
    }
    // else do nothing

    return *this;
  }

  bool operator<(light_ptr const& rhs) const noexcept
  {
    return get() < rhs.get();
  }

  bool operator==(light_ptr const& rhs) const noexcept
  {
    return counter_ptr_ == rhs.counter_ptr_;
  }

  bool operator!=(light_ptr const& rhs) const noexcept
  {
    return !operator==(rhs);
  }

  bool operator==(::std::nullptr_t const) const noexcept
  {
    return !ptr_;
  }

  bool operator!=(::std::nullptr_t const) const noexcept
  {
    return ptr_;
  }

  explicit operator bool() const noexcept { return ptr_; }

  typename ::detail::ref_type<T>::type
  operator*() const noexcept
  {
    return *static_cast<T*>(static_cast<void*>(ptr_));
  }

  T* operator->() const noexcept
  {
    return static_cast<T*>(static_cast<void*>(ptr_));
  }

  element_type* get() const noexcept { return ptr_; }

  void reset() { reset(nullptr); }

  void reset(::std::nullptr_t const)
  {
    ::detail::dec_ref(counter_ptr_, ptr_, deleter_);

    counter_ptr_ = nullptr;
    ptr_ = nullptr;
  }

  template <typename U>
  void reset(U* const p, deleter_type const d = default_deleter<U>)
  {
    ::detail::dec_ref(counter_ptr_, ptr_, deleter_);

    counter_ptr_ = new ::detail::atomic_type(::detail::counter_type(1));
    ptr_ = p;

    deleter_ = d;
  }

  void swap(light_ptr& other) noexcept
  {
    ::std::swap(counter_ptr_, other.counter_ptr_);
    ::std::swap(ptr_, other.ptr_);
    ::std::swap(deleter_, other.deleter_);
  }

  bool unique() const noexcept
  {
    return ::detail::counter_type(1) == use_count();
  }

  ::detail::counter_type use_count() const noexcept
  {
    return counter_ptr_ ?
      counter_ptr_->load(::std::memory_order_relaxed) :
      ::detail::counter_type{};
  }

  template <typename U>
  static void default_deleter(element_type* const p)
  {
    ::std::default_delete<typename deletion_type<T, U>::type>()(
      static_cast<U*>(p));
  }

private:
  ::detail::atomic_type* counter_ptr_{};

  element_type* ptr_{};

  deleter_type deleter_;
};

template<class T, class ...Args>
inline light_ptr<T> make_light(Args&& ...args)
{
  return light_ptr<T>(new T(::std::forward<Args>(args)...));
}

namespace std
{
  template <typename T>
  struct hash<light_ptr<T> >
  {
    size_t operator()(light_ptr<T> const& l) const noexcept
    {
      return hash<typename light_ptr<T>::element_type*>(l.get());
    }
  };
}

#endif // LIGHTPTR_HPP
<commit_msg>strips<commit_after>#pragma once
#ifndef LIGHTPTR_HPP
# define LIGHTPTR_HPP

#include <cassert>

#include <atomic>

#include <memory>

#include <utility>

#include <type_traits>

namespace detail
{
  using counter_type = ::std::size_t;

  using atomic_type = ::std::atomic<counter_type>;

  template <typename T>
  using deleter_type = void (*)(T*);

  template <typename U>
  struct ref_type
  {
    using type = U&;
  };

  template <>
  struct ref_type<void>
  {
    using type = void;
  };

  template <typename T>
  inline void dec_ref(atomic_type* const counter_ptr,
    T* const ptr, deleter_type<T> const deleter)
  {
    if (counter_ptr && (counter_type(1) ==
      counter_ptr->fetch_sub(counter_type(1), ::std::memory_order_relaxed)))
    {
      delete counter_ptr;

      deleter(ptr);
    }
    // else do nothing
  }

  inline void inc_ref(atomic_type* const counter_ptr)
  {
    assert(counter_ptr);
    counter_ptr->fetch_add(counter_type(1), ::std::memory_order_relaxed);
  }
}

template <typename T>
struct light_ptr
{
  template <typename U, typename V>
  struct deletion_type
  {
    using type = V;
  };

  template <typename U, typename V>
  struct deletion_type<U[], V>
  {
    using type = V[];
  };

  template <typename U, typename V, ::std::size_t N>
  struct deletion_type<U[N], V>
  {
    using type = V[];
  };

  template <typename U>
  struct remove_array
  {
    using type = U;
  };

  template <typename U>
  struct remove_array<U[]>
  {
    using type = U;
  };

  template <typename U, ::std::size_t N>
  struct remove_array<U[N]>
  {
    using type = U;
  };

  using element_type = typename remove_array<T>::type;

  using deleter_type = ::detail::deleter_type<element_type>;

  light_ptr() = default;

  template <typename U>
  explicit light_ptr(U* const p, deleter_type const d = default_deleter<U>)
  {
    reset(p, d);
  }

  ~light_ptr() { ::detail::dec_ref(counter_ptr_, ptr_, deleter_); }

  light_ptr(light_ptr const& other) { *this = other; }

  light_ptr(light_ptr&& other) noexcept { *this = ::std::move(other); }

  light_ptr& operator=(light_ptr const& rhs)
  {
    if (*this != rhs)
    {
      ::detail::dec_ref(counter_ptr_, ptr_, deleter_);

      counter_ptr_ = rhs.counter_ptr_;
      ptr_ = rhs.ptr_;

      deleter_ = rhs.deleter_;

      ::detail::inc_ref(counter_ptr_);
    }
    // else do nothing

    return *this;
  }

  light_ptr& operator=(light_ptr&& rhs) noexcept
  {
    if (*this != rhs)
    {
      counter_ptr_ = rhs.counter_ptr_;
      ptr_ = rhs.ptr_;

      deleter_ = rhs.deleter_;

      rhs.counter_ptr_ = nullptr;
      rhs.ptr_ = nullptr;
    }
    // else do nothing

    return *this;
  }

  bool operator<(light_ptr const& rhs) const noexcept
  {
    return get() < rhs.get();
  }

  bool operator==(light_ptr const& rhs) const noexcept
  {
    return counter_ptr_ == rhs.counter_ptr_;
  }

  bool operator!=(light_ptr const& rhs) const noexcept
  {
    return !operator==(rhs);
  }

  bool operator==(::std::nullptr_t const) const noexcept
  {
    return !ptr_;
  }

  bool operator!=(::std::nullptr_t const) const noexcept
  {
    return ptr_;
  }

  explicit operator bool() const noexcept { return ptr_; }

  typename ::detail::ref_type<T>::type
  operator*() const noexcept
  {
    return *static_cast<T*>(static_cast<void*>(ptr_));
  }

  T* operator->() const noexcept
  {
    return static_cast<T*>(static_cast<void*>(ptr_));
  }

  element_type* get() const noexcept { return ptr_; }

  void reset() { reset(nullptr); }

  void reset(::std::nullptr_t const)
  {
    ::detail::dec_ref(counter_ptr_, ptr_, deleter_);

    counter_ptr_ = nullptr;
    ptr_ = nullptr;
  }

  template <typename U>
  void reset(U* const p, deleter_type const d = default_deleter<U>)
  {
    ::detail::dec_ref(counter_ptr_, ptr_, deleter_);

    counter_ptr_ = new ::detail::atomic_type(::detail::counter_type(1));
    ptr_ = p;

    deleter_ = d;
  }

  void swap(light_ptr& other) noexcept
  {
    ::std::swap(counter_ptr_, other.counter_ptr_);
    ::std::swap(ptr_, other.ptr_);
    ::std::swap(deleter_, other.deleter_);
  }

  bool unique() const noexcept
  {
    return ::detail::counter_type(1) == use_count();
  }

  ::detail::counter_type use_count() const noexcept
  {
    return counter_ptr_ ?
      counter_ptr_->load(::std::memory_order_relaxed) :
      ::detail::counter_type{};
  }

  template <typename U>
  static void default_deleter(element_type* const p)
  {
    ::std::default_delete<typename deletion_type<T, U>::type>()(
      static_cast<U*>(p));
  }

private:
  ::detail::atomic_type* counter_ptr_{};

  element_type* ptr_{};

  deleter_type deleter_;
};

template<class T, class ...Args>
inline light_ptr<T> make_light(Args&& ...args)
{
  return light_ptr<T>(new T(::std::forward<Args>(args)...));
}

namespace std
{
  template <typename T>
  struct hash<light_ptr<T> >
  {
    size_t operator()(light_ptr<T> const& l) const noexcept
    {
      return hash<typename light_ptr<T>::element_type*>(l.get());
    }
  };
}

#endif // LIGHTPTR_HPP
<|endoftext|>


<commit_before>#pragma once
#ifndef LIGHTPTR_HPP
# define LIGHTPTR_HPP

#include <cassert>

#include <atomic>

#include <memory>

#include <utility>

#include <type_traits>

namespace generic
{

namespace detail
{
  using counter_type = unsigned;

  using atomic_type = ::std::atomic<counter_type>;

  template <typename T>
  using deleter_type = void (*)(T*);

  template <typename U>
  struct ref_type
  {
    using type = U&;
  };

  template <>
  struct ref_type<void>
  {
    using type = void;
  };
}

template <typename T>
struct light_ptr
{
  template <typename U, typename V>
  struct deletion_type
  {
    using type = V;
  };

  template <typename U, typename V>
  struct deletion_type<U[], V>
  {
    using type = V[];
  };

  template <typename U, typename V, ::std::size_t N>
  struct deletion_type<U[N], V>
  {
    using type = V[];
  };

  template <typename U>
  struct remove_array
  {
    using type = U;
  };

  template <typename U>
  struct remove_array<U[]>
  {
    using type = U;
  };

  template <typename U, ::std::size_t N>
  struct remove_array<U[N]>
  {
    using type = U;
  };

  using element_type = typename remove_array<T>::type;

  using deleter_type = detail::deleter_type<element_type>;

  struct counter
  {
    counter(detail::counter_type const c, deleter_type const d) noexcept :
      deleter_(d)
    {
      counter_.store(c, ::std::memory_order_relaxed);
    }

    template <typename U>
    typename ::std::enable_if<!::std::is_void<U>{}>::type
    dec_ref(U* const ptr)
    {
      if (detail::counter_type(1) ==
        counter_.fetch_sub(detail::counter_type(1),
          ::std::memory_order_relaxed))
      {
        typedef char type_must_be_complete[sizeof(U) ? 1 : -1];
        (void)sizeof(type_must_be_complete);
        deleter_(ptr);

        delete this;
      }
      // else do nothing
    }

    template <typename U>
    typename ::std::enable_if<::std::is_void<U>{}>::type
    dec_ref(U* const ptr)
    {
      if (detail::counter_type(1) ==
        counter_.fetch_sub(detail::counter_type(1),
          ::std::memory_order_relaxed))
      {
        deleter_(ptr);

        delete this;
      }
      // else do nothing
    }

    void inc_ref() noexcept
    {
      //assert(counter_ptr);
      counter_.fetch_add(detail::counter_type(1),
        ::std::memory_order_relaxed);
    }

    detail::atomic_type counter_{};

    deleter_type deleter_;
  };

  light_ptr() = default;

  template <typename U>
  explicit light_ptr(U* const p, deleter_type const d = default_deleter<U>)
  {
    reset(p, d);
  }

  ~light_ptr()
  {
    counter_ && (counter_->dec_ref(ptr_), true);
  }

  light_ptr(light_ptr const& other) { *this = other; }

  light_ptr(light_ptr&& other) noexcept { *this = ::std::move(other); }

  light_ptr& operator=(light_ptr const& rhs)
  {
    if (*this != rhs)
    {
      if (counter_)
      {
        counter_->dec_ref(ptr_);
      }
      // else do nothing

      counter_ = rhs.counter_;
      ptr_ = rhs.ptr_;

      if (counter_)
      {
        counter_->inc_ref();
      }
      // else do nothing
    }
    // else do nothing

    return *this;
  }

  light_ptr& operator=(light_ptr&& rhs) noexcept
  {
    if (*this != rhs)
    {
      counter_ = rhs.counter_;
      ptr_ = rhs.ptr_;

      rhs.counter_ = nullptr;
      rhs.ptr_ = nullptr;
    }
    // else do nothing

    return *this;
  }

  light_ptr& operator=(::std::nullptr_t const) noexcept { reset(); }

  bool operator<(light_ptr const& rhs) const noexcept
  {
    return get() < rhs.get();
  }

  bool operator==(light_ptr const& rhs) const noexcept
  {
    return counter_ == rhs.counter_;
  }

  bool operator!=(light_ptr const& rhs) const noexcept
  {
    return !operator==(rhs);
  }

  bool operator==(::std::nullptr_t const) const noexcept
  {
    return !ptr_;
  }

  bool operator!=(::std::nullptr_t const) const noexcept
  {
    return ptr_;
  }

  explicit operator bool() const noexcept { return ptr_; }

  typename detail::ref_type<T>::type
  operator*() const noexcept
  {
    return *static_cast<T*>(static_cast<void*>(ptr_));
  }

  T* operator->() const noexcept
  {
    return static_cast<T*>(static_cast<void*>(ptr_));
  }

  element_type* get() const noexcept { return ptr_; }

  void reset() { reset(nullptr); }

  void reset(::std::nullptr_t const)
  {
    if (counter_)
    {
      counter_->dec_ref(ptr_);

      counter_ = {};
    }
    // else do nothing

    ptr_ = {};
  }

  template <typename U>
  void reset(U* const p, deleter_type const d = default_deleter<U>)
  {
    if (counter_)
    {
      counter_->dec_ref(ptr_);
    }
    // else do nothing

    counter_ = new counter(detail::counter_type(1), d);

    ptr_ = p;
  }

  void swap(light_ptr& other) noexcept
  {
    ::std::swap(counter_, other.counter_);
    ::std::swap(ptr_, other.ptr_);
  }

  bool unique() const noexcept
  {
    return detail::counter_type(1) == use_count();
  }

  detail::counter_type use_count() const noexcept
  {
    return counter_ ?
      counter_->counter_ptr_->load(::std::memory_order_relaxed) :
      detail::counter_type{};
  }

  template <typename U>
  static void default_deleter(element_type* const p)
  {
    ::std::default_delete<typename deletion_type<T, U>::type>()(
      static_cast<U*>(p));
  }

private:
  counter* counter_{};

  element_type* ptr_{};
};

template<class T, class ...Args>
inline light_ptr<T> make_light(Args&& ...args)
{
  return light_ptr<T>(new T(::std::forward<Args>(args)...));
}

}

namespace std
{
  template <typename T>
  struct hash<::generic::light_ptr<T> >
  {
    size_t operator()(::generic::light_ptr<T> const& l) const noexcept
    {
      return hash<typename ::generic::light_ptr<T>::element_type*>()(l.get());
    }
  };
}

#endif // LIGHTPTR_HPP
<commit_msg>some fixes<commit_after>#pragma once
#ifndef LIGHTPTR_HPP
# define LIGHTPTR_HPP

#include <cassert>

#include <atomic>

#include <memory>

#include <utility>

#include <type_traits>

namespace generic
{

namespace detail
{
  using counter_type = unsigned;

  using atomic_type = ::std::atomic<counter_type>;

  template <typename T>
  using deleter_type = void (*)(T*);

  template <typename U>
  struct ref_type
  {
    using type = U&;
  };

  template <>
  struct ref_type<void>
  {
    using type = void;
  };
}

template <typename T>
struct light_ptr
{
  template <typename U, typename V>
  struct deletion_type
  {
    using type = V;
  };

  template <typename U, typename V>
  struct deletion_type<U[], V>
  {
    using type = V[];
  };

  template <typename U, typename V, ::std::size_t N>
  struct deletion_type<U[N], V>
  {
    using type = V[];
  };

  template <typename U>
  struct remove_array
  {
    using type = U;
  };

  template <typename U>
  struct remove_array<U[]>
  {
    using type = U;
  };

  template <typename U, ::std::size_t N>
  struct remove_array<U[N]>
  {
    using type = U;
  };

  using element_type = typename remove_array<T>::type;

  using deleter_type = detail::deleter_type<element_type>;

  struct counter
  {
    counter(detail::counter_type const c, deleter_type const d) noexcept :
      deleter_(d)
    {
      counter_.store(c, ::std::memory_order_relaxed);
    }

    template <typename U>
    typename ::std::enable_if<!::std::is_void<U>{}>::type
    dec_ref(U* const ptr)
    {
      if (detail::counter_type(1) ==
        counter_.fetch_sub(detail::counter_type(1),
          ::std::memory_order_relaxed))
      {
        typedef char type_must_be_complete[sizeof(U) ? 1 : -1];
        (void)sizeof(type_must_be_complete);
        deleter_(ptr);

        delete this;
      }
      // else do nothing
    }

    template <typename U>
    typename ::std::enable_if<::std::is_void<U>{}>::type
    dec_ref(U* const ptr)
    {
      if (detail::counter_type(1) ==
        counter_.fetch_sub(detail::counter_type(1),
          ::std::memory_order_relaxed))
      {
        deleter_(ptr);

        delete this;
      }
      // else do nothing
    }

    void inc_ref() noexcept
    {
      //assert(counter_ptr);
      counter_.fetch_add(detail::counter_type(1),
        ::std::memory_order_relaxed);
    }

    detail::atomic_type counter_{};

    deleter_type deleter_;
  };

  light_ptr() = default;

  template <typename U>
  explicit light_ptr(U* const p, deleter_type const d = default_deleter<U>)
  {
    reset(p, d);
  }

  ~light_ptr()
  {
    counter_ && (counter_->dec_ref(ptr_), true);
  }

  light_ptr(light_ptr const& other) { *this = other; }

  light_ptr(light_ptr&& other) noexcept { *this = ::std::move(other); }

  light_ptr& operator=(light_ptr const& rhs)
  {
    if (*this != rhs)
    {
      if (counter_)
      {
        counter_->dec_ref(ptr_);
      }
      // else do nothing

      counter_ = rhs.counter_;
      ptr_ = rhs.ptr_;

      if (counter_)
      {
        counter_->inc_ref();
      }
      // else do nothing
    }
    // else do nothing

    return *this;
  }

  light_ptr& operator=(light_ptr&& rhs) noexcept
  {
    counter_ = rhs.counter_;
    ptr_ = rhs.ptr_;

    rhs.counter_ = nullptr;
    rhs.ptr_ = nullptr;

    return *this;
  }

  light_ptr& operator=(::std::nullptr_t const) noexcept { reset(); }

  bool operator<(light_ptr const& rhs) const noexcept
  {
    return get() < rhs.get();
  }

  bool operator==(light_ptr const& rhs) const noexcept
  {
    return counter_ == rhs.counter_;
  }

  bool operator!=(light_ptr const& rhs) const noexcept
  {
    return !operator==(rhs);
  }

  bool operator==(::std::nullptr_t const) const noexcept
  {
    return !ptr_;
  }

  bool operator!=(::std::nullptr_t const) const noexcept
  {
    return ptr_;
  }

  explicit operator bool() const noexcept { return ptr_; }

  typename detail::ref_type<T>::type
  operator*() const noexcept
  {
    return *static_cast<T*>(static_cast<void*>(ptr_));
  }

  T* operator->() const noexcept
  {
    return static_cast<T*>(static_cast<void*>(ptr_));
  }

  element_type* get() const noexcept { return ptr_; }

  void reset() { reset(nullptr); }

  void reset(::std::nullptr_t const)
  {
    if (counter_)
    {
      counter_->dec_ref(ptr_);

      counter_ = {};
    }
    // else do nothing

    ptr_ = {};
  }

  template <typename U>
  void reset(U* const p, deleter_type const d = default_deleter<U>)
  {
    if (counter_)
    {
      counter_->dec_ref(ptr_);
    }
    // else do nothing

    counter_ = new counter(detail::counter_type(1), d);

    ptr_ = p;
  }

  void swap(light_ptr& other) noexcept
  {
    ::std::swap(counter_, other.counter_);
    ::std::swap(ptr_, other.ptr_);
  }

  bool unique() const noexcept
  {
    return detail::counter_type(1) == use_count();
  }

  detail::counter_type use_count() const noexcept
  {
    return counter_ ?
      counter_->counter_ptr_->load(::std::memory_order_relaxed) :
      detail::counter_type{};
  }

  template <typename U>
  static void default_deleter(element_type* const p)
  {
    ::std::default_delete<typename deletion_type<T, U>::type>()(
      static_cast<U*>(p));
  }

private:
  counter* counter_{};

  element_type* ptr_{};
};

template<class T, class ...Args>
inline light_ptr<T> make_light(Args&& ...args)
{
  return light_ptr<T>(new T(::std::forward<Args>(args)...));
}

}

namespace std
{
  template <typename T>
  struct hash<::generic::light_ptr<T> >
  {
    size_t operator()(::generic::light_ptr<T> const& l) const noexcept
    {
      return hash<typename ::generic::light_ptr<T>::element_type*>()(l.get());
    }
  };
}

#endif // LIGHTPTR_HPP
<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include "hw2.h"

int main( int argc , char **argv )
{
    testing :: InitGoogleTest( &argc , argv ) ;
    return RUN_ALL_TESTS( ) ;
}
<commit_msg>Delete mainTerm.cpp<commit_after><|endoftext|>


<commit_before>//================================================================================================================================

void AliMuonForwardTrackFinder(Int_t run=0,
			       Int_t matching=0,
			       const Char_t *readDir= ".",
			       const Char_t *outDir = ".",
			       Int_t nEventsToAnalyze = -1) {

  //  TGeoGlobalMagField::Instance()->SetField(new AliMagF("Maps","Maps", -1., -1, AliMagF::k5kG));

  // AliLog::SetClassDebugLevel("AliMuonForwardTrackFinder", 1);

  AliCDBManager* man = AliCDBManager::Instance();
  man->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
  man->SetSpecificStorage("GRP/GRP/Data", Form("local://%s",gSystem->pwd()));

  AliMuonForwardTrackFinder *finder = new AliMuonForwardTrackFinder();
  finder->SetDraw(kFALSE);
  finder->Init(run, readDir, outDir, nEventsToAnalyze);

  finder -> SetSigmaSpectrometerCut(4.0);
  finder -> SetSigmaClusterCut(4.0);
  finder -> SetChi2GlobalCut(2.0);
  finder -> SetRAbsorberCut(0.0);
  //  finder -> SetRAbsorberCut(26.4);
  finder -> SetLowPtCut(0.0);
  //  finder -> SetLowPtCut(0.5);
  finder -> SetExtrapOriginTransvError(0.05);   // To be imposed if the gen. vertex is fixed in (0,0,0)
  finder -> SetGaussianBlurZVert(5.0);          // To be imposed if the gen. vertex is fixed in (0,0,0)
  finder -> SetMatchingMode(matching);          // 0 -> real matching   1 -> ideal matching
  finder -> SetMinResearchRadiusAtLastPlane(0.5);

  while (finder->LoadNextTrack()) continue;

  if (finder->GetNRealTracksAnalyzed()) finder->Terminate();

}

//================================================================================================================================

<commit_msg>Support files added<commit_after>//================================================================================================================================

void AliMuonForwardTrackFinder(Int_t run=0,
			       Int_t matching=0,
			       const Char_t *readDir= ".",
			       const Char_t *outDir = ".",
			       Int_t nEventsToAnalyze = -1) {

  //  TGeoGlobalMagField::Instance()->SetField(new AliMagF("Maps","Maps", -1., -1, AliMagF::k5kG));

  // AliLog::SetClassDebugLevel("AliMuonForwardTrackFinder", 1);

  AliCDBManager* man = AliCDBManager::Instance();
  man->SetDefaultStorage("local://$ALICE_ROOT/OCDB");
  man->SetSpecificStorage("GRP/GRP/Data", Form("local://%s",gSystem->pwd()));

  AliMuonForwardTrackFinder *finder = new AliMuonForwardTrackFinder();
  finder->SetDraw(kFALSE);
  finder->Init(run, readDir, outDir, nEventsToAnalyze);

  finder -> SetSigmaSpectrometerCut(4.0);
  finder -> SetSigmaClusterCut(4.0);
  finder -> SetChi2GlobalCut(2.0);
  finder -> SetRAbsorberCut(0.0);
  //  finder -> SetRAbsorberCut(26.4);
  finder -> SetLowPtCut(0.0);
  //  finder -> SetLowPtCut(0.5);
  finder -> SetVertexError(0.015, 0.015, 0.010);
  finder -> SetMatchingMode(matching);                // 0 -> real matching   1 -> ideal matching
  finder -> SetMinResearchRadiusAtLastPlane(0.0);

  while (finder->LoadNextTrack()) continue;

  if (finder->GetNRealTracksAnalyzed()) finder->Terminate();

}

//================================================================================================================================

<|endoftext|>


<commit_before>#include "server_functions.h"
#include <stdio.h>
#include <string.h>
#include <rpc.h>

#include <iostream>
#include <sstream>

#include <netinet/in.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <vector>
#include <algorithm>

#include <netdb.h>
#include <stdlib.h>

#include <register_success_message.h>
#include <register_failure_message.h>
#include <register_request_message.h>
#include <execute_success_message.h>
#include <execute_failure_message.h>
#include <execute_request_message.h>

using namespace std;

static map<procedure_signature, skeleton> proc_skele_dict;
string serverIdentifier;
unsigned int port;
int binder_sock;

	//TODO:
  // CREATE SERVER
  // CONNECT TO BINDER

struct thread_data {
  int sock;
  vector<string> *buf;
};

void *SendToServer(void *threadarg) {
  struct thread_data *my_data;
  my_data = (struct thread_data *) threadarg;

  vector<string> *dataQueue = my_data->buf;

  while (true) {
    if ((*dataQueue).size() > 0) {
      string data = (*dataQueue)[0];
      (*dataQueue).erase((*dataQueue).begin());

      // send data to server
      int len = data.length() + 1;
      send(my_data->sock, &len, sizeof(len), 0);
      send(my_data->sock, data.c_str(), len, 0);

      // block on receive
      string titleCasedData;
      recv(my_data->sock, &len, sizeof(len), 0);

      char *msg = new char[len];
      recv(my_data->sock, msg, len, 0);

      //Printing the response from the server:
      cout << "Server: " << msg << endl;

      sleep(2);
    }
  }

  pthread_exit(NULL);
}

void connect_to_binder() {
  char *serverAddress = getenv("BINDER_ADDRESS");
  char *port = getenv("BINDER_PORT");

  if (serverAddress == NULL || port == NULL) {
    cerr << "Missing SERVER_ADDRESS or SERVER_PORT environment variable" << endl;
    cerr << *port << endl;
    cerr << *serverAddress << endl;
    exit(1);
  }

  string data;
  vector<string> buffer;

  int sockfd, portno;
  struct sockaddr_in serv_addr;
  struct hostent *server;
  portno = atoi(port);
  sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  server = gethostbyname(serverAddress);

  bzero((char *) &serv_addr, sizeof(serv_addr));

  serv_addr.sin_family = AF_INET;

  bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);

  serv_addr.sin_port = htons(portno);

  connect(sockfd,(struct sockaddr *)&serv_addr, sizeof(serv_addr));

  struct thread_data td;
  td.sock = sockfd;
  td.buf = &buffer;

  pthread_t thread;

  int val = pthread_create(&thread, NULL, SendToServer, (void *)&td);

  binder_sock = sockfd;
}

int rpcRegister(char * name, int *argTypes, skeleton f){

  connect_to_binder();
  int status = RegisterRequestMessage request_message = new RegisterRequestMessage(serverIdentifier, port, name, argTypes);
  success_message.send(sock);
  int retStatus;

  if(status == 0){
    //Success
    Message message;
    Message::receive(binder_sock, message, retStatus);

    if(message.type == 2){
      struct procedure_signature k(string(name), argTypes);
      proc_skele_dict[k] = f;
    }else if(message.type ==3){

    }

  }else if( status > 0){
    //Warning

  }else if( status < 0){
    //Error
    return status;
  }

}

int rpcInit(void){
  //Create connection socket ot be used for accepting clients

  vector<int> myConnections;
  vector<int> myToRemove;

  int status;
  struct addrinfo hints;
  struct addrinfo* servinfo;
  struct addrinfo* p;

  memset(&hints, 0, sizeof hints);
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags = AI_PASSIVE;

  status = getaddrinfo(NULL, "0", &hints, &servinfo);

  if (status != 0) {
    fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
    return 0;
  }

  p = servinfo;
  int sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol);

  status = bind(sock, servinfo->ai_addr, servinfo->ai_addrlen);
  status = listen(sock, 5);

  char hostname[256];
  gethostname(hostname, 256);

  struct sockaddr_in sin;
  socklen_t len = sizeof(sin);

  getsockname(sock, (struct sockaddr *)&sin, &len);

  stringstream ss;
  ss << ntohs(sin.sin_port);
  string ps = ss.str();

  serverIdentifier = hostname;
  port =  ntohs(sin.sin_port);

  fd_set readfds;
  int n;
  struct sockaddr_storage their_addr;

  while(true){
    //CONNECTIONS VECTOR
    FD_ZERO(&readfds);
    FD_SET(sock, &readfds);

    n = sock;

    for (vector<int>::iterator it = myConnections.begin();it != myConnections.end(); ++it) {
      int connection = *it;
      FD_SET(connection, &readfds);
       if (connection > n){
        n = connection;
      }
    }

    n = n+1;

    status = select(n, &readfds, NULL, NULL, NULL);

    if (status == -1) {
      cerr << "ERROR: select failed." << endl;
    } else {

      if (FD_ISSET(sock, &readfds)) {
        socklen_t addr_size = sizeof their_addr;
        int new_sock = accept(sock, (struct sockaddr*)&their_addr, &addr_size);

        if (new_sock < 0) {
          cerr << "ERROR: while accepting connection" << endl;
          close(new_sock);
          continue;
        }

        myConnections.push_back(new_sock);

      } else {

        for (vector<int>::iterator it = myConnections.begin(); it != myConnections.end(); ++it) {
          int tempConnection = *it;
          if (FD_ISSET(tempConnection, &readfds)) {

            Message message;
            Message::receive(sock, message, status);

            if (status < 0) {
                RegisterFailureMessage failure_message = new RegisterFailureMessage(status);
                failure_message.send(sock);

                return errorMsg;
            }

            if (status == 0) {
              // client has closed the connection
              myToRemove.push_back(sock);
              return errorMsg;
            }

            request_handler(message, sock);
          }
        }
      }

      for (vector<int>::iterator it = myToRemove.begin(); it != myToRemove.end(); ++it) {
        myConnections.erase(remove(myConnections.begin(), myConnections.end(), *it), myConnections.end());
        close(*it);
      }
      myToRemove.clear();
    }
  }

  freeaddrinfo(servinfo);
}<commit_msg>changes to rpcServer<commit_after>#include "server_functions.h"
#include <stdio.h>
#include <string.h>
#include <rpc.h>

#include <iostream>
#include <sstream>

#include <netinet/in.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <vector>
#include <algorithm>

#include <netdb.h>
#include <stdlib.h>

#include <register_success_message.h>
#include <register_failure_message.h>
#include <register_request_message.h>
#include <execute_success_message.h>
#include <execute_failure_message.h>
#include <execute_request_message.h>

using namespace std;

static map<procedure_signature, skeleton> proc_skele_dict;
string serverIdentifier;
unsigned int port;
int binder_sock;
int sock;

	//TODO:
  // CREATE SERVER
  // CONNECT TO BINDER

struct thread_data {
  int sock;
  vector<string> *buf;
};

void *SendToServer(void *threadarg) {
  struct thread_data *my_data;
  my_data = (struct thread_data *) threadarg;

  vector<string> *dataQueue = my_data->buf;

  while (true) {
    if ((*dataQueue).size() > 0) {
      string data = (*dataQueue)[0];
      (*dataQueue).erase((*dataQueue).begin());

      // send data to server
      int len = data.length() + 1;
      send(my_data->sock, &len, sizeof(len), 0);
      send(my_data->sock, data.c_str(), len, 0);

      // block on receive
      string titleCasedData;
      recv(my_data->sock, &len, sizeof(len), 0);

      char *msg = new char[len];
      recv(my_data->sock, msg, len, 0);

      //Printing the response from the server:
      cout << "Server: " << msg << endl;

      sleep(2);
    }
  }

  pthread_exit(NULL);
}

void connect_to_binder() {
  char *serverAddress = getenv("BINDER_ADDRESS");
  char *port = getenv("BINDER_PORT");

  if (serverAddress == NULL || port == NULL) {
    cerr << "Missing SERVER_ADDRESS or SERVER_PORT environment variable" << endl;
    cerr << *port << endl;
    cerr << *serverAddress << endl;
    exit(1);
  }

  string data;
  vector<string> buffer;

  int sockfd, portno;
  struct sockaddr_in serv_addr;
  struct hostent *server;
  portno = atoi(port);
  sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  server = gethostbyname(serverAddress);

  bzero((char *) &serv_addr, sizeof(serv_addr));

  serv_addr.sin_family = AF_INET;

  bcopy((char *)server->h_addr, (char *)&serv_addr.sin_addr.s_addr, server->h_length);

  serv_addr.sin_port = htons(portno);

  connect(sockfd,(struct sockaddr *)&serv_addr, sizeof(serv_addr));

  struct thread_data td;
  td.sock = sockfd;
  td.buf = &buffer;

  pthread_t thread;

  int val = pthread_create(&thread, NULL, SendToServer, (void *)&td);

  binder_sock = sockfd;
}

int rpcRegister(char * name, int *argTypes, skeleton f){

  connect_to_binder();
  int status = RegisterRequestMessage request_message = new RegisterRequestMessage(serverIdentifier, port, name, argTypes);
  success_message.send(sock);
  int retStatus;

  if(status == 0){
    //Success
    Message message;
    Message::receive(binder_sock, message, retStatus);

    if(message.type == 2){
      struct procedure_signature k(string(name), argTypes);
      proc_skele_dict[k] = f;
    }else if(message.type ==3){

    }

  }else if( status > 0){
    //Warning

  }else if( status < 0){
    //Error
    return status;
  }

}

int rpcExecute(void){
  //Create connection socket ot be used for accepting clients
  vector<int> myConnections;
  vector<int> myToRemove;

  fd_set readfds;
  int n;
  int status;
  struct sockaddr_storage their_addr;

  while(true){
    //CONNECTIONS VECTOR
    FD_ZERO(&readfds);
    FD_SET(sock, &readfds);

    n = sock;

    for (vector<int>::iterator it = myConnections.begin();it != myConnections.end(); ++it) {
      int connection = *it;
      FD_SET(connection, &readfds);
       if (connection > n){
        n = connection;
      }
    }

    n = n+1;

    status = select(n, &readfds, NULL, NULL, NULL);

    if (status == -1) {
      cerr << "ERROR: select failed." << endl;
    } else {

      if (FD_ISSET(sock, &readfds)) {
        socklen_t addr_size = sizeof their_addr;
        int new_sock = accept(sock, (struct sockaddr*)&their_addr, &addr_size);

        if (new_sock < 0) {
          cerr << "ERROR: while accepting connection" << endl;
          close(new_sock);
          continue;
        }

        myConnections.push_back(new_sock);

      } else {

        for (vector<int>::iterator it = myConnections.begin(); it != myConnections.end(); ++it) {
          int tempConnection = *it;
          if (FD_ISSET(tempConnection, &readfds)) {

            Message message;
            Message::receive(sock, message, status);

            if (status < 0) {
                RegisterFailureMessage failure_message = new RegisterFailureMessage(status);
                failure_message.send(sock);

                return errorMsg;
            }

            if (status == 0) {
              // client has closed the connection
              myToRemove.push_back(sock);
              return errorMsg;
            }

            request_handler(message, sock);
          }
        }
      }

      for (vector<int>::iterator it = myToRemove.begin(); it != myToRemove.end(); ++it) {
        myConnections.erase(remove(myConnections.begin(), myConnections.end(), *it), myConnections.end());
        close(*it);
      }
      myToRemove.clear();
    }
  }

  freeaddrinfo(servinfo);
}

int rpcInit(void){
  int status;
  struct addrinfo hints;
  struct addrinfo* servinfo;
  struct addrinfo* p;

  memset(&hints, 0, sizeof hints);
  hints.ai_family = AF_UNSPEC;
  hints.ai_socktype = SOCK_STREAM;
  hints.ai_flags = AI_PASSIVE;

  status = getaddrinfo(NULL, "0", &hints, &servinfo);

  if (status != 0) {
    fprintf(stderr, "getaddrinfo error: %s\n", gai_strerror(status));
    return 0;
  }

  p = servinfo;
  sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol);

  status = bind(sock, servinfo->ai_addr, servinfo->ai_addrlen);
  status = listen(sock, 5);

  char hostname[256];
  gethostname(hostname, 256);

  struct sockaddr_in sin;
  socklen_t len = sizeof(sin);

  getsockname(sock, (struct sockaddr *)&sin, &len);

  stringstream ss;
  ss << ntohs(sin.sin_port);
  string ps = ss.str();

  serverIdentifier = hostname;
  port =  ntohs(sin.sin_port);

}<|endoftext|>


<commit_before>
#include "mathematica/integrator_plots.hpp"

#include <fstream>  // NOLINT(readability/streams)
#include <iostream>  // NOLINT(readability/streams)
#include <string>
#include <vector>

#include "glog/logging.h"
#include "integrators/symplectic_partitioned_runge_kutta_integrator.hpp"
#include "quantities/quantities.hpp"
#include "quantities/named_quantities.hpp"
#include "mathematica/mathematica.hpp"
#include "testing_utilities/numerical_analysis.hpp"
#include "testing_utilities/numerics.hpp"

#define INTEGRATOR(name) &integrators::name(), #name

namespace principia {

using base::not_null;
using integrators::SRKNIntegrator;
using quantities::AngularFrequency;
using quantities::Cos;
using quantities::Energy;
using quantities::Length;
using quantities::Pow;
using quantities::Sin;
using quantities::Speed;
using si::Joule;
using si::Kilogram;
using si::Metre;
using si::Radian;
using si::Second;
using testing_utilities::AbsoluteError;
using testing_utilities::ComputeHarmonicOscillatorAcceleration;

namespace mathematica {

namespace {

struct SimpleHarmonicMotionPlottedIntegrator {
  not_null<SRKNIntegrator const*> integrator;
  std::string name;
  int stages;
};

std::vector<SimpleHarmonicMotionPlottedIntegrator> Methods() {
  return {
      {INTEGRATOR(Leapfrog), 1},
      {INTEGRATOR(PseudoLeapfrog), 1},
      {INTEGRATOR(McLachlanAtela1992Order2Optimal), 2},
      {INTEGRATOR(McLachlan1995S2), 2},
      {INTEGRATOR(Ruth1983), 3},
      {INTEGRATOR(McLachlanAtela1992Order3Optimal), 3},
      {INTEGRATOR(CandyRozmus1991ForestRuth1990SynchronousMomenta), 3},
      {INTEGRATOR(CandyRozmus1991ForestRuth1990SynchronousPositions), 3},
      {INTEGRATOR(Suzuki1990), 5},
      {INTEGRATOR(McLachlan1995SS5), 5},
      {INTEGRATOR(McLachlan1995S4), 4},
      {INTEGRATOR(McLachlan1995S5), 5},
      {INTEGRATOR(McLachlanAtela1992Order4Optimal), 4},
      {INTEGRATOR(McLachlan1995SB3A4), 4},
      {INTEGRATOR(McLachlan1995SB3A5), 5},
      {INTEGRATOR(McLachlanAtela1992Order5Optimal), 6},
      {INTEGRATOR(Yoshida1990Order6A), 7},
      {INTEGRATOR(Yoshida1990Order6B), 7},
      {INTEGRATOR(Yoshida1990Order6C), 7},
      {INTEGRATOR(McLachlan1995SS9), 9},
      {INTEGRATOR(OkunborSkeel1994Order6Method13), 7},
      {INTEGRATOR(Yoshida1990Order8A), 15},
      {INTEGRATOR(Yoshida1990Order8B), 15},
      {INTEGRATOR(Yoshida1990Order8C), 15},
      {INTEGRATOR(Yoshida1990Order8D), 15},
      {INTEGRATOR(Yoshida1990Order8E), 15},
      {INTEGRATOR(McLachlan1995SS15), 15},
      {INTEGRATOR(McLachlan1995SS17), 17}};
}

std::string ErrorPlot(std::string const& data, std::string const& legend,
                      std::string const& error_kind) {
  std::vector<double> const range = {1e-16, 1};
  std::vector<std::string> const axes_label = {"Evaluations",
                                               Escape(error_kind)};
  return Apply(
      "ListLogLogPlot",
      {data,
       Option("PlotLegends", Apply("SwatchLegend", {legend})),
       Option("PlotRange", ToMathematica(range)),
       Option("AxesLabel", ToMathematica(axes_label)),
       Option("ImageSize", "1200")});
}

}  // namespace

void GenerateSimpleHarmonicMotionWorkErrorGraphs() {
  SRKNIntegrator::Parameters<Length, Speed> parameters;
  SRKNIntegrator::Solution<Length, Speed> solution;
  std::ofstream file;
  file.open("simple_harmonic_motion_graphs.m");
  Length const q_amplitude = 1 * Metre;
  Speed const v_amplitude = 1 * Metre / Second;
  AngularFrequency const ω = 1 * Radian / Second;
  Stiffness const k = SIUnit<Stiffness>();
  Mass const m = 1 * Kilogram;
  double const step_reduction = 1.015;
  parameters.initial.positions.emplace_back(q_amplitude);
  parameters.initial.momenta.emplace_back(0 * Metre / Second);
  parameters.initial.time = 0 * Second;
  parameters.tmax = 50 * Second;
  // We use dense sampling in order to compute average errors, this leads to
  // more evaluations than reported for FSAL methods.
  parameters.sampling_period = 1;
  std::vector<std::string> q_plots;
  std::vector<std::string> v_plots;
  std::vector<std::string> e_plots;
  std::vector<std::string> names;
  for (auto const& method : Methods()) {
    LOG(INFO) << method.name;
    parameters.Δt = method.stages * 1 * Second;
    std::vector<Length> q_errors;
    std::vector<Speed> v_errors;
    std::vector<Energy> e_errors;
    std::vector<double> evaluations;
    for (int i = 0; i < 500; ++i, parameters.Δt /= step_reduction) {
      int const number_of_evaluations =
          method.stages * std::ceil(parameters.tmax / parameters.Δt);
      LOG_IF(INFO, (i + 1) % 50 == 0) << number_of_evaluations;
      method.integrator->SolveTrivialKineticEnergyIncrement<Length>(
          &ComputeHarmonicOscillatorAcceleration,
          parameters,
          &solution);
      std::vector<Length> q_error;
      std::vector<Speed> v_error;
      std::vector<Energy> e_error;
      for (auto const& system_state : solution) {
        q_error.emplace_back(
            AbsoluteError(q_amplitude * Cos(ω * system_state.time.value),
                          system_state.positions[0].value));
        v_error.emplace_back(
            AbsoluteError(-v_amplitude * Sin(ω * system_state.time.value),
                          system_state.momenta[0].value));
        e_error.emplace_back(
            AbsoluteError(
                0.5 * Joule,
                (m * Pow<2>(system_state.momenta[0].value) +
                 k * Pow<2>(system_state.positions[0].value)) / 2));
      }
      q_errors.emplace_back(*std::max_element(q_error.begin(), q_error.end()));
      v_errors.emplace_back(*std::max_element(v_error.begin(), v_error.end()));
      e_errors.emplace_back(*std::max_element(e_error.begin(), e_error.end()));
      evaluations.emplace_back(number_of_evaluations);
    }
    q_plots.emplace_back(PlottableDataset(evaluations, q_errors));
    v_plots.emplace_back(PlottableDataset(evaluations, v_errors));
    e_plots.emplace_back(PlottableDataset(evaluations, e_errors));
    names.emplace_back(Escape(method.name));
  }
  file << Assign("qErrorPlots", q_plots);
  file << Assign("vErrorPlots", v_plots);
  file << Assign("eErrorPlots", e_plots);
  file << Assign("names", names);
  file << Export("shm_q_error.png",
                 ErrorPlot("qErrorPlots", "names", "Position error (m)"));
  file << Export("shm_v_error.png",
                 ErrorPlot("vErrorPlots", "names", "Velocity error (m/s)"));
  file << Export("shm_e_error.png",
                 ErrorPlot("eErrorPlots", "names", "Energy error (J)"));
  file.close();
}

}  // namespace mathematica
}  // namespace principia
<commit_msg>comment<commit_after>
#include "mathematica/integrator_plots.hpp"

#include <fstream>  // NOLINT(readability/streams)
#include <iostream>  // NOLINT(readability/streams)
#include <string>
#include <vector>

#include "glog/logging.h"
#include "integrators/symplectic_partitioned_runge_kutta_integrator.hpp"
#include "quantities/quantities.hpp"
#include "quantities/named_quantities.hpp"
#include "mathematica/mathematica.hpp"
#include "testing_utilities/numerical_analysis.hpp"
#include "testing_utilities/numerics.hpp"

#define INTEGRATOR(name) &integrators::name(), #name

namespace principia {

using base::not_null;
using integrators::SRKNIntegrator;
using quantities::AngularFrequency;
using quantities::Cos;
using quantities::Energy;
using quantities::Length;
using quantities::Pow;
using quantities::Sin;
using quantities::Speed;
using si::Joule;
using si::Kilogram;
using si::Metre;
using si::Radian;
using si::Second;
using testing_utilities::AbsoluteError;
using testing_utilities::ComputeHarmonicOscillatorAcceleration;

namespace mathematica {

namespace {

struct SimpleHarmonicMotionPlottedIntegrator {
  not_null<SRKNIntegrator const*> integrator;
  std::string name;
  int stages;
};

std::vector<SimpleHarmonicMotionPlottedIntegrator> Methods() {
  return {
      {INTEGRATOR(Leapfrog), 1},
      {INTEGRATOR(PseudoLeapfrog), 1},
      {INTEGRATOR(McLachlanAtela1992Order2Optimal), 2},
      {INTEGRATOR(McLachlan1995S2), 2},
      {INTEGRATOR(Ruth1983), 3},
      {INTEGRATOR(McLachlanAtela1992Order3Optimal), 3},
      {INTEGRATOR(CandyRozmus1991ForestRuth1990SynchronousMomenta), 3},
      {INTEGRATOR(CandyRozmus1991ForestRuth1990SynchronousPositions), 3},
      {INTEGRATOR(Suzuki1990), 5},
      {INTEGRATOR(McLachlan1995SS5), 5},
      {INTEGRATOR(McLachlan1995S4), 4},
      {INTEGRATOR(McLachlan1995S5), 5},
      {INTEGRATOR(McLachlanAtela1992Order4Optimal), 4},
      {INTEGRATOR(McLachlan1995SB3A4), 4},
      {INTEGRATOR(McLachlan1995SB3A5), 5},
      {INTEGRATOR(McLachlanAtela1992Order5Optimal), 6},
      {INTEGRATOR(Yoshida1990Order6A), 7},
      {INTEGRATOR(Yoshida1990Order6B), 7},
      {INTEGRATOR(Yoshida1990Order6C), 7},
      {INTEGRATOR(McLachlan1995SS9), 9},
      {INTEGRATOR(OkunborSkeel1994Order6Method13), 7},
      {INTEGRATOR(Yoshida1990Order8A), 15},
      {INTEGRATOR(Yoshida1990Order8B), 15},
      {INTEGRATOR(Yoshida1990Order8C), 15},
      {INTEGRATOR(Yoshida1990Order8D), 15},
      {INTEGRATOR(Yoshida1990Order8E), 15},
      {INTEGRATOR(McLachlan1995SS15), 15},
      {INTEGRATOR(McLachlan1995SS17), 17}};
}

std::string ErrorPlot(std::string const& data, std::string const& legend,
                      std::string const& error_kind) {
  std::vector<double> const range = {1e-16, 1};
  std::vector<std::string> const axes_label = {"Evaluations",
                                               Escape(error_kind)};
  return Apply(
      "ListLogLogPlot",
      {data,
       Option("PlotLegends", Apply("SwatchLegend", {legend})),
       Option("PlotRange", ToMathematica(range)),
       Option("AxesLabel", ToMathematica(axes_label)),
       Option("ImageSize", "1200")});
}

}  // namespace

void GenerateSimpleHarmonicMotionWorkErrorGraphs() {
  SRKNIntegrator::Parameters<Length, Speed> parameters;
  SRKNIntegrator::Solution<Length, Speed> solution;
  std::ofstream file;
  file.open("simple_harmonic_motion_graphs.m");
  Length const q_amplitude = 1 * Metre;
  Speed const v_amplitude = 1 * Metre / Second;
  AngularFrequency const ω = 1 * Radian / Second;
  Stiffness const k = SIUnit<Stiffness>();
  Mass const m = 1 * Kilogram;
  double const step_reduction = 1.015;
  parameters.initial.positions.emplace_back(q_amplitude);
  parameters.initial.momenta.emplace_back(0 * Metre / Second);
  parameters.initial.time = 0 * Second;
  parameters.tmax = 50 * Second;
  // We use dense sampling in order to compute average errors, this leads to
  // more evaluations than reported for FSAL methods.
  parameters.sampling_period = 1;
  std::vector<std::string> q_plots;
  std::vector<std::string> v_plots;
  std::vector<std::string> e_plots;
  std::vector<std::string> names;
  for (auto const& method : Methods()) {
    LOG(INFO) << method.name;
    parameters.Δt = method.stages * 1 * Second;
    std::vector<Length> q_errors;
    std::vector<Speed> v_errors;
    std::vector<Energy> e_errors;
    std::vector<double> evaluations;
    for (int i = 0; i < 500; ++i, parameters.Δt /= step_reduction) {
      int const number_of_evaluations =
          method.stages * std::ceil(parameters.tmax / parameters.Δt);
      LOG_IF(INFO, (i + 1) % 50 == 0) << number_of_evaluations;
      method.integrator->SolveTrivialKineticEnergyIncrement<Length>(
          &ComputeHarmonicOscillatorAcceleration,
          parameters,
          &solution);
      std::vector<Length> q_error;
      std::vector<Speed> v_error;
      std::vector<Energy> e_error;
      for (auto const& system_state : solution) {
        q_error.emplace_back(
            AbsoluteError(q_amplitude * Cos(ω * system_state.time.value),
                          system_state.positions[0].value));
        v_error.emplace_back(
            AbsoluteError(-v_amplitude * Sin(ω * system_state.time.value),
                          system_state.momenta[0].value));
        e_error.emplace_back(
            AbsoluteError(
                0.5 * Joule,
                (m * Pow<2>(system_state.momenta[0].value) +
                 k * Pow<2>(system_state.positions[0].value)) / 2));
      }
      // We plot the maximum error, i.e., the L∞ norm of the error.
      // Blanes and Moan (2002), or Blanes, Casas and Ros (2001) tend to use
      // the average error (the normalized L¹ norm) instead.
      q_errors.emplace_back(*std::max_element(q_error.begin(), q_error.end()));
      v_errors.emplace_back(*std::max_element(v_error.begin(), v_error.end()));
      e_errors.emplace_back(*std::max_element(e_error.begin(), e_error.end()));
      evaluations.emplace_back(number_of_evaluations);
    }
    q_plots.emplace_back(PlottableDataset(evaluations, q_errors));
    v_plots.emplace_back(PlottableDataset(evaluations, v_errors));
    e_plots.emplace_back(PlottableDataset(evaluations, e_errors));
    names.emplace_back(Escape(method.name));
  }
  file << Assign("qErrorPlots", q_plots);
  file << Assign("vErrorPlots", v_plots);
  file << Assign("eErrorPlots", e_plots);
  file << Assign("names", names);
  file << Export("shm_q_error.png",
                 ErrorPlot("qErrorPlots", "names", "Position error (m)"));
  file << Export("shm_v_error.png",
                 ErrorPlot("vErrorPlots", "names", "Velocity error (m/s)"));
  file << Export("shm_e_error.png",
                 ErrorPlot("eErrorPlots", "names", "Energy error (J)"));
  file.close();
}

}  // namespace mathematica
}  // namespace principia
<|endoftext|>


<commit_before>#include "V3DInstance.h"

V3D_RESULT V3DCheckLayer(V3D_LAYER layer)
{
	uint32_t vLayerPropCount;
	std::vector<VkLayerProperties> vLayerProps;

	VkResult vResult = vkEnumerateInstanceLayerProperties(&vLayerPropCount, nullptr);
	if (vResult != VK_SUCCESS)
	{
		return V3D_ERROR_FAIL;
	}

	vLayerProps.resize(vLayerPropCount);
	vResult = vkEnumerateInstanceLayerProperties(&vLayerPropCount, vLayerProps.data());
	if (vResult != VK_SUCCESS)
	{
		return V3D_ERROR_FAIL;
	}

	const char* pLayerName = nullptr;

	switch (layer)
	{
	case V3D_LAYER_STANDARD:
		pLayerName = V3D_LAYER_LUNARG_standard_validation;
		break;

	case V3D_LAYER_NSIGHT:
		pLayerName = V3D_LAYER_NV_nsight;
		break;

	case V3D_LAYER_RENDERDOC:
		pLayerName = V3D_LAYER_RENDERDOC_Capture;
		break;
	}

	if ((pLayerName == nullptr) || (std::find_if(vLayerProps.begin(), vLayerProps.end(), V3DFindLayer(pLayerName)) == vLayerProps.end()))
	{
		return V3D_ERROR_NOT_SUPPORTED;
	}

	return V3D_OK;
}

V3D_RESULT V3DCreateInstance(const V3DInstanceDesc& instanceDesc, IV3DInstance** ppInstance)
{
	if (V3DInstance::IsCreated() == true)
	{
		return V3D_ERROR_FAIL;
	}

	// ----------------------------------------------------------------------------------------------------
	// ̏
	// ----------------------------------------------------------------------------------------------------

	if (((instanceDesc.memory.pAllocateFunction == nullptr) && (instanceDesc.memory.pReallocateFunction == nullptr) && (instanceDesc.memory.pFreeFunction == nullptr)) ||
		((instanceDesc.memory.pAllocateFunction != nullptr) && (instanceDesc.memory.pReallocateFunction != nullptr) && (instanceDesc.memory.pFreeFunction != nullptr)))
	{
		;
	}
	else
	{
		return V3D_ERROR_INVALID_ARGUMENT;
	}

	V3D_MEM_INIT(instanceDesc.memory.pAllocateFunction, instanceDesc.memory.pReallocateFunction, instanceDesc.memory.pFreeFunction, instanceDesc.memory.pUserData);

	// ----------------------------------------------------------------------------------------------------
	// CX^X̍쐬
	// ----------------------------------------------------------------------------------------------------

	V3DInstance* pInstance = V3DInstance::Create();
	if (pInstance == nullptr)
	{
		return V3D_ERROR_OUT_OF_HOST_MEMORY;
	}

	V3D_RESULT result = pInstance->Initialize(instanceDesc);
	if (result != V3D_OK)
	{
		V3D_RELEASE(pInstance);
		return result;
	}

	(*ppInstance) = pInstance;

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

	return V3D_OK;
}
<commit_msg>レイヤーの名前を変更<commit_after>#include "V3DInstance.h"

V3D_RESULT V3DCheckLayer(V3D_LAYER layer)
{
	uint32_t vLayerPropCount;
	std::vector<VkLayerProperties> vLayerProps;

	VkResult vResult = vkEnumerateInstanceLayerProperties(&vLayerPropCount, nullptr);
	if (vResult != VK_SUCCESS)
	{
		return V3D_ERROR_FAIL;
	}

	vLayerProps.resize(vLayerPropCount);
	vResult = vkEnumerateInstanceLayerProperties(&vLayerPropCount, vLayerProps.data());
	if (vResult != VK_SUCCESS)
	{
		return V3D_ERROR_FAIL;
	}

	const char* pLayerName = nullptr;

	switch (layer)
	{
	case V3D_LAYER_VALIDATION:
		pLayerName = V3D_LAYER_LUNARG_standard_validation;
		break;

	case V3D_LAYER_NSIGHT:
		pLayerName = V3D_LAYER_NV_nsight;
		break;

	case V3D_LAYER_RENDERDOC:
		pLayerName = V3D_LAYER_RENDERDOC_Capture;
		break;
	}

	if ((pLayerName == nullptr) || (std::find_if(vLayerProps.begin(), vLayerProps.end(), V3DFindLayer(pLayerName)) == vLayerProps.end()))
	{
		return V3D_ERROR_NOT_SUPPORTED;
	}

	return V3D_OK;
}

V3D_RESULT V3DCreateInstance(const V3DInstanceDesc& instanceDesc, IV3DInstance** ppInstance)
{
	if (V3DInstance::IsCreated() == true)
	{
		return V3D_ERROR_FAIL;
	}

	// ----------------------------------------------------------------------------------------------------
	// ̏
	// ----------------------------------------------------------------------------------------------------

	if (((instanceDesc.memory.pAllocateFunction == nullptr) && (instanceDesc.memory.pReallocateFunction == nullptr) && (instanceDesc.memory.pFreeFunction == nullptr)) ||
		((instanceDesc.memory.pAllocateFunction != nullptr) && (instanceDesc.memory.pReallocateFunction != nullptr) && (instanceDesc.memory.pFreeFunction != nullptr)))
	{
		;
	}
	else
	{
		return V3D_ERROR_INVALID_ARGUMENT;
	}

	V3D_MEM_INIT(instanceDesc.memory.pAllocateFunction, instanceDesc.memory.pReallocateFunction, instanceDesc.memory.pFreeFunction, instanceDesc.memory.pUserData);

	// ----------------------------------------------------------------------------------------------------
	// CX^X̍쐬
	// ----------------------------------------------------------------------------------------------------

	V3DInstance* pInstance = V3DInstance::Create();
	if (pInstance == nullptr)
	{
		return V3D_ERROR_OUT_OF_HOST_MEMORY;
	}

	V3D_RESULT result = pInstance->Initialize(instanceDesc);
	if (result != V3D_OK)
	{
		V3D_RELEASE(pInstance);
		return result;
	}

	(*ppInstance) = pInstance;

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

	return V3D_OK;
}
<|endoftext|>