text:
// graph-tool -- a general graph modification and manipulation thingy
//
// Copyright (C) 2006-2018 Tiago de Paula Peixoto <tiago@skewed.de>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

#include "graph_filtering.hh"
#include "graph.hh"
#include "graph_util.hh"
#include "graph_python_interface.hh"

#include <boost/python.hpp>
#include <boost/python/stl_iterator.hpp>
#include <set>

using namespace std;
using namespace boost;
using namespace graph_tool;

namespace graph_tool
{

template <class ValueList>
struct add_edge_list
{
    template <class Graph>
    void operator()(Graph& g, python::object aedge_list,
                    python::object& eprops, bool& found) const
    {
        boost::mpl::for_each<ValueList>(std::bind(dispatch(), std::ref(g),
                                                  std::ref(aedge_list),
                                                  std::ref(eprops),
                                                  std::ref(found),
                                                  std::placeholders::_1));
    }

    struct dispatch
    {
        template <class Graph, class Value>
        void operator()(Graph& g, python::object& aedge_list,
                        python::object& oeprops, bool& found, Value) const
        {
            if (found)
                return;
            try
            {
                boost::multi_array_ref<Value, 2> edge_list = get_array<Value, 2>(aedge_list);

                if (edge_list.shape()[1] < 2)
                    throw GraphException("Second dimension in edge list must be of size (at least) two");

                typedef typename graph_traits<Graph>::edge_descriptor edge_t;
                vector<DynamicPropertyMapWrap<Value, edge_t>> eprops;
                python::stl_input_iterator<boost::any> iter(oeprops), end;
                for (; iter != end; ++iter)
                    eprops.emplace_back(*iter, writable_edge_properties());

                size_t n_props = std::min(eprops.size(), edge_list.shape()[1] - 2);

                for (const auto& e : edge_list)
                {
                    size_t s = e[0];
                    size_t t = e[1];
                    while (s >= num_vertices(g) || t >= num_vertices(g))
                        add_vertex(g);
                    auto ne = add_edge(vertex(s, g), vertex(t, g), g).first;
                    for (size_t i = 0; i < n_props; ++i)
                    {
                        try
                        {
                            put(eprops[i], ne, e[i + 2]);
                        }
                        catch(bad_lexical_cast&)
                        {
                            throw ValueException("Invalid edge property value: " +
                                                 lexical_cast<string>(e[i + 2]));
                        }
                    }
                }
                found = true;
            }
            catch (InvalidNumpyConversion& e) {}
        }
    };
};

void do_add_edge_list(GraphInterface& gi, python::object aedge_list,
                      python::object eprops)
{
    typedef mpl::vector<bool, char, uint8_t, uint16_t, uint32_t, uint64_t,
                        int8_t, int16_t, int32_t, int64_t, uint64_t, double,
                        long double> vals_t;
    bool found = false;
    run_action<>()(gi, std::bind(add_edge_list<vals_t>(), std::placeholders::_1,
                                 aedge_list, std::ref(eprops),
                                 std::ref(found)))();
    if (!found)
        throw GraphException("Invalid type for edge list; must be two-dimensional with a scalar type");
}

template <class ValueList>
struct add_edge_list_hash
{
    template <class Graph, class VProp>
    void operator()(Graph& g, python::object aedge_list, VProp vmap,
                    bool& found, bool use_str, python::object& eprops) const
    {
        boost::mpl::for_each<ValueList>(std::bind(dispatch(), std::ref(g),
                                                  std::ref(aedge_list), std::ref(vmap),
                                                  std::ref(found), std::ref(eprops),
                                                  std::placeholders::_1));
        if (!found)
        {
            if (use_str)
                dispatch()(g, aedge_list, vmap, found, eprops, std::string());
            else
                dispatch()(g, aedge_list, vmap, found, eprops, python::object());
        }
    }

    struct dispatch
    {
        template <class Graph, class VProp, class Value>
        void operator()(Graph& g, python::object& aedge_list, VProp& vmap,
                        bool& found, python::object& oeprops, Value) const
        {
            if (found)
                return;
            try
            {
                boost::multi_array_ref<Value, 2> edge_list = get_array<Value, 2>(aedge_list);
                unordered_map<Value, size_t> vertices;

                if (edge_list.shape()[1] < 2)
                    throw GraphException("Second dimension in edge list must be of size (at least) two");

                typedef typename graph_traits<Graph>::edge_descriptor edge_t;
                vector<DynamicPropertyMapWrap<Value, edge_t>> eprops;
                python::stl_input_iterator<boost::any> iter(oeprops), end;
                for (; iter != end; ++iter)
                    eprops.emplace_back(*iter, writable_edge_properties());

                auto get_vertex = [&] (const Value& r) -> size_t
                    {
                        auto iter = vertices.find(r);
                        if (iter == vertices.end())
                        {
                            auto v = add_vertex(g);
                            vertices[r] = v;
                            vmap[v] = lexical_cast<typename property_traits<VProp>::value_type>(r);
                            return v;
                        }
                        return iter->second;
                    };

                for (const auto& e : edge_list)
                {
                    size_t s = get_vertex(e[0]);
                    size_t t = get_vertex(e[1]);
                    auto ne = add_edge(vertex(s, g), vertex(t, g), g).first;
                    for (size_t i = 0; i < e.size() - 2; ++i)
                    {
                        try
                        {
                            put(eprops[i], ne, e[i + 2]);
                        }
                        catch(bad_lexical_cast&)
                        {
                            throw ValueException("Invalid edge property value: " +
                                                 lexical_cast<string>(e[i + 2]));
                        }
                    }
                }
                found = true;
            }
            catch (InvalidNumpyConversion& e) {}
        }

        template <class Graph, class VProp>
        void operator()(Graph& g, python::object& edge_list, VProp& vmap,
                        bool& found, python::object& oeprops, std::string) const
        {
            if (found)
                return;
            try
            {
                unordered_map<std::string, size_t> vertices;

                typedef typename graph_traits<Graph>::edge_descriptor edge_t;
                vector<DynamicPropertyMapWrap<python::object, edge_t>> eprops;
                python::stl_input_iterator<boost::any> piter(oeprops), pend;
                for (; piter != pend; ++piter)
                    eprops.emplace_back(*piter, writable_edge_properties());

                auto get_vertex = [&] (const std::string& r) -> size_t
                    {
                        auto iter = vertices.find(r);
                        if (iter == vertices.end())
                        {
                            auto v = add_vertex(g);
                            vertices[r] = v;
                            vmap[v] = lexical_cast<typename property_traits<VProp>::value_type>(r);
                            return v;
                        }
                        return iter->second;
                    };

                python::stl_input_iterator<python::object> iter(edge_list), end;
                for (; iter != end; ++iter)
                {
                    const auto& row = *iter;

                    python::stl_input_iterator<python::object> eiter(row), eend;

                    size_t s = 0;
                    size_t t = 0;

                    typename graph_traits<Graph>::edge_descriptor e;
                    size_t i = 0;
                    for(; eiter != eend; ++eiter)
                    {
                        if (i >= eprops.size() + 2)
                            break;
                        const auto& val = *eiter;
                        switch (i)
                        {
                        case 0:
                            s = get_vertex(python::extract<std::string>(val));
                            while (s >= num_vertices(g))
                                add_vertex(g);
                            break;
                        case 1:
                            t = get_vertex(python::extract<std::string>(val));
                            while (t >= num_vertices(g))
                                add_vertex(g);
                            e = add_edge(vertex(s, g), vertex(t, g), g).first;
                            break;
                        default:
                            try
                            {
                                put(eprops[i - 2], e, val);
                            }
                            catch(bad_lexical_cast&)
                            {
                                throw ValueException("Invalid edge property value: " +
                                                     python::extract<string>(python::str(val))());
                            }
                        }
                        i++;
                    }
                }
                found = true;
            }
            catch (InvalidNumpyConversion& e) {}
        }

        template <class Graph, class VProp>
        void operator()(Graph& g, python::object& edge_list, VProp& vmap,
                        bool& found, python::object& oeprops, python::object) const
        {
            if (found)
                return;
            try
            {
                unordered_map<python::object, size_t> vertices;

                typedef typename graph_traits<Graph>::edge_descriptor edge_t;
                vector<DynamicPropertyMapWrap<python::object, edge_t>> eprops;
                python::stl_input_iterator<boost::any> piter(oeprops), pend;
                for (; piter != pend; ++piter)
                    eprops.emplace_back(*piter, writable_edge_properties());

                auto get_vertex = [&] (const python::object& r) -> size_t
                    {
                        auto iter = vertices.find(r);
                        if (iter == vertices.end())
                        {
                            auto v = add_vertex(g);
                            vertices[r] = v;
                            vmap[v] = python::extract<typename property_traits<VProp>::value_type>(r);
                            return v;
                        }
                        return iter->second;
                    };

                python::stl_input_iterator<python::object> iter(edge_list), end;
                for (; iter != end; ++iter)
                {
                    const auto& row = *iter;

                    python::stl_input_iterator<python::object> eiter(row), eend;

                    size_t s = 0;
                    size_t t = 0;

                    typename graph_traits<Graph>::edge_descriptor e;
                    size_t i = 0;
                    for(; eiter != eend; ++eiter)
                    {
                        if (i >= eprops.size() + 2)
                            break;
                        const auto& val = *eiter;
                        switch (i)
                        {
                        case 0:
                            s = get_vertex(val);
                            while (s >= num_vertices(g))
                                add_vertex(g);
                            break;
                        case 1:
                            t = get_vertex(val);
                            while (t >= num_vertices(g))
                                add_vertex(g);
                            e = add_edge(vertex(s, g), vertex(t, g), g).first;
                            break;
                        default:
                            try
                            {
                                put(eprops[i - 2], e, val);
                            }
                            catch(bad_lexical_cast&)
                            {
                                throw ValueException("Invalid edge property value: " +
                                                     python::extract<string>(python::str(val))());
                            }
                        }
                        i++;
                    }
                }
                found = true;
            }
            catch (InvalidNumpyConversion& e) {}
        }
    };
};

void do_add_edge_list_hashed(GraphInterface& gi, python::object aedge_list,
                             boost::any& vertex_map, bool is_str,
                             python::object eprops)
{
    typedef mpl::vector<bool, char, uint8_t, uint16_t, uint32_t, uint64_t,
                        int8_t, int16_t, int32_t, int64_t, uint64_t, double,
                        long double> vals_t;
    bool found = false;
    run_action<graph_tool::all_graph_views, boost::mpl::true_>()
        (gi, std::bind(add_edge_list_hash<vals_t>(), std::placeholders::_1,
                       aedge_list, std::placeholders::_2, std::ref(found),
                       is_str, std::ref(eprops)),
         writable_vertex_properties())(vertex_map);
}

struct add_edge_list_iter
{
    template <class Graph>
    void operator()(Graph& g, python::object& edge_list,
                    python::object& oeprops) const
    {
        typedef typename graph_traits<Graph>::edge_descriptor edge_t;
        vector<DynamicPropertyMapWrap<python::object, edge_t>> eprops;
        python::stl_input_iterator<boost::any> piter(oeprops), pend;
        for (; piter != pend; ++piter)
            eprops.emplace_back(*piter, writable_edge_properties());

        python::stl_input_iterator<python::object> iter(edge_list), end;
        for (; iter != end; ++iter)
        {
            const auto& row = *iter;
            python::stl_input_iterator<python::object> eiter(row), eend;

            size_t s = 0;
            size_t t = 0;

            typename graph_traits<Graph>::edge_descriptor e;
            size_t i = 0;
            for(; eiter != eend; ++eiter)
            {
                if (i >= eprops.size() + 2)
                    break;
                const auto& val = *eiter;
                switch (i)
                {
                case 0:
                    s = python::extract<size_t>(val);
                    while (s >= num_vertices(g))
                        add_vertex(g);
                    break;
                case 1:
                    t = python::extract<size_t>(val);
                    while (t >= num_vertices(g))
                        add_vertex(g);
                    e = add_edge(vertex(s, g), vertex(t, g), g).first;
                    break;
                default:
                    try
                    {
                        put(eprops[i - 2], e, val);
                    }
                    catch(bad_lexical_cast&)
                    {
                        throw ValueException("Invalid edge property value: " +
                                             python::extract<string>(python::str(val))());
                    }
                }
                i++;
            }
        }
    }
};

void do_add_edge_list_iter(GraphInterface& gi, python::object edge_list,
                           python::object eprops)
{
    run_action<>()
        (gi, std::bind(add_edge_list_iter(), std::placeholders::_1,
                       std::ref(edge_list), std::ref(eprops)))();
}

} // namespace graph_tool


text:
/*
 * WorkDispatcher.cxx
 *
 *  Created on: May 12, 2015
 *      Author: kheddar
 */

#include "WorkDispatcher.hxx"
#include "MddProxyException.hxx"
#include "MddProxyRunLogger.hxx"
#include <boost/thread/mutex.hpp>
#include <boost/thread/thread.hpp>
#include <boost/foreach.hpp>

namespace mdm {
namespace mddproxy {

WorkDispatcher::WorkDispatcher(WorkItemsT* rcvrs, size_t maxWorkerThreads)
{
	receivers = rcvrs;
	pendingItems = new PendingWorkQueue<Socket*>();
	freeWorkers = new std::deque<Worker*>;
	busyWorkers = new std::deque<Worker*>;

	totalWorkerCount = 0;
	AddWorkers(5);
}

WorkDispatcher::~WorkDispatcher() {

	pendingItems->Clear();
	delete pendingItems;

}

int WorkDispatcher::AddWorkers(size_t count)
{
	for (size_t i=0; i < count; i++)
	{
		Worker* newWorker = CreateNewWorker();
		freeWorkers->push_back(newWorker);
	}
	LOGINF("Added %d new workers. Total worker count %d", count, totalWorkerCount);
	return count;
}

Worker* WorkDispatcher::CreateNewWorker()
{
	Worker* newWorker = new Worker(totalWorkerCount, this);
	pthread_t* thId = newWorker->Create();

	LOGINF("Created new worker id %ld", thId);
	workers.push_back(newWorker);

	totalWorkerCount++;

	return newWorker;
}

void WorkDispatcher::WakeUpAllThreads()
{
	boost::mutex::scoped_lock lock(sync_lock);

	BOOST_FOREACH(Worker *worker, workers)
	{
		worker->FinishAndDie();
	}
}

void WorkDispatcher::ProcessData(struct epoll_event* evList, int eventCount)
{
	for (int i=0; i < eventCount; i++)
	{
		WorkItemsItT result = receivers->find(evList[i].data.fd);

		THROW_IF(result == receivers->end(), "receiver not found fd=>%d",evList[i].data.fd );

		Worker*  worker;
		if (GetFreeWorker(worker))
		{
			//result->second->ReceiveData();
			worker->GetParams()->receiverSocket = result->second;
			worker->Resume();
		}
		else if (totalWorkerCount < MAX_WORKER_THREADS)
		{
			worker = CreateNewWorker();
			// allocate worker
			//result->second->ReceiveData();
			worker->GetParams()->receiverSocket = result->second;
			worker->Resume();
			RecordNewBusyWorker(worker);

			worker->Create();
		}
		else
		{
			pendingItems->Push(result->second);
		}
	}
}

bool WorkDispatcher::GetFreeWorker(Worker* &worker)
{
	boost::mutex::scoped_lock lock(sync_lock);

	if (freeWorkers->size() > 0)
	{
		worker = freeWorkers->front();
		freeWorkers->pop_front();
		busyWorkers->push_back(worker);
		return true;
	}

	return false;
}

void WorkDispatcher::RecordNewBusyWorker(Worker* worker)
{
	boost::mutex::scoped_lock lock(sync_lock);

	busyWorkers->push_back(worker);
}

size_t WorkDispatcher::ReturnFreeWorker(Worker* worker)
{
	boost::mutex::scoped_lock lock(sync_lock);

	freeWorkers->push_back(worker);
	return freeWorkers->size();
}

void WorkDispatcher::JoinThreads()
{
	BOOST_FOREACH(Worker *worker, workers)
	{
		pthread_join(*worker->GetThreadId(), NULL);
		delete worker;
	}
}

} /* namespace mddproxy */
} /* namespace mdm */

ext: cxx

max_stars_repo_name: dkhedekar/ProxyDataRouter

max_issues_repo_name: dkhedekar/ProxyDataRouter

max_forks_repo_name: dkhedekar/ProxyDataRouter


text:
/* (c) Copyright 2012 Felipe Magno de Almeida
 *
 * Distributed under the Boost Software License, Version 1.0. (See
 * accompanying file LICENSE_1_0.txt or copy at
 * http://www.boost.org/LICENSE_1_0.txt)
 */

#ifndef MORBID_IDL_PARSER_GRAMMAR_MODULE_OPEN_HPP
#define MORBID_IDL_PARSER_GRAMMAR_MODULE_OPEN_HPP

#include <boost/spirit/home/qi/nonterminal/grammar.hpp>
#include <boost/spirit/home/qi.hpp>
#include <boost/spirit/home/phoenix.hpp>

#include <morbid/idl_parser/tokenizer.hpp>
#include <morbid/idl_parser/typedef_def.hpp>

namespace morbid { namespace idl_parser { namespace grammar {

namespace qi = boost::spirit::qi;
namespace lex = boost::spirit::lex;

template <typename Iterator>
struct module_open : boost::spirit::qi::grammar
 <Iterator, std::string(), skipper<Iterator> >
{
  typedef typename Iterator::base_iterator_type base_iterator;

  template <typename TokenDef>
  module_open(TokenDef const& tok)
    : module_open::base_type(start)
  {
    start %= qi::omit[tok.module_keyword]
      >> tok.identifier >> qi::omit['{'];
  }

  boost::spirit::qi::rule<Iterator, std::string(), skipper<Iterator> > start;
};

} } }

#endif

ext: hpp

max_stars_repo_name: felipealmeida/mORBid

max_issues_repo_name: felipealmeida/mORBid

max_forks_repo_name: felipealmeida/mORBid


text:
//==================================================================================================
/*!
  @file

  @copyright 2016 NumScale SAS

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#ifndef BOOST_SIMD_FUNCTION_BITOFSIGN_HPP_INCLUDED
#define BOOST_SIMD_FUNCTION_BITOFSIGN_HPP_INCLUDED

#if defined(DOXYGEN_ONLY)
namespace boost { namespace simd
{

 /*!

    @ingroup group-ieee
    Function object implementing bitofsign capabilities

    Returns a value of the same type as the input with all bits set to zero
    except the bit of sign which is preserved.

    Returns always @ref Zero for unsigned types

    @par Semantic:

    @code
    auto r = bitofsign(x);
    @endcode

    for signed types is similar to:

    @code
    auto r = x&Signmask<T>();
    @endcode

    @see sign, signnz, is_negative, is_positive, Mzero, Signmask;

  **/
  Value bitofsign(Value const & v0);
} }
#endif

#include <boost/simd/function/scalar/bitofsign.hpp>
#include <boost/simd/function/simd/bitofsign.hpp>

#endif

max_stars_repo_name: xmar/pythran

max_issues_repo_name: xmar/pythran

max_forks_repo_name: xmar/pythran


text:
//==================================================================================================
/*!
  @file

  @copyright 2016 NumScale SAS
  @copyright 2016 J.T. Lapreste

  Distributed under the Boost Software License, Version 1.0.
  (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
*/
//==================================================================================================
#ifndef BOOST_SIMD_FUNCTION_FMAX_HPP_INCLUDED
#define BOOST_SIMD_FUNCTION_FMAX_HPP_INCLUDED

#if defined(DOXYGEN_ONLY)
namespace boost { namespace simd
{

 /*!

    @ingroup group-ieee
    Function object implementing fmax capabilities

    Returns the maximum value, ignoring nans.

    This is a convenient alias of @ref maxnum
  **/
  const boost::dispatch::functor<tag::fmax_> fmax = {};
} }
#endif

#include <boost/simd/function/scalar/maxnum.hpp>
#include <boost/simd/function/simd/fmax.hpp>

#endif


text:
// Copyright 2013-2020 Lawrence Livermore National Security, LLC and other
// HavoqGT Project Developers. See the top-level LICENSE file for details.
//
// SPDX-License-Identifier: MIT

#ifndef HAVOQGT_MPI_MAILBOX_ROUTED_HPP_INCLUDED
#define HAVOQGT_MPI_MAILBOX_ROUTED_HPP_INCLUDED

#include <havoqgt/mpi.hpp>

#include <vector>
#include <list>
#include <limits>
#include <deque>
#include <boost/unordered_map.hpp>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <boost/tuple/tuple.hpp>

namespace havoqgt {

template <typename TMsg>
class mailbox_routed {

  // class routed_msg_type {
  // public:
  //   routed_msg_type(uint32_t _dest, const TMsg& _msg)
  //     : msg(_msg) { }
  //   TMsg     msg;
  //   //uint32_t m_dest;
  //   uint32_t dest() const { return msg.vertex.owner();/*m_dest;*/ }
  //   bool     is_tree_op() const { return msg.vertex.is_bcast() ||
  //                                        msg.vertex.is_parent_op(); }
  // };

  struct routed_msg_type {
    uint64_t dest      : 30;
    uint64_t bcast     : 1;
    uint64_t intercept : 1;
    TMsg        msg;
  };

  class twod_router{
  public:
    //const static int procs_per_node = 16;
    int procs_per_node;
    twod_router() { }
    twod_router(uint32_t rank, uint32_t size) {
      procs_per_node = std::min(size,uint32_t(24));
      uint64_t rank_to_print = 2;
      //if(rank == rank_to_print)
      //std::cout << "Rank " << rank_to_print << "'s bcast_targets: ";
      my_node_base_rank = rank - (rank % procs_per_node);;
      for(uint32_t i=0; i<procs_per_node; ++i) {
        uint64_t target = my_node_base_rank + i;
        m_bcast_targets.push_back(target);
        //if(rank==rank_to_print)
        //std::cout << target << " ";
      }
      //if(rank==rank_to_print)
      //  std::cout << std::endl << "Rank " << rank_to_print << "'s bcast_proxies: ";
      uint64_t node_offset = rank % procs_per_node;
      for(uint32_t i=0; i<size / procs_per_node; ++i) {
        uint64_t proxy = (i * procs_per_node) + node_offset;
        m_bcast_proxies.push_back(proxy);
        //if(rank==rank_to_print)
        //  std::cout << proxy << " ";
      }
      //if(rank == rank_to_print)
      //  std::cout << std::endl;
    }
    uint32_t proxy_rank(uint32_t dest) {
      uint64_t dest_offset = dest % procs_per_node;
      return my_node_base_rank + dest_offset;
    }
    const std::vector<uint32_t>& bcast_targets() const { return m_bcast_targets; }
    const std::vector<uint32_t>& bcast_proxies() const { return m_bcast_proxies; }
  private:
    std::vector<uint32_t> m_bcast_proxies;
    std::vector<uint32_t> m_bcast_targets;
    uint64_t my_node_base_rank;
  };

  class msg_buffer {
  public:
    msg_buffer():m_size(0),m_ptr(NULL) { }
    msg_buffer(void* _ptr):m_size(0),m_ptr(_ptr) { }

    size_t push_back(const routed_msg_type& _msg) {
      static_cast<routed_msg_type*>(m_ptr)[m_size] = _msg;
      return ++m_size;
    }

    routed_msg_type& operator[](size_t i) { return static_cast<routed_msg_type*>(m_ptr)[i]; }

    size_t size_in_bytes() { return m_size * sizeof(routed_msg_type); }

    size_t size() const { return m_size; }
    bool empty() const { return m_size == 0; }
    void clear() { m_size = 0; m_ptr = NULL; }
    bool is_init() const {return m_ptr != NULL; }
    void* get_ptr() const {return m_ptr; }

  private:
    size_t m_size;
    void* m_ptr;
  };
public:
  typedef TMsg message_type;

  mailbox_routed(int _mpi_tag):
              m_mpi_comm(MPI_COMM_WORLD),
              m_mpi_tag(_mpi_tag) {
    m_pending_partial_buffers = 0;
    m_num_pending_isend = 0;

    m_last_recv_count = 0;

    //statistics
    m_mpi_send_counter  = 0;
    m_tree_send_counter = 0;
    m_route_counter     = 0;
    m_send_counter      = 0;
    m_recv_counter      = 0;

    m_receiving = false;

    CHK_MPI(MPI_Comm_rank(m_mpi_comm, &m_mpi_rank) );
    CHK_MPI(MPI_Comm_size(m_mpi_comm, &m_mpi_size) );

    //Allocate buffer slots for each rank.
    //This does not acutally allocate the buffer's memory
    m_buffer_per_rank.resize(m_mpi_size);
    m_list_isend_request_per_rank.resize(m_mpi_size);
    m_pending_iterator_per_rank.resize(m_mpi_size,m_list_pending.end());

    for(size_t i=0; i<get_environment().mailbox_num_irecv(); ++i) {
      void* irecv_buff = NULL;
      int ret = posix_memalign(&irecv_buff, 32,
                     get_environment().mailbox_aggregation() * sizeof(routed_msg_type));
      if(ret !=0) {
        perror("posix_memalign-irecv"); exit(-1);
      }
      post_new_irecv(irecv_buff);
    }
    m_2d_comm = twod_router(m_mpi_rank, m_mpi_size);

    m_tree_parent = m_mpi_rank / 2;
    m_tree_child1 = (m_mpi_rank * 2) + 1;
    m_tree_child2 = (m_mpi_rank * 2) + 2;

    if(m_mpi_rank ==0) {
      std::cout << "sizeof(message_type) = " << sizeof(message_type) << std::endl;
    }

  }

  ~mailbox_routed() {
    assert(m_pending_partial_buffers == 0);
    while(m_num_pending_isend > 0) {
      cleanup_pending_isend_requests(true);
    }
    while(!m_list_irecv_request.empty()) {
      CHK_MPI( MPI_Cancel( &(m_list_irecv_request.front().first) ) );
      free(m_list_irecv_request.front().second);
      m_list_irecv_request.pop_front();
    }
    for(size_t i=0; i<m_vec_free_buffers.size(); ++i) {
      free(m_vec_free_buffers[i]);
    }

    if(get_environment().mailbox_print_stats()) {
      uint64_t g_mpi_send_counter  = mpi_all_reduce(m_mpi_send_counter, std::plus<uint64_t>(), MPI_COMM_WORLD);
      uint64_t g_tree_send_counter = mpi_all_reduce(m_tree_send_counter, std::plus<uint64_t>(), MPI_COMM_WORLD);
      uint64_t g_route_counter     = mpi_all_reduce(m_route_counter, std::plus<uint64_t>(), MPI_COMM_WORLD);
      uint64_t g_send_counter      = mpi_all_reduce(m_send_counter, std::plus<uint64_t>(), MPI_COMM_WORLD);
      uint64_t g_recv_counter      = mpi_all_reduce(m_recv_counter, std::plus<uint64_t>(), MPI_COMM_WORLD);
      if(m_mpi_rank == 0) {
        std::cout << "******************  Mailbox Statistics ********************" << std::endl;
        std::cout << "routed message size = " << sizeof(TMsg) << std::endl;
        std::cout << "mpi_send_counter  = " << g_mpi_send_counter  << std::endl;
        std::cout << "tree_send_counter = " << g_tree_send_counter << std::endl;
        std::cout << "route_counter     = " << g_route_counter     << std::endl;
        std::cout << "send_counter      = " << g_send_counter      << std::endl;
        std::cout << "recv_counter      = " << g_recv_counter      << std::endl;
        std::cout << "Average send size = " << double(g_send_counter + g_route_counter) / double(g_mpi_send_counter) << std::endl;
        std::cout << "***********************************************************" << std::endl;
      }
    }

    CHK_MPI( MPI_Barrier( m_mpi_comm ) );
  }

  /*void send_tree_fast(int raw_dest, const TMsg& _raw_msg) {
    ++m_tree_send_counter;
    routed_msg_type msg(raw_dest, _raw_msg);
    if(!m_buffer_per_rank[raw_dest].is_init()) {
      m_buffer_per_rank[raw_dest] = allocate_msg_buffer();
      ++m_pending_partial_buffers;
      m_list_pending.push_back(raw_dest);
      m_pending_iterator_per_rank[raw_dest] = --m_list_pending.end();
    }
    size_t size = m_buffer_per_rank[raw_dest].push_back(msg);

    if(size >= get_environment().mailbox_tree_aggregation() ) {
      post_isend(raw_dest);
      check_for_starvation();
    }
  }

  void send_tree_parent(const TMsg& _raw_msg) {
    send_tree_fast(m_tree_parent, _raw_msg);
  }

  void send_tree_children(const TMsg& _raw_msg) {
    if(m_tree_child1 < m_mpi_size) {
      send_tree_fast(m_tree_child1, _raw_msg);
      if(m_tree_child2 < m_mpi_size) {
        send_tree_fast(m_tree_child2, _raw_msg);
      }
    }
  }
  */

  void route_fast_path(uint32_t dest, const routed_msg_type& _msg) {
    ++m_route_counter;
    if(!m_buffer_per_rank[dest].is_init()) {
      m_buffer_per_rank[dest] = allocate_msg_buffer();
      ++m_pending_partial_buffers;
      m_list_pending.push_back(dest);
      m_pending_iterator_per_rank[dest] = --m_list_pending.end();
    }
    size_t size = m_buffer_per_rank[dest].push_back(_msg);

    if(size == get_environment().mailbox_aggregation() ) {
      post_isend(dest);
      check_for_starvation();
    }
  }

  template <typename OutputIterator>
  void bcast(TMsg _raw_msg, OutputIterator _oitr) {
    _raw_msg.vertex.set_bcast(true);
    routed_msg_type msg;
    msg.bcast = true;
    msg.msg = _raw_msg;
    msg.dest = m_mpi_size+1;
    for(uint32_t i=0; i<m_2d_comm.bcast_proxies().size(); ++i) {
      uint32_t proxy_rank = m_2d_comm.bcast_proxies()[i];
      if(proxy_rank == uint32_t(m_mpi_rank)) {
        bcast_to_targets(msg);
      } else {
        route_fast_path(proxy_rank, msg);
      }
    }
    if(m_receiving) return;   //prevent receive recursion @todo, make this a function called wait
    do {
      cleanup_pending_isend_requests();
      receive(_oitr);
    } while(m_num_pending_isend > get_environment().mailbox_num_isend());
  }

  void bcast_to_targets(routed_msg_type msg) {
    assert(msg.bcast);
    for(uint32_t i=0; i<m_2d_comm.bcast_targets().size(); ++i) {
      uint32_t target = m_2d_comm.bcast_targets()[i];
      msg.dest= target;
      route_fast_path(target, msg);
    }
  }

  void check_for_starvation() {
    /*if(!m_list_pending.empty()) {
      size_t to_check = m_list_pending.front();
      size_t size = m_send_ticket_per_rank.size();
      //size_t to_check = ++m_fair_checker % size;
      if(m_send_counter > m_send_ticket_per_rank[to_check] + size) {
        post_isend(to_check);
      }
    }*/
  }

  template <typename OutputIterator>
  void send(int raw_dest, const TMsg& _raw_msg, OutputIterator _oitr, bool _intercept) {
    ++m_send_counter;
    assert(raw_dest >= 0 && raw_dest < m_mpi_size);
    //++m_last_recv_count;
    assert(raw_dest != m_mpi_rank); // just dont send to self!
    //routed_msg_type msg(raw_dest, _raw_msg);
    routed_msg_type msg; //@todo fixme
    msg.msg  = _raw_msg;
    msg.dest = raw_dest;
    msg.intercept = _intercept;
    msg.bcast = false;
    int dest = m_2d_comm.proxy_rank(raw_dest);
    if(dest == m_mpi_rank) dest = raw_dest;
    if(!m_buffer_per_rank[dest].is_init()) {
      m_buffer_per_rank[dest] = allocate_msg_buffer();
      ++m_pending_partial_buffers;
      m_list_pending.push_back(dest);
      m_pending_iterator_per_rank[dest] = --m_list_pending.end();
    }
    size_t size = m_buffer_per_rank[dest].push_back(msg);

    if(size == get_environment().mailbox_aggregation() ) {
      post_isend(dest);
      check_for_starvation();
      if(m_receiving) return;   //prevent receive recursion
      do {
        //cleanup_pending_isend_requests_index(dest);
        cleanup_pending_isend_requests();
        receive(_oitr);
      //} while(m_list_isend_request_per_rank[dest].size() > 1);
      } while(m_num_pending_isend > get_environment().mailbox_num_isend());
    }
    //if(m_last_recv_count > 128) {
    //  receive(_oitr);
    //}
  }

  template <typename OutputIterator > //was vector but also want list
  void receive(OutputIterator _oitr, bool aggregsive=false) {
    m_receiving = true;
    m_last_recv_count = 0;
    int flag(0);
    //do {
      if(!m_list_irecv_request.empty()) {
        std::pair<MPI_Request, void* > pair_req = m_list_irecv_request.front();
        m_list_irecv_request.pop_front();
        MPI_Request* request_ptr = &(pair_req.first);
        MPI_Status status;
        CHK_MPI( MPI_Test( request_ptr, &flag, &status) );
        if(flag) {
          routed_msg_type* recv_ptr = static_cast<routed_msg_type*> (
                           pair_req.second );
          int count(0);
          CHK_MPI( MPI_Get_count(&status, MPI_BYTE, &count) );
          for(size_t i=0; i<count/sizeof(routed_msg_type); ++i) {
            if(recv_ptr[i].dest == uint32_t(m_mpi_rank) /*|| recv_ptr[i].is_tree_op()*/) {
              *_oitr = recv_ptr[i].msg;//.msg;
              ++_oitr;
              ++m_recv_counter;
            } else if(recv_ptr[i].bcast) {
              bcast_to_targets(recv_ptr[i]);
            } else if(recv_ptr[i].intercept) {
              if( _oitr.intercept(recv_ptr[i].msg) ) {
                route_fast_path(recv_ptr[i].dest, recv_ptr[i]);
              }
            } else {
              route_fast_path(recv_ptr[i].dest, recv_ptr[i]);
            }
          }
          post_new_irecv(recv_ptr);
        } else {
          m_list_irecv_request.push_front(pair_req);
        }
      }
    //} while(flag);
    m_receiving = false;
  }

  bool is_idle() {
    cleanup_pending_isend_requests();
    return m_pending_partial_buffers == 0 && m_num_pending_isend == 0;
  }

  void flush_buffers_if_idle() {
    if(!m_list_pending.empty()) {
      size_t index = m_list_pending.front();
      if(m_num_pending_isend < 1 && !m_buffer_per_rank[index].empty()) {
        post_isend(index);
      }
    }
  }

  int comm_rank() const { return m_mpi_rank; }
  int comm_size() const { return m_mpi_size; }

private:
  msg_buffer allocate_msg_buffer() {
    if(m_vec_free_buffers.empty()) {
      void* buff = NULL;
      int ret = posix_memalign(&buff, 32,
                      get_environment().mailbox_aggregation() * sizeof(routed_msg_type));
      if(ret !=0) {
        perror("posix_memalign"); exit(-1);
      }
      m_vec_free_buffers.push_back(buff);
    }
    msg_buffer to_return(m_vec_free_buffers.back());
    m_vec_free_buffers.pop_back();
    return to_return;
  }

  void free_msg_buffer(void* _ptr) {
    m_vec_free_buffers.push_back(_ptr);
  }

  void post_isend(int index) {
    if(m_buffer_per_rank[index].empty()) return;
    m_mpi_send_counter++;
    int dest = index;
    bool was_first_pending = false;
    if(m_pending_iterator_per_rank[dest] != m_list_pending.end()) {
      if(m_pending_iterator_per_rank[dest] == m_list_pending.begin()) {
        was_first_pending = true;
      }
      m_list_pending.erase(m_pending_iterator_per_rank[dest]);
      m_pending_iterator_per_rank[dest] = m_list_pending.end();
    }

    m_list_isends.push_back(index);
    boost::tuple<MPI_Request, void*,std::list<size_t>::iterator> isend_req_tuple;
    MPI_Request* request_ptr = &(isend_req_tuple.get<0>());
    isend_req_tuple.get<1>() = m_buffer_per_rank[index].get_ptr();
    isend_req_tuple.get<2>() = --m_list_isends.end();
    void* buffer_ptr = m_buffer_per_rank[index].get_ptr();
    int size_in_bytes = m_buffer_per_rank[index].size_in_bytes();

    CHK_MPI( MPI_Issend( buffer_ptr, size_in_bytes, MPI_BYTE, dest,
                        m_mpi_tag, m_mpi_comm, request_ptr) );

    --m_pending_partial_buffers;
    m_buffer_per_rank[index].clear();
    //int flag(0);
    //CHK_MPI( MPI_Test( request_ptr, &flag, MPI_STATUS_IGNORE) );
    //if(!flag) {
    m_list_isend_request_per_rank[index].push_back(isend_req_tuple);
    ++m_num_pending_isend;
    //}
    cleanup_pending_isend_requests();
    if(!was_first_pending/* && m_tree_parent != index && m_tree_child1 != index && m_tree_child2 != index*/) {
      post_isend(m_list_pending.front());
    }
  }

  bool cleanup_pending_isend_requests_index(size_t index) {
    bool to_return = false;
    if(m_list_isend_request_per_rank[index].empty()) return true;
    while(!m_list_isend_request_per_rank[index].empty()) {
      int flag(0);
      MPI_Request* request_ptr = &(m_list_isend_request_per_rank[index].front().get<0>());
      CHK_MPI( MPI_Test( request_ptr, &flag, MPI_STATUS_IGNORE) );
      if(flag) {
        free_msg_buffer(m_list_isend_request_per_rank[index].front().get<1>());
        m_list_isends.erase(m_list_isend_request_per_rank[index].front().get<2>());
        m_list_isend_request_per_rank[index].pop_front();
        --m_num_pending_isend;
        to_return = true;
      } else {
        break;
      }
    }
    return to_return;
  }

  /// If the number of current pending isends is less than user desired,
  /// just check the next fair bit.   If the number is greater than
  /// desired, aggregsively check all bits.
  void cleanup_pending_isend_requests(bool force_aggressive = false) {
    while(!m_list_isends.empty()) {
      bool found = cleanup_pending_isend_requests_index(m_list_isends.front());
      if(!found) break;
    }
  }

  void post_new_irecv(void* _buff) {
    std::pair<MPI_Request, void*> irecv_req;
    irecv_req.second = _buff;
    MPI_Request* request_ptr = &(irecv_req.first);
    int num_bytes = get_environment().mailbox_aggregation() * sizeof(routed_msg_type);
    CHK_MPI( MPI_Irecv( _buff, num_bytes, MPI_BYTE, MPI_ANY_SOURCE,
                        m_mpi_tag, m_mpi_comm, request_ptr) );
    m_list_irecv_request.push_back(irecv_req);
  }

  /// MPI configuration
  MPI_Comm m_mpi_comm;
  int m_mpi_tag;
  int m_mpi_rank;
  int m_mpi_size;

  size_t m_pending_partial_buffers;
  size_t m_num_pending_isend;
  size_t                  m_last_recv_count;

  std::vector<void*> m_vec_free_buffers;
  std::vector<msg_buffer> m_buffer_per_rank;
  //boost::unordered_map<uint32_t, msg_buffer> m_buffer_per_rank;

  std::vector< std::list< boost::tuple<MPI_Request, void*, std::list<size_t>::iterator > > > m_list_isend_request_per_rank;
  //boost::unordered_map<uint64_t, std::list< boost::tuple<MPI_Request, void*, std::list<size_t>::iterator > > > m_list_isend_request_per_rank;
  std::list <size_t> m_list_isends;
  std::list < std::pair<MPI_Request, void*> > m_list_irecv_request;

  twod_router m_2d_comm;

  std::vector< std::list<size_t>::iterator > m_pending_iterator_per_rank;
  //boost::unordered_map<uint64_t, std::list<size_t>::iterator > m_pending_iterator_per_rank;
  std::list <size_t> m_list_pending;

  int m_tree_parent;
  int m_tree_child1;
  int m_tree_child2;

  bool m_receiving;

  //Statistics
  uint64_t                m_mpi_send_counter;
  uint64_t                m_tree_send_counter;
  uint64_t                m_route_counter;
  uint64_t                m_send_counter;
  uint64_t                m_recv_counter;

};

} //namespace havoqgt {

#endif //HAVOQGT_MPI_MAILBOX_ROUTED_HPP_INCLUDED

max_stars_repo_name: niklas-uhl/havoqgt

max_issues_repo_name: niklas-uhl/havoqgt

max_forks_repo_name: niklas-uhl/havoqgt


text:
/*
 * LYHoldemTable.cpp
 *
 *  Created on: 2013-7-6
 *      Author: caiqingfeng
 */

#include "LYHoldemTable.h"
//#include <boost/foreach.hpp>
#include "LYHoldemTrunk.h"
//#include "common/src/my_log.h"
#include "LYHoldemGame.h"
#include <iostream>

LYHoldemTable::LYHoldemTable(const std::string &tid, unsigned int ts, enum LYTableStatus sta,
		const std::string &nm, const std::string &oid, unsigned int occupied, LYProfileMgr *prof_mgr)
{
	// TODO Auto-generated constructor stub
	_id = tid;
	owner = oid;
	status = sta;
	name = nm;
	total_seats = ts;
	occupied_seat_number = occupied;
	createSeats();
    trunk = NULL;
    profileMgr = prof_mgr;
}

LYHoldemTable::LYHoldemTable(const std::string &tid, LYProfileMgr *prof_mgr)
{
	// TODO Auto-generated constructor stub
	_id = tid;
	status = LYTableOpen;
	name = "";
	total_seats = 9;
	createSeats();
    trunk = NULL;
    profileMgr = prof_mgr;
}

LYHoldemTable::~LYHoldemTable() {
	// TODO Auto-generated destructor stub
}

bool LYHoldemTable::playGame(LYHoldemAction &action)
{
//	LY_LOG_DBG("enter LYHoldemTable::playHoldem");
	if (trunk == NULL) {
//		LY_LOG_ERR("fatal error, without trunk!");
		return false;
	}
	return ((LYHoldemTrunk *)trunk)->playGame(action);
}

/*
 * 在反序列化时被外部调用，因为反序列化时，先生成HoldemTable实例
 * 然后得到Table的TotalSeats，再生成Seats实例
 */
void LYHoldemTable::createSeats()
{
	for (unsigned int i = 0; i < total_seats; i++) {
		LYHoldemSeat *seat = new LYHoldemSeat((enum LYApplicant) (i + 1));
		LYSeatPtr sp((LYSeat *)seat);
		seats.push_back(sp);
	}
}

/*
 * after having loaded data from db, call run to set occupied seats
 * register timers
 * ...
 * 20140312 deprecated
 */
void LYHoldemTable::run()
{
//	LY_LOG_DBG("running table...");
	if (trunk == NULL) {
//		LY_LOG_ERR("fatal error, without trunk!");
		return;
	}
	//trunk->run();
}

bool LYHoldemTable::ready2go()
{
//	LY_LOG_DBG("ready2go");
	if (trunk == NULL) {
//		LY_LOG_ERR("fatal error, without trunk!");
		return false;
	}
	return trunk->ready2go();
}

bool LYHoldemTable::isGameOver()
{
//	LY_LOG_DBG("isGameOver");
	if (trunk == NULL) {
//		LY_LOG_ERR("fatal error, without trunk!");
		return true;
	}
	return trunk->isGameOver();
}

void LYHoldemTable::createGame(const std::string &game_id, LYHoldemAlgorithmDelegate *had)
{
//	LY_LOG_DBG("createGame");
	if (trunk == NULL) {
//		LY_LOG_ERR("fatal error, without trunk!");
		return;
	}
	((LYHoldemTrunk *)trunk)->createGame(game_id, had);
	game_round ++;
	current_game_id = game_id;
}

/*
 * 创建游戏
 */
void LYHoldemTable::createGameInstance(const std::string &game_id)
{
	if (trunk == NULL) {
		return;
	}
	((LYHoldemTrunk *)trunk)->createGameInstance(game_id);
	game_round ++;
	current_game_id = game_id;
}

/*
 * 20160311
 */
void LYHoldemTable::createGameInstance(const std::string &game_id, std::vector < std::pair<std::string, std::string> >& kvps)
{
	if (trunk == NULL) {
		return;
	}
	((LYHoldemTrunk *)trunk)->createGameInstance(game_id, kvps);
	game_round ++;
	current_game_id = game_id;
}

void LYHoldemTable::openTrunk(const std::string &trunk_id, const std::string &trunk_name,
		const std::string &player, const std::string &prof_id)
{
	trunk = new LYHoldemTrunk(trunk_id, trunk_name,
			this, this->total_seats, this->seats,
			player, prof_id);
}

void LYHoldemTable::openTrunk(const std::string &trunk_id)
{
	trunk = new LYHoldemTrunk(trunk_id, "trunk_name_is_to_be_done",
			this, this->total_seats, this->seats,
			"", "");
}

void LYHoldemTable::openTrunk(const std::string &trunk_id, const std::string &trunk_name,
			const std::string &player, LYPokerProfile *prof)
{
	trunk = new LYHoldemTrunk(trunk_id, trunk_name,
			this, this->total_seats, this->seats,
			player, prof->_id);
	trunk->profile = prof;
}

void LYHoldemTable::resetSeats() //reset seat to initial status
{
	std::vector<LYSeatPtr>::iterator it = seats.begin();
	for (; it != seats.end(); it++) {
		LYHoldemSeat *seat = (LYHoldemSeat *)(*it).get();
		seat->reset();
	}

	occupied_seat_number = 0;
}

void LYHoldemTable::setSeat(const LYHoldemSeat &seat)
{
	LYSeatPtr st = fetchSeat(seat.seatNo);
	if (NULL == st.get()) {
		return;
	}
	LYHoldemSeat *hst = (LYHoldemSeat *) st.get();
	*hst = seat;
}

LYRanking LYHoldemTable::caculateSeatRanking(LYApplicant seatNo)
{
	LYHoldemGame *game = (LYHoldemGame *)getCurrentGame();
	if (NULL == game) {
		return HighCard;
	}
	return game->caculateSeatRanking(seatNo);
}

unsigned int LYHoldemTable::getCurrentMaxBuyin()
{
	LYHoldemTrunk *trunk = (LYHoldemTrunk *)getTrunk();
	if (trunk == NULL) return 0;
	return trunk->getCurrentMaxBuyin();
}

unsigned int LYHoldemTable::getCurrentMinBuyin()
{
	LYHoldemTrunk *trunk = (LYHoldemTrunk *)getTrunk();
	if (trunk == NULL) return 0;
	return trunk->getCurrentMinBuyin();
}

bool LYHoldemTable::isGameOngoing()
{
	LYHoldemGame* game = (LYHoldemGame*)this->getCurrentGame();
	if (game == NULL) return false;
	return (game->gameStatus == LY_HOLDEMGAME_ONGOING);
}

std::vector < std::pair<std::string, std::string> > LYHoldemTable::table2kvps()
{
	std::vector < std::pair<std::string, std::string> > key_value_pairs;
	key_value_pairs = LYTable::table2kvps();
	return key_value_pairs;
}

std::vector<std::string> LYHoldemTable::getWhiteList()
{
	std::vector<std::string> w;
	LYHoldemGame *game = (LYHoldemGame *)getCurrentGame();
	if (game == NULL) return w;
	return game->getWhiteList();
}

std::vector<std::string> LYHoldemTable::showLastGame()
{
	std::vector<std::string> logs;
	LYHoldemGame *game = (LYHoldemGame *)getLastGame();
	if (game == NULL) return logs;

	return game->getGameLogs();
}

ext: cpp

max_stars_repo_name: caiqingfeng/libpoker

max_issues_repo_name: caiqingfeng/libpoker

max_forks_repo_name: caiqingfeng/libpoker


text:
#include "Generic/common/leak_detection.h"
#include "ActiveLearningData.h"

#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <algorithm>

#include <boost/foreach.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
#include "Generic/common/foreach_pair.hpp"
#include "Generic/common/UnexpectedInputException.h"
#include "Generic/common/SessionLogger.h"
#include "ActiveLearning/AnnotatedInstanceRecord.h"
#include "ActiveLearning/InstanceAnnotationDB.h"
#include "ActiveLearning/FeatureGrid.h"
#include "ActiveLearning/DataView.h"
#include "ActiveLearning/AnnotatedFeatureRecord.h"
#include "ActiveLearning/alphabet/FeatureAlphabet.h"
#define EIGEN_YES_I_KNOW_SPARSE_MODULE_IS_NOT_STABLE_YET
#include "LearnIt/Eigen/Sparse"
#include "LearnIt/db/LearnItDB.h"
//#include "exceptions/ExpiredTrainerException.h"
//#include "trainer.h"

using std::string; using std::wstring;
using std::make_pair;
using std::vector;
using boost::make_shared;
using Eigen::SparseVector;

ActiveLearningData::ActiveLearningData(InstanceAnnotationDBView_ptr db,
			FeatureAlphabet_ptr alphabet, const InstanceHashes_ptr instance_hashes,
			DataView_ptr data) :
_db(db), _alphabet(alphabet), _instance_hashes(instance_hashes),
_fastInstanceAnnotations(instance_hashes->size(), AnnotatedInstanceRecord::NO_ANNOTATION),
_instanceHasAnnotatedFeature(instance_hashes->size(), false),
_data(data)
{
	BOOST_FOREACH(AnnotatedInstanceRecord air, db->getInstanceAnnotations()) {
		try {
			addOrUpdateInstanceAnnotation(air);
		} catch (UnknownInstanceHashException& e) {
			SessionLogger::warn("active_learning") << "No instance matches hash "
				<< e.hash << " stored for an annotation; ignoring";
		}
	}

	BOOST_FOREACH(AnnotatedFeatureRecord_ptr afr, alphabet->annotations()) {
		addAnnotatedFeature(afr);
	}
}

bool ActiveLearningData::addOrUpdateInstanceAnnotation(AnnotatedInstanceRecord air) {
	bool updatedInstances = false;
	_fastInstanceAnnotations[_instance_hashes->instance(air.instance_hash())] =
		air.annotation();

	// check if we already have an annotation for this instance
	InstanceAnnotations::iterator probe =
		_annotatedInstances.find(air.instance_hash());
	SessionLogger::info("register_annotation") <<
		L"Registered annotation for hash " << air.instance_hash();
	if (probe == _annotatedInstances.end()) {
		// if not, add it if it's not a neutral annotation
		// (no need to add neutrals, since everything is neutral
		// by default)
		if (air.annotation()) {
			_annotatedInstances.insert(make_pair(air.instance_hash(), air));
			updatedInstances = true;
		}
	} else {
		if (probe->second.annotation() != air.annotation()) {
			probe->second.setAnnotation(air.annotation());
			updatedInstances = true;
		}
	}

	_fastInstanceAnnotations[_instance_hashes->instance(air.instance_hash())] =
		air.annotation();

	return updatedInstances;
}

int ActiveLearningData::instanceAnnotation(int inst) const {
	return _fastInstanceAnnotations[inst];
}

void ActiveLearningData::startAnnotation(int feat) {
	_featuresBeingAnnotated.insert(feat);
}

void ActiveLearningData::stopAnnotation(int feat) {
	_featuresBeingAnnotated.erase(feat);
}

bool ActiveLearningData::featureBeingAnnotated(int idx) const {
	return std::find(_featuresBeingAnnotated.begin(), _featuresBeingAnnotated.end(),
					idx) != _featuresBeingAnnotated.end();
}

bool ActiveLearningData::featureAlreadyAnnotated(int idx) const {
	return std::find(_features_previously_annotated.begin(), _features_previously_annotated.end(),
					idx) != _features_previously_annotated.end();
}

const std::vector<AnnotatedFeatureRecord_ptr>& ActiveLearningData::annotatedFeatures() const {
	return _annotatedFeatures;
}

AnnotatedFeatureRecord_ptr ActiveLearningData::makeAnnotation(int feat,
													const string& state)
{
	if ("positive" == state) {
		return make_shared<AnnotatedFeatureRecord>(feat, true, 0.85);
	} else if ("weakpositive" == state) {
		return make_shared<AnnotatedFeatureRecord>(feat, true, 0.30);
	} else if ("negative" == state) {
		return make_shared<AnnotatedFeatureRecord>(feat, false, 0.025);
	} else if ("weaknegative" == state) {
		return make_shared<AnnotatedFeatureRecord>(feat, false, 0.05);
	}

	throw UnexpectedInputException("LearnIt2Trainer::makeAnnotation",
		(string("Unknown annotation type ") + state).c_str());
}

void ActiveLearningData::updateInstanceAnnotations(const InstanceHashToAnnotationMap&
											   hashToAnnMap)
{
	BOOST_FOREACH_PAIR(size_t hash, int annotation, hashToAnnMap) {
		_newAnnotatedInstances.push_back(AnnotatedInstanceRecord(hash, annotation));
	}
}

void ActiveLearningData::registerAnnotation(size_t feat, const string& state) {
	_features_previously_annotated.push_back(static_cast<int>(feat));

	if (state != "ignore") {
		_newAnnotatedFeatures.push_back(makeAnnotation(static_cast<int>(feat), state));
	}
}

void ActiveLearningData::syncToDB() {
	_alphabet->recordAnnotations(_annotatedFeatures);
	std::vector<AnnotatedInstanceRecord> airs;
	BOOST_FOREACH_PAIR(size_t hash, const AnnotatedInstanceRecord air, _annotatedInstances) {
		airs.push_back(air);
	}
	_db->recordAnnotations(airs);
}

const std::set<int>& ActiveLearningData::featuresBeingAnnotated() const {
	return _featuresBeingAnnotated;
}

bool ActiveLearningData::updateBetweenIterations() {
	bool ret = false;
	if (!_newAnnotatedFeatures.empty()) {
		BOOST_FOREACH(const AnnotatedFeatureRecord_ptr annFeat, _newAnnotatedFeatures) {
			addAnnotatedFeature(annFeat);
		}
		_newAnnotatedFeatures.clear();
		ret = true;
	}
	if (!_newAnnotatedInstances.empty()) {
		bool updatedInstances = false;

		BOOST_FOREACH(const AnnotatedInstanceRecord annInst, _newAnnotatedInstances) {
			updatedInstances =
				addOrUpdateInstanceAnnotation(annInst) || updatedInstances;
		}
		_newAnnotatedInstances.clear();
		if (updatedInstances) {
			ret = true;
		}
	}
	return ret;
}

void ActiveLearningData::addAnnotatedFeature(AnnotatedFeatureRecord_ptr afr) {
	_annotatedFeatures.push_back(afr);
	for (SparseVector<double>::InnerIterator inst_it(_data->instancesWithFeature(afr->idx));
		inst_it; ++inst_it)
	{
		_instanceHasAnnotatedFeature[inst_it.index()] = true;
	}
}

void ActiveLearningData::_test_clear_annotations() {
	_annotatedFeatures.clear();
	std::fill(_instanceHasAnnotatedFeature.begin(),
		_instanceHasAnnotatedFeature.end(), false);
}

bool ActiveLearningData::instanceHasAnnotatedFeature(int inst) const {
	return _instanceHasAnnotatedFeature[inst];
}

max_stars_repo_name: BBN-E/serif

max_issues_repo_name: BBN-E/serif

max_forks_repo_name: BBN-E/serif


text:
/**
 * Copyright Soramitsu Co., Ltd. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0
 */

#include "framework/integration_framework/port_guard.hpp"

#include <boost/assert.hpp>
#include <boost/format.hpp>

namespace integration_framework {

  constexpr PortGuard::PortType PortGuard::kMaxPort;
  PortGuard::UsedPorts PortGuard::all_used_ports_ = {};
  std::mutex PortGuard::all_used_ports_mutex_ = {};

  PortGuard::PortGuard() = default;

  PortGuard::PortGuard(PortGuard &&other) noexcept
      : instance_used_ports_(std::move(other.instance_used_ports_)) {
    other.instance_used_ports_.reset();
  }

  PortGuard::~PortGuard() {
    std::lock_guard<std::mutex> lock(all_used_ports_mutex_);
    BOOST_ASSERT_MSG(
        ((all_used_ports_ | instance_used_ports_) ^ all_used_ports_).none(),
        "Some ports used by this PortGuard instance are not set in ports "
        "used by all instances!");
    all_used_ports_ &= ~instance_used_ports_;
  }

  boost::optional<PortGuard::PortType> PortGuard::tryGetPort(
      const PortType min_value, const PortType max_value) {
    std::lock_guard<std::mutex> lock(all_used_ports_mutex_);
    PortType tested_port = min_value;
    while (all_used_ports_.test(tested_port)) {
      if (tested_port == max_value) {
        return boost::none;
      }
      ++tested_port;
    }
    BOOST_ASSERT_MSG(!all_used_ports_.test(tested_port),
                     "PortGuard chose an occupied port!");
    BOOST_ASSERT_MSG(tested_port >= min_value && tested_port <= max_value,
                     "PortGuard chose a port outside boundaries!");
    instance_used_ports_.set(tested_port);
    all_used_ports_.set(tested_port);
    return tested_port;
  }

  PortGuard::PortType PortGuard::getPort(const PortType min_value,
                                         const PortType max_value) {
    const auto opt_port = tryGetPort(min_value, max_value);
    BOOST_VERIFY_MSG(
        opt_port,
        (boost::format("Could not get a port in interval [%d, %d]!") % min_value
         % max_value)
            .str()
            .c_str());
    return *opt_port;
  }

  }  // namespace integration_framework

max_stars_repo_name: artyom-yurin/iroha-archive

max_issues_repo_name: artyom-yurin/iroha-archive

max_forks_repo_name: artyom-yurin/iroha-archive


text:
#ifndef BOOST_CONTRACT_DETAIL_DECLSPEC_HPP_
#define BOOST_CONTRACT_DETAIL_DECLSPEC_HPP_

// Copyright (C) 2008-2018 Lorenzo Caminiti
// Distributed under the Boost Software License, Version 1.0 (see accompanying
// file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).
// See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html

// IMPORTANT: Indirectly included by contract_macro.hpp so trivial headers only.
#include <boost/contract/core/config.hpp> // No compile-time overhead.
#include <boost/config.hpp>

/* PUBLIC */

// IMPORTANT: In general, this library should always and only be compiled and
// used as a shared library. Otherwise, lib's state won't be shared among
// different user programs and user libraries. However, this library can be
// safely compiled and used as a static or header-only library only when it is
// being used by a single program unit (e.g., a single program with only
// statically linked libraries that check contracts).

#ifdef BOOST_CONTRACT_DYN_LINK
    #ifdef BOOST_CONTRACT_SOURCE
        #define BOOST_CONTRACT_DETAIL_DECLSPEC BOOST_SYMBOL_EXPORT
    #else
        #define BOOST_CONTRACT_DETAIL_DECLSPEC BOOST_SYMBOL_IMPORT
    #endif
#else
    #define BOOST_CONTRACT_DETAIL_DECLSPEC /* nothing */
#endif

#ifdef BOOST_CONTRACT_HEADER_ONLY
    #define BOOST_CONTRACT_DETAIL_DECLINLINE inline
#else
    #define BOOST_CONTRACT_DETAIL_DECLINLINE /* nothing */

    // Automatically link this lib to correct build variant (for MSVC, etc.).
    #if     !defined(BOOST_ALL_NO_LIB) && \
            !defined(BOOST_CONTRACT_NO_LIB) && \
            !defined(BOOST_CONTRACT_SOURCE)
        #define BOOST_LIB_NAME boost_contract // This lib (static or shared).
        #if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_CONTRACT_DYN_LINK)
            #define BOOST_DYN_LINK // This lib as shared.
        #endif
        #include <boost/config/auto_link.hpp> // Also #undef BOOST_LIB_NAME.
    #endif
#endif

#endif // #include guard


text: #include <boost/log/core/record_view.hpp>

max_stars_repo_name: miathedev/BoostForArduino

max_issues_repo_name: miathedev/BoostForArduino

max_forks_repo_name: miathedev/BoostForArduino


text:
/*
 * Copyright 2021 Assured Information Security, Inc.
 *
 * 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 <introvirt/windows/libraries/advapi32/functions/CryptGenRandom.hh>

#include <boost/io/ios_state.hpp>

namespace introvirt {
namespace windows {
namespace advapi32 {

uint64_t CryptGenRandom::hProv() const { return hProv_; }
void CryptGenRandom::hProv(HCRYPTPROV value) {
    set_argument(0, value);
    hProv_ = value;
}

uint32_t CryptGenRandom::dwLen() const { return dwLen_; }
void CryptGenRandom::dwLen(uint32_t value) {
    set_argument(1, value);
    dwLen_ = value;
}

GuestVirtualAddress CryptGenRandom::pbBuffer() const { return pbBuffer_; }
void CryptGenRandom::pbBuffer(const GuestVirtualAddress& value) {
    set_address_argument(2, value);
    pbBuffer_ = value;
}

bool CryptGenRandom::result() const { return raw_return_value(); }
void CryptGenRandom::result(bool value) { raw_return_value(value); }

void CryptGenRandom::write(std::ostream& os) const {
    boost::io::ios_flags_saver ifs(os);
    os << std::hex;
    os << '\t' << "hProv: 0x" << hProv() << '\n';
    os << std::dec;
    os << '\t' << "dwLen: " << dwLen() << '\n';
    os << '\t' << "pbBuffer: " << pbBuffer() << '\n';
    if (returned())
        os << '\t' << "Result: " << result() << '\n';
}

CryptGenRandom::CryptGenRandom(Event& event) : WindowsFunctionCall(event, ArgumentCount) {
    hProv_ = get_argument(0);
    dwLen_ = get_argument(1);
    pbBuffer_ = get_address_argument(2);
}

CryptGenRandom::~CryptGenRandom() = default;

const std::string& CryptGenRandom::function_name() const { return FunctionName; }
const std::string& CryptGenRandom::library_name() const { return LibraryName; }

} // namespace advapi32
} // namespace windows
} // namespace introvirt

ext: cc

max_stars_repo_name: srpape/IntroVirt

max_issues_repo_name: srpape/IntroVirt

max_forks_repo_name: srpape/IntroVirt


text:
#ifndef READWRITESOCKET
#define READWRITESOCKET

#include <boost/asio.hpp>

namespace asio = boost::asio;

using tcp=asio::ip::tcp;

class readWriteSocket
{
    public:
    static void writeSocket(tcp::socket&socket,char*data,int len)
    {
        boost::asio::write(socket,boost::asio::buffer(&len,sizeof(int)));
        int transferedBytes=0;
        while(transferedBytes!=len)
        {
            transferedBytes+=boost::asio::write(socket,boost::asio::buffer(data+transferedBytes,len));
        }
    }
    static void readSocket(tcp::socket&socket,char*data)
    {
        int len;
        boost::asio::read(socket,boost::asio::buffer(&len,sizeof(int)));
        int transferedBytes=0;
        while(transferedBytes!=len)
        {
            transferedBytes+=boost::asio::read(socket,boost::asio::buffer(data+transferedBytes,len));
        }
    }
};

#endif /* READWRITESOCKET */

max_stars_repo_name: DimanCPlusPlus/BoostTest

max_issues_repo_name: DimanCPlusPlus/BoostTest

max_forks_repo_name: DimanCPlusPlus/BoostTest


text:
/*
 *  Copyright (c) 2013-2014, Filippo Basso <bassofil@dei.unipd.it>
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are met:
 *     1. Redistributions of source code must retain the above copyright
 *        notice, this list of conditions and the following disclaimer.
 *     2. Redistributions in binary form must reproduce the above copyright
 *        notice, this list of conditions and the following disclaimer in the
 *        documentation and/or other materials provided with the distribution.
 *     3. Neither the name of the copyright holder(s) nor the
 *        names of its contributors may be used to endorse or promote products
 *        derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
 *  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 *  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 *  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef UNIPD_CALIBRATION_IMPL_CALIBRATION_PCL_UTILITIES_POINT_PLANE_EXTRACTION_HPP_
#define UNIPD_CALIBRATION_IMPL_CALIBRATION_PCL_UTILITIES_POINT_PLANE_EXTRACTION_HPP_

#include <Eigen/Geometry>
#include <Eigen/StdVector>

#include <pcl/impl/point_types.hpp>
#include <pcl/PCLHeader.h>
#include <pcl/PointIndices.h>
#include <pcl/segmentation/extract_clusters.h>
#include <pcl/visualization/keyboard_event.h>

#include <vector>

#include <calibration_pcl/utilities/point_plane_extraction.h>

namespace unipd
{
namespace calib
{

template <typename PCLPointT_>
  void PointPlaneExtraction<PCLPointT_>::setInputCloud(const PointCloudConstPtr & cloud)
  {
    cloud_ = cloud;
    cloud_tree_->setInputCloud(cloud_);

    NormalEstimator normal_estimator;
    normal_estimator.setInputCloud(cloud_);
    normal_estimator.setSearchMethod(cloud_tree_);
    normal_estimator.setKSearch(100); // TODO setRadiusSearch
    //normal_estimator.setRadiusSearch(0.05f);
    normal_estimator.compute(*cloud_normals_);
  }

template <typename PCLPointT_>
  bool PointPlaneExtraction<PCLPointT_>::extract(PlaneInfo & plane_info) const
  {
    if (not plane_info.indices)
      plane_info.indices = boost::make_shared<Indices1>();
    else
      plane_info.indices->clear();

    pcl::PointIndices init_indices;
    std::vector<float> sqr_distances;
    cloud_tree_->radiusSearch(point_, radius_, init_indices.indices, sqr_distances);

    if (init_indices.indices.size() < 50)
    {
      //ROS_ERROR_STREAM("Not enough points found near (" << point_.x << ", " << point_.y << ", " << point_.z << ")");
      return false;
    }

    Eigen::VectorXf coefficients(Eigen::VectorXf::Zero(4));
    ModelNormalPlane model(cloud_);
    model.setNormalDistanceWeight(0.2);
    model.setInputNormals(cloud_normals_);
    Eigen::VectorXf new_coefficients(4);
    model.optimizeModelCoefficients(init_indices.indices, coefficients, new_coefficients);
    if (coefficients == new_coefficients)
      return false;
    coefficients = new_coefficients;

    boost::shared_ptr<std::vector<int> > all_cloud_indices = model.getIndices();

    model.setIndices(init_indices.indices);
    std::vector<Scalar> distances;
    model.getDistancesToModel(coefficients, distances);
    Eigen::VectorXd v = Eigen::VectorXd::Map(&distances[0], distances.size());
    plane_info.std_dev = 0.0;

    if (v.size() > 0)
      plane_info.std_dev = std::sqrt(v.cwiseAbs2().mean() - std::pow(v.mean(), 2));

    model.setIndices(all_cloud_indices);
    model.selectWithinDistance(coefficients, 5 * plane_info.std_dev, *plane_info.indices);

    model.optimizeModelCoefficients(*plane_info.indices, coefficients, new_coefficients);
    if (coefficients == new_coefficients)
      return false;
    coefficients = new_coefficients;

    model.setNormalDistanceWeight(0.05);
    model.selectWithinDistance(coefficients, 5 * plane_info.std_dev, *plane_info.indices);

    std::vector<pcl::PointIndices> cluster_indices;
    pcl::EuclideanClusterExtraction<PCLPointT_> ec;
    ec.setClusterTolerance(radius_ / 8);
    ec.setMinClusterSize(plane_info.indices->size() / 8);
    ec.setMaxClusterSize(plane_info.indices->size());
    //ec.setSearchMethod(cloud_tree_);
    ec.setInputCloud(cloud_);
    ec.setIndices(plane_info.indices);
    ec.extract(cluster_indices);

    if (cluster_indices.empty())
      return false;

    Size1 max_index = 0;
    Size1 max_size = cluster_indices[0].indices.size();
    for (Size1 i = 1; i < cluster_indices.size(); ++i)
    {
      if (cluster_indices[i].indices.size() > max_size)
      {
        max_size = cluster_indices[i].indices.size();
        max_index = i;
      }
    }

    *plane_info.indices = cluster_indices[max_index].indices;

    plane_info.plane.normal()[0] = coefficients[0];
    plane_info.plane.normal()[1] = coefficients[1];
    plane_info.plane.normal()[2] = coefficients[2];
    plane_info.plane.offset() = coefficients[3];

    return true;
  }

} // namespace calib
} // namespace unipd
#endif // UNIPD_CALIBRATION_sIMPL_CALIBRATION_PCL_UTILITIES_POINT_PLANE_EXTRACTION_HPP_


text:
//
// Created by Karine Miras on 21/03/2017.
//

#include <algorithm>
#include <ctime>
#include <fstream>
#include <iostream>
#include <map>
#include <random>
#include <string>
#include <sstream>
#include <vector>

#include <boost/algorithm/string/classification.hpp>
#include <boost/algorithm/string/split.hpp>

#include <mlpack/core.hpp>
#include <mlpack/methods/neighbor_search/neighbor_search.hpp>

#include "Aux.h"
#include "EvolutionIndirect.h"
#include "Genome.h"
#include "LSystem.h"
#include "Measures.h"

/**
 * Initializes the population with new genomes.
 * @param LS - Lsystem structure containing the alphabet.
 **/
void EvolutionIndirect::initPopulation(LSystem LS)
{

  //creates new genomes according to population size
  for (int i = 1; i <= this->params["pop_size"]; i++)
  {
    // initial genomes receive personal ids, but the ids of the parents are none
    Genome gen = Genome(std::to_string(this->next_id),
                        "N",
                        "N");

    // creates genetic-strings for the production rules of the letters in the grammar (initial random rules)
    gen.build_grammar(LS,
                      this->params);

    this->offspring.push_back(gen);  // adds genome to the population

    // increments id that will be used for any next genome created
    this->next_id++;

  }
}

/**
*   Performs crossover among individuals in the population.
**/

void EvolutionIndirect::crossover(
    LSystem LS)
{

  // creates new individuals via crossover (size of offspring is relative to the size of population)
  for (int i = 0;
       i < ceil(this->params["pop_size"] * this->params["offspring_prop"]); i++)
  {

    // selects parents for the crossover, according to INDEX
    int parent1 = this->tournament();
    int parent2 = parent1;

    while (parent2 == parent1)
    { // makes sure that parent2 is different from parent1
      parent2 = this->tournament();
    }

    // #TEST: Tests if selected parents are different.
    this->tests.testParents(parent1,
                            parent2);

    // creates new offspring genome
    Genome gen = Genome(std::to_string(this->next_id),
                        this->population[parent1].getId(),
                        this->population[parent2].getId());

    this->aux.logs(" crossover for genome " + std::to_string(this->next_id)
                   + " - p1: " + this->population[parent1].getId()
                   + " p2: " + this->population[parent2].getId());

    this->next_id++;

    std::map< std::string, GeneticString  > grammar =
        std::map< std::string, GeneticString  >();

    std::random_device rd;
    std::default_random_engine generator(rd());

    std::uniform_real_distribution< double > prob(0.0, 1.0);

    // for each letter in the grammar
    for (const auto &letter : LS.getAlphabet())
    {
      if (prob(generator) <= prob(generator))
      {
        this->aux.logs(letter.first + " from parent1");

        // copies object of rule from the genome parent1
        GeneticString gsp1 = GeneticString(this->population[parent1]
                                              .getGrammar()[letter.first]);
        grammar.emplace(letter.first, gsp1); // gets it from parent1
      }
      else
      {
        this->aux.logs(letter.first + " from parent2");

        // copies object of rule from the genome parent2
        GeneticString gsp2 = GeneticString(this->population[parent2]
                                               .getGrammar()[letter.first]);
        grammar.emplace(letter.first, gsp2); // gets it from parent1
      }
    }

    gen.setGrammar(grammar); // sets grammar for the new genome

    this->offspring.push_back(gen); // adds new individual to the offspring
  }

}

/**
 * Performs mutation to individuals of the offspring.
 * @param LS - Lsystem structure containing the alphabet.
 * @param offspring - offspring to be mutated
 */

void EvolutionIndirect::mutation(
    LSystem LS)
{

  std::random_device rd;
  std::default_random_engine generator(rd());

  // distribution for letters of the alphabet, to be possibly included
  // (does not include position 0, which is core-component, as it should be present only once)
  std::uniform_int_distribution< int >
      dist_letter(1,
                  (int) LS.getAlphabetIndex().size() - 1);

  // distribution for letters of the alphabet, to be the target of the mutation
  std::uniform_int_distribution< int >
      dist_letter_target(0,
                         (int) LS.getAlphabetIndex().size() - 1);

  // distribution for the mounting commands
  std::uniform_int_distribution< int >
      dist_mountingcommand(0,
                           (int) LS.getMountingCommands().size() - 1);

  // distribution for the moving commands
  std::uniform_int_distribution< int >
      dist_movingcommand(0,
                         (int) LS.getMovingCommands().size() - 1);

  // distribution for the brain move commands (does not include brainperturb)
  std::uniform_int_distribution< int >
      dist_brainmovecommand(1,
                            (int) LS.getBrainMoveCommands().size() - 1);

  // distribution for the brain change commands
  std::uniform_int_distribution< int >
      dist_brainchangecommand(0,
                              (int) LS.getBrainChangeCommands().size() - 1);

  // distribution for 0-1 probabilities
  std::uniform_real_distribution< double > prob(0.0,
                                                1.0);

  // for each genome of the offspring
  for (int i = 0; i < this->offspring.size(); i++)
  {

    std::string mutate_letter = LS.getAlphabetIndex()[dist_letter_target(generator)];
    // distribution for the type of mutation which will be performed
    std::uniform_int_distribution< int > type_mutation(1,
                                                       3);
    int type_of_mutation = type_mutation(generator);

    // mutates genome given  probability
    if (prob(generator) <= this->params["mutation_prob"])
    {

      // # deletion
      if (type_of_mutation == 1)
      {

        //  if there is at least more than one component
        if (this->offspring[i].getGrammar()[mutate_letter].count() > 1)
        {

          // distribution for position of deletion in the genetic-string
          std::uniform_int_distribution< int > pos_d(1,
                                                     this->offspring[i].getGrammar()[mutate_letter].count());
          int pos_deletion = pos_d(generator);

          // if it is the production rule of the core-component, prevents core-component from being deleted, preserving the root
          if (mutate_letter == "C" and pos_deletion == 1)
          {
            // std::cout<<"cant delete the the core-component from the beginning of its rule";
          }
          else
          {

            this->aux.logs("mutation: remove in " + this->offspring[i].getId()
                           + " for " + mutate_letter
                           + " at " + std::to_string(pos_deletion));
            this->offspring[i].getGrammar()[mutate_letter].remove(pos_deletion); //
            // removes item from chosen position

          }
        }

        // # swapping
      }
      else if (type_of_mutation == 2)
      {

        // distribution for position of insertion/swap in the genetic-string
        std::uniform_int_distribution< int > pos_s(1,
                                                   this->offspring[i].getGrammar()[mutate_letter].count());

        // position of items to be swapped in the genetic-string
        int pos_swap1 = pos_s(generator);
        int pos_swap2 = pos_s(generator);

        while (pos_swap2 < pos_swap1)
        {
          pos_swap2 = pos_s(generator);
        }  // makes sure position swap1 is before position swap2

        // never swaps core component
        if (mutate_letter == "C" and pos_swap1 == 1)
        {
          pos_swap1 = 0;
          pos_swap2 = 0;
        }

        this->offspring[i].getGrammar()[mutate_letter].swap(pos_swap1,
                                                       pos_swap2); // removes item from chosen position
        this->aux.logs("mutation: swap in " + this->offspring[i].getId() + " for " +
                       mutate_letter
                       + " between " + std::to_string(pos_swap1) + " and " +
                       std::to_string(pos_swap2));

        // # adding
      }
      else if (type_of_mutation == 3)
      {

        // type of item to add
        std::uniform_int_distribution< int > type_adding(1,
                                                         5);
        int type_of_adding = type_adding(generator);
        int aux =0;

        std::string genetic_string_item = "";

        // distribution for position of insertion in the genetic-string
        std::uniform_int_distribution< int > pos_i(0,
                                                   this->offspring[i].getGrammar()[mutate_letter].count());
        int pos_insertion = pos_i(generator);

        // if it is the production rule of the core-component, prevents new items from being inserted at the beginning, preserving the root
        if (mutate_letter == "C" and pos_insertion == 0)  pos_insertion++;

        // # adding mounting command
        if (type_of_adding == 1)
        {
          aux = dist_mountingcommand(generator);
          this->aux.logs(
              "mutation: add mounting command " + LS.getMountingCommands()[aux]
              + " in " + this->offspring[i].getId()
              + " for " + mutate_letter + " at "
              + std::to_string(pos_insertion));
          genetic_string_item = LS.getMountingCommands()[aux];
        }

          // # adding letter
        else if (type_of_adding == 2)
        {
          aux = dist_letter(generator);
          auto letter = LS.buildBrainCommand(LS.getAlphabetIndex()[aux]);
          this->aux.logs("mutation: add letter " + letter
                         + " in " + this->offspring[i].getId()
                         + " for " + mutate_letter + " at "
                         + std::to_string(pos_insertion));
          genetic_string_item = letter;
        }

          // # adding moving command
        else if (type_of_adding == 3)
        {
          aux = dist_movingcommand(generator);
          this->aux.logs("mutation: add moving command " + LS
              .getMovingCommands()[aux]
                         + " in " + this->offspring[i].getId()
                         + " for " + mutate_letter
                         + " at " + std::to_string(pos_insertion));
          genetic_string_item = LS.getMovingCommands()[aux];
        }

          // # adding brain move command
        else if (type_of_adding == 4)
        {
          aux = dist_brainmovecommand(generator);
          std::string com = LS.buildBrainCommand(LS.getBrainMoveCommands()[aux]);
          this->aux.logs("mutation: add brain move command "
                         + com
                         + " in " + this->offspring[i].getId()
                         + " for " + mutate_letter
                         + " at " + std::to_string(pos_insertion));
          genetic_string_item = com;
        }

          // # adding brain change command (topological change)
        else if (type_of_adding == 5)
        {
          aux = dist_brainchangecommand(generator);
          std::string com = LS.buildBrainCommand(LS.getBrainChangeCommands()[aux]);
          this->aux.logs("mutation: add brain change command "
                         + com
                         + " in " + this->offspring[i].getId()
                         + " for " + mutate_letter
                         + " at " + std::to_string(pos_insertion));
          genetic_string_item = com;
        }

        //  (possibly) alters genetic-string (production rule) adding items (letters or commands)
        this->offspring[i].getGrammar()[mutate_letter].add(pos_insertion,
                                                      genetic_string_item);
      }
    }
  }
}

max_stars_repo_name: karinemiras/l-system

max_issues_repo_name: karinemiras/l-system

max_forks_repo_name: karinemiras/l-system


text:
/*
 * Copyright (C) 2019 Intel Corporation
 *
 * SPDX-License-Identifier: MIT
 *
 */

#include "vme_wpp/vme_wpp.hpp"

#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>
#include <stdexcept>
#include <vector>

#include <boost/program_options.hpp>

#include <boost/compute/core.hpp>
#include <boost/compute/image.hpp>
#include <boost/compute/utility.hpp>

#include <CL/cl_ext_intel.h>

#include "align_utils/align_utils.hpp"
#include "timer/timer.hpp"
#include "ocl_utils/ocl_utils.hpp"
#include "logging/logging.hpp"

namespace au = compute_samples::align_utils;
namespace po = boost::program_options;
namespace compute = boost::compute;

namespace compute_samples {

VmeWppApplication::Arguments VmeWppApplication::parse_command_line(
    const std::vector<std::string> &command_line) {
  Arguments args;

  po::options_description desc("Allowed options");
  auto options = desc.add_options();
  options("help,h", "show help message");
  options("output-bmp,b",
          po::value<bool>(&args.output_bmp)
              ->default_value(false)
              ->implicit_value(true),
          "output to bmp images for each frame");
  options("input-yuv,i",
          po::value<std::string>(&args.input_yuv_path)
              ->default_value("goal_1280x720.yuv"),
          "path to input yuv file");
  options("output-yuv,o",
          po::value<std::string>(&args.output_yuv_path)
              ->default_value("output_goal_1280x720.yuv"),
          "path to output yuv with motion vectors");
  options("qp,q", po::value<int>(&args.qp)->default_value(49),
          "quantization parameter value to use for estimation heuristics"
          "(higher for faster motion frames)");
  options("width,w", po::value<int>(&args.width)->default_value(1280),
          "width of input yuv");
  options("height,h", po::value<int>(&args.height)->default_value(720),
          "height of input yuv");
  options("frames,f", po::value<int>(&args.frames)->default_value(0),
          "number of frame to use for motion estimation (0 represents entire "
          "yuv sequence)");

  po::positional_options_description p;
  p.add("input-yuv", 1);
  p.add("output-yuv", 1);

  po::variables_map vm;
  po::store(
      po::command_line_parser(command_line).options(desc).positional(p).run(),
      vm);

  if (vm.count("help") != 0u) {
    std::cout << desc;
    args.help = true;
    return args;
  }

  po::notify(vm);

  if (args.qp > 51) {
    throw std::invalid_argument("Invalid argument for qp. Valid range (0-51).");
  }

  return args;
}

#define MV_PER_DIM (2)
#define DIM_TO_MB_SZ(X, Y) (au::align_units(au::align_units(X, Y), 16))
#define DIM_TO_MV_SZ(X, Y) (DIM_TO_MB_SZ(X, Y) * MV_PER_DIM)

Application::Status
VmeWppApplication::run_implementation(std::vector<std::string> &command_line) {
  const Arguments args = parse_command_line(command_line);
  if (args.help) {
    return Status::SKIP;
  }

  compute::device device = compute::system::default_device();
  LOG_INFO << "OpenCL device: " << device.name();

  if (!device.supports_extension(
          "cl_intel_device_side_avc_motion_estimation")) {
    LOG_ERROR
        << "The selected device doesn't support device-side motion estimation.";
    return Status::SKIP;
  }

  if (!device.check_version(2, 0)) {
    LOG_ERROR << "The selected device doesn't support OpenCL 2.0.";
    return Status::SKIP;
  }

  LOG_INFO << "Input yuv path: " << args.input_yuv_path;
  LOG_INFO << "Frame size: " << args.width << "x" << args.height << " pixels";

  Timer timer_total;

  compute::context context(device);
  compute::command_queue queue(context, device);

  Timer timer;
  compute::program program =
      build_program(context, "vme_wpp.cl", "-cl-std=CL2.0");
  timer.print("Program created");

  compute::kernel ds_kernel = program.create_kernel("downsample_3_tier");
  compute::kernel hme_n_kernel = program.create_kernel("tier_n_hme");
  compute::kernel wpp_kernel = program.create_kernel("vme_wpp");
  timer.print("Kernels created");

  YuvCapture capture(args.input_yuv_path, args.width, args.height, args.frames);
  const int frame_count =
      (args.frames) != 0 ? args.frames : capture.get_num_frames();
  YuvWriter writer(args.width, args.height, frame_count, args.output_bmp);

  PlanarImage planar_image(args.width, args.height);
  capture.get_sample(0, planar_image);
  timer.print("Read YUV frame 0 from disk to CPU linear memory.");

  writer.append_frame(planar_image);

  compute::image_format format(CL_R, CL_UNORM_INT8);
  compute::image2d ref_image(context, args.width, args.height, format);
  compute::image2d src_image(context, args.width, args.height, format);
  compute::image2d src_image_8x(context, au::align_units(args.width, 8),
                                au::align_units(args.height, 8), format);
  compute::image2d ref_image_8x(context, au::align_units(args.width, 8),
                                au::align_units(args.height, 8), format);
  compute::image2d src_image_4x(context, au::align_units(args.width, 4),
                                au::align_units(args.height, 4), format);
  compute::image2d ref_image_4x(context, au::align_units(args.width, 4),
                                au::align_units(args.height, 4), format);
  compute::image2d src_image_2x(context, au::align_units(args.width, 2),
                                au::align_units(args.height, 2), format);
  compute::image2d ref_image_2x(context, au::align_units(args.width, 2),
                                au::align_units(args.height, 2), format);
  timer.print("Created opencl mem objects for downsample_3_tier kernel");

  size_t origin[] = {0, 0, 0};
  size_t region[] = {static_cast<size_t>(args.width),
                     static_cast<size_t>(args.height), 1};
  queue.enqueue_write_image(src_image, origin, region, planar_image.get_y(),
                            planar_image.get_pitch_y());
  timer.print("Copied frame 0 to tiled memory.");

  ds_kernel.set_args(src_image, src_image_2x, src_image_4x, src_image_8x);
  queue.enqueue_nd_range_kernel(
      ds_kernel, 2, nullptr,
      compute::dim(au::align16(au::align_units(args.width, 4)),
                   au::align_units(args.height, 16))
          .data(),
      compute::dim(16, 1).data());
  timer.print("Enqueued downsample_3_tier kernel for frame 0");

  for (int k = 1; k < frame_count; k++) {
    LOG_INFO << "Processing frame " << k << "...";
    run_vme_wpp(args, device, context, queue, ds_kernel, hme_n_kernel,
                wpp_kernel, capture, planar_image, src_image, ref_image,
                src_image_2x, ref_image_2x, src_image_4x, ref_image_4x,
                src_image_8x, ref_image_8x, k);
    writer.append_frame(planar_image);
  }

  LOG_INFO << "Wrote " << frame_count << " frames with overlaid "
           << "motion vectors to " << args.output_yuv_path << " .";
  writer.write_to_file(args.output_yuv_path.c_str());

  timer_total.print("Total");
  return Status::OK;
}

void VmeWppApplication::run_vme_wpp(
    const VmeWppApplication::Arguments &args, compute::device &device,
    compute::context &context, compute::command_queue &queue,
    compute::kernel &ds_kernel, compute::kernel &hme_n_kernel,
    compute::kernel &wpp_kernel, YuvCapture &capture, PlanarImage &planar_image,
    compute::image2d &src_image, compute::image2d &ref_image,
    compute::image2d &src_2x_image, compute::image2d &ref_2x_image,
    compute::image2d &src_4x_image, compute::image2d &ref_4x_image,
    compute::image2d &src_8x_image, compute::image2d &ref_8x_image,
    int frame_idx) const {
  Timer timer;

  int width = args.width;
  int height = args.height;

  std::swap(ref_image, src_image);
  std::swap(ref_2x_image, src_2x_image);
  std::swap(ref_4x_image, src_4x_image);
  std::swap(ref_8x_image, src_8x_image);

  capture.get_sample(frame_idx, planar_image);
  timer.print("Read next YUV frame from disk to CPU linear memory.");

  size_t origin[] = {0, 0, 0};
  size_t region[] = {static_cast<size_t>(width), static_cast<size_t>(height),
                     1};
  queue.enqueue_write_image(src_image, origin, region, planar_image.get_y(),
                            planar_image.get_pitch_y());
  timer.print("Copied next frame to GPU tiled memory.");

  ds_kernel.set_args(src_image, src_2x_image, src_4x_image, src_8x_image);
  queue.enqueue_nd_range_kernel(
      ds_kernel, 2, nullptr,
      compute::dim(au::align16(au::align_units(width, 4)),
                   au::align_units(height, 16))
          .data(),
      compute::dim(16, 1).data());
  timer.print("Enqueued downsample_3_tier kernel for next frame");

  uint32_t mv_8x_count = DIM_TO_MV_SZ(width, 8) * DIM_TO_MV_SZ(height, 8);
  au::PageAlignedVector<cl_short2> predictors_4x(au::align64(mv_8x_count));
  uint32_t mv_4x_count = DIM_TO_MV_SZ(width, 4) * DIM_TO_MV_SZ(height, 4);
  au::PageAlignedVector<cl_short2> predictors_2x(au::align64(mv_4x_count));
  uint32_t mv_2x_count = DIM_TO_MV_SZ(width, 2) * DIM_TO_MV_SZ(height, 2);
  au::PageAlignedVector<cl_short2> predictors(au::align64(mv_2x_count));

  compute::buffer pred_4x_buffer(
      context, au::align64(mv_8x_count * sizeof(cl_short2)),
      CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, predictors_4x.data());
  compute::buffer pred_2x_buffer(
      context, au::align64(mv_4x_count * sizeof(cl_short2)),
      CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, predictors_2x.data());
  compute::buffer pred_buffer(
      context, au::align64(mv_2x_count * sizeof(cl_short2)),
      CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR, predictors.data());
  timer.print("Created opencl mem objects for tier_n_hme kernel");

  hme_n_kernel.set_arg(0, src_8x_image);
  hme_n_kernel.set_arg(1, ref_8x_image);
  hme_n_kernel.set_arg(2, sizeof(cl_mem), nullptr);
  hme_n_kernel.set_arg(3, pred_4x_buffer);
  queue.enqueue_nd_range_kernel(
      hme_n_kernel, 2, nullptr,
      compute::dim(au::align16(au::align_units(width, 8)),
                   DIM_TO_MB_SZ(height, 8))
          .data(),
      compute::dim(16, 1).data());
  timer.print("Enqueued tier 3 hme kernel for next frame");

  hme_n_kernel.set_args(src_4x_image, ref_4x_image, pred_4x_buffer,
                        pred_2x_buffer);
  queue.enqueue_nd_range_kernel(
      hme_n_kernel, 2, nullptr,
      compute::dim(au::align16(au::align_units(width, 4)),
                   DIM_TO_MB_SZ(height, 4))
          .data(),
      compute::dim(16, 1).data());
  timer.print("Enqueued tier 2 hme kernel for next frame");

  hme_n_kernel.set_args(src_2x_image, ref_2x_image, pred_2x_buffer,
                        pred_buffer);
  queue.enqueue_nd_range_kernel(
      hme_n_kernel, 2, nullptr,
      compute::dim(au::align16(au::align_units(width, 2)),
                   DIM_TO_MB_SZ(height, 2))
          .data(),
      compute::dim(16, 1).data());
  timer.print("Enqueued tier 1 hme kernel for next frame");

  int mb_image_width = au::align_units(width, 16);
  int mb_image_height = au::align_units(height, 16);
  int mb_count = mb_image_width * mb_image_height;
  int mv_image_width = mb_image_width * 4;
  int mv_image_height = mb_image_height * 4;
  int mv_count = mv_image_width * mv_image_height;

  uint32_t num_eu = device.compute_units();
  uint32_t num_threads_per_eu = 7;
  uint32_t max_threads = num_eu * num_threads_per_eu;
  uint32_t width_mb_sz = au::align_units(width, 16);
  uint32_t num_blocks = (width_mb_sz < max_threads) ? width_mb_sz : max_threads;
  uint32_t simd_size = 16;

  au::PageAlignedVector<cl_short2> mvs(au::align64(mv_count));
  au::PageAlignedVector<cl_ushort> residuals(au::align64(mv_count));
  au::PageAlignedVector<cl_uchar2> shapes(au::align64(mb_count));
  au::PageAlignedVector<cl_int> scoreboard(au::align64(width_mb_sz), 0);

  compute::buffer scoreboard_buffer(
      context, au::align64(width_mb_sz * sizeof(uint32_t)),
      CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, scoreboard.data());
  compute::buffer mv_buffer(context, au::align64(mv_count * sizeof(cl_short2)),
                            CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
                            mvs.data());
  compute::buffer residual_buffer(
      context, au::align64(mv_count * sizeof(cl_ushort)),
      CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, residuals.data());
  compute::buffer shape_buffer(
      context, au::align64(mb_count * sizeof(cl_uchar2)),
      CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, shapes.data());
  timer.print("Created opencl mem objects for tier 0 wpp kernel");

  auto qp = static_cast<cl_uchar>(args.qp);
  cl_uchar sad_adjustment = CL_AVC_ME_SAD_ADJUST_MODE_NONE_INTEL;
  cl_uchar pixel_mode = CL_AVC_ME_SUBPIXEL_MODE_QPEL_INTEL;
  wpp_kernel.set_args(src_image, ref_image, pred_buffer, mv_buffer,
                      residual_buffer, shape_buffer, scoreboard_buffer, qp,
                      sad_adjustment, pixel_mode);
  size_t local_size = 16;
  size_t global_size = num_blocks * simd_size;
  queue.enqueue_nd_range_kernel(wpp_kernel, 1, nullptr, &global_size,
                                &local_size);
  timer.print("Enquequed tier 0 vme_wpp kernel");

  queue.finish();
  timer.print("Kernel finished.");

  planar_image.overlay_vectors(reinterpret_cast<motion_vector *>(mvs.data()),
                               reinterpret_cast<inter_shape *>(shapes.data()));
}
} // namespace compute_samples


text:
#ifndef _VSC_BINDINGS_H_
#define _VSC_BINDINGS_H_

#include <map>
#include <set>

#include <boost/shared_ptr.hpp>
#include <boost/foreach.hpp>

/*
 *  Bindings stores and manipulates a group of bindings between Action and
 *  Input types
 */

namespace VSC {

template<typename Action, typename Input>
class Bindings
{

public:

    typedef typename boost::shared_ptr< Bindings<Action,Input> > SPtr;

    typedef typename std::set<Input>                     InputSet;
    typedef typename std::set<Action>                    ActionSet;

    Bindings() {}
    virtual ~Bindings() {}

    /*
     *  Get the Action/Combination associated with a Combination/Action. Returns NullAction/NullCombination
     *  if none was found.
     */

    const ActionSet& getActionsForInput(const Input& input);
    const InputSet& getInputsForAction(const Action& action);

    /*
     *  Erase the binding for a given Action or Combination.
     */

    void eraseBinding(const Action& action, const Input& input);
    void eraseInputBindings(const Input& input);
    void eraseActionBindings(const Action& action);

    /*
     *  Set a binding, throws an exception if the action and/or the combination is already bound.
     */

    void setBinding(const Action& action, const Input& input);

private:

    typedef std::map<Action, InputSet>          ActionInputsMap;
    typedef std::map<Input, ActionSet>          InputActionsMap;

    ActionInputsMap   mActionInputsMap;
    InputActionsMap   mInputActionsMap;

};

template<typename Action, typename Input>
const typename Bindings<Action,Input>::ActionSet& Bindings<Action,Input>::getActionsForInput(const Input& input)
{
    typename InputActionsMap::iterator it = mInputActionsMap.find(input);

    if (it == mInputActionsMap.end())
    {
        /*
         *  If we don't have anything, then create an empty set and return that.
         *  NOTE: DON'T just create a local and return it as it would go out of
         *  scope and be destroyed (potentially) as soon as the function returns.
         */

        ActionSet actionSet;
        mInputActionsMap[input] = actionSet;

        it = mInputActionsMap.find(input);
    }

    return it->second;
}

template<typename Action, typename Input>
const typename Bindings<Action,Input>::InputSet& Bindings<Action,Input>::getInputsForAction(const Action& action)
{
    typename ActionInputsMap::iterator it = mActionInputsMap.find(action);

    if (it == mActionInputsMap.end())
    {
        /*
         *  If we don't have anything, then create an empty set and return that.
         *  NOTE: DON'T just create a local and return it as it would go out of
         *  scope and be destroyed (potentially) as soon as the function returns.
         */

        InputSet inputSet;
        mActionInputsMap[action] = inputSet;

        it = mActionInputsMap.find(action);
    }

    return it->second;
}

template<typename Action, typename Input>
void Bindings<Action,Input>::eraseBinding(const Action& action, const Input& input)
{
    {
        typename ActionInputsMap::iterator it = mActionInputsMap.find(action);

        if (it != mActionInputsMap.end())
        {
            it->second.erase(input);
        }
    }

    {
        typename InputActionsMap::iterator it = mInputActionsMap.find(input);

        if (it != mInputActionsMap.end())
        {
            it->second.erase(action);
        }
    }
}

template<typename Action, typename Input>
void Bindings<Action,Input>::eraseInputBindings(const Input& input)
{
    /*
     *  Have to cycle through all the input sets to remove the input. A bit expensive but
     *  not a time critical operation...
     */

    mInputActionsMap.erase(input);

    BOOST_FOREACH (typename ActionInputsMap::value_type& pair, mActionInputsMap)
    {
        pair->second.erase(input);
    }
}

template<typename Action, typename Input>
void Bindings<Action,Input>::eraseActionBindings(const Action& action)
{
    mActionInputsMap.erase(action);

    BOOST_FOREACH (typename InputActionsMap::value_type& pair, mInputActionsMap)
    {
        pair->second.erase(action);
    }
}

template<typename Action, typename Input>
void Bindings<Action,Input>::setBinding(const Action& action, const Input& input)
{
    /*
     *  Update input set for action
     */

    {
        typename ActionInputsMap::iterator it = mActionInputsMap.find(action);
        if (it == mActionInputsMap.end())
        {
            InputSet inputSet;
            mActionInputsMap[action] = inputSet;
            it = mActionInputsMap.find(action);
        }
        it->second.insert(input);
    }

    /*
     *  Update action set for input
     */

    {
        typename InputActionsMap::iterator it = mInputActionsMap.find(input);
        if (it == mInputActionsMap.end())
        {
            ActionSet actionSet;
            mInputActionsMap[input] = actionSet;
            it = mInputActionsMap.find(input);
        }
        it->second.insert(action);
    }
}

}

#endif//_VSC_BINDINGS_H_