<commit_before>/**
 *	\file
 */

#pragma once

#include <rleahylib/rleahylib.hpp>
#include <cstdlib>
#include <type_traits>
#include <utility>

namespace MCPP {

	/**
	 *	Specifies an interface to which providers
	 *	that wish to provide data for the MCPP server
	 *	shall conform.
	 *
	 *	Supports the storage of settings (unique keys
	 *	mapped to values), key/value pairs (non-unique
	 *	keys mapped to values), and binary objects (unique
	 *	keys mapped to raw binary data) in addition to
	 *	chat logging and system logging.
	 */
	class DataProvider {

		protected:

			DataProvider () noexcept;

		public:

			/**
			 *	Gets a concrete DataProvider.
			 *
			 *	\return
			 *		A pointer to an object which
			 *		derives from DataProvider.
			 */
			static DataProvider * GetDataProvider ();
			/**
			 *	Maps a Service::LogType to a descriptive
			 *	string.
			 *
			 *	This function is not compiled into the
			 *	MCPP library, it must be compiled into
			 *	the data provider binary.
			 *
			 *	Include \em data_provider.o in your
			 *	data provider compilation.
			 *
			 *	\param [in] type
			 *		The type of event which is being
			 *		logged.
			 *
			 *	\return
			 *		A reference to an immutable string
			 *		which is a human readable label for
			 *		\em type.
			 */
			static const String & GetLogType (Service::LogType type) noexcept;

			DataProvider (const DataProvider &) = delete;
			DataProvider (DataProvider &&) = delete;
			DataProvider & operator = (const DataProvider &) = delete;
			DataProvider & operator = (DataProvider &&) = delete;

			/**
			 *	Destroys an instance of a derived class.
			 */
			virtual ~DataProvider () noexcept;

			/**
			 *	When overriden in a derived class, retrieves
			 *	information about that concrete implementation.
			 *
			 *	The returned value is a tuple, whose members
			 *	are a string (which is the name of the concrete
			 *	implementation) and a collection of key/value
			 *	pairs realized as a vector of 2-tuples containing
			 *	strings.  These key/value pairs contain labels and
			 *	values for pieces of information about the
			 *	concrete implementation.
			 *
			 *	\return
			 *		Information about a concrete implementation of
			 *		this abstract class.
			 */
			virtual Tuple<String,Vector<Tuple<String,String>>> GetInfo () = 0;

			/**
			 *	When overriden in a derived class, writes to
			 *	the log.
			 *
			 *	\param [in] log
			 *		The message to log.
			 *	\param [in] type
			 *		The type of message being logged.
			 */
			virtual void WriteLog (const String & log, Service::LogType type) = 0;
			/**
			 *	When overriden in a derived class, writes to
			 *	the chat log.
			 *
			 *	\param [in] from
			 *		The person sending the message.
			 *	\param [in] to
			 *		A vector of strings representing the
			 *		recipients of the message.  If everyone
			 *		was a recipient of the message (i.e.\ it
			 *		was a broadcast), pass an empty collection.
			 *	\param [in] message
			 *		The body of the message.
			 *	\param [in] notes
			 *		Any notes about this message.
			 */
			virtual void WriteChatLog (const String & from, const Vector<String> & to, const String & message, const Nullable<String> & notes) = 0;

			/**
			 *	When overriden in a derived class, fetches
			 *	binary data from the binary store.
			 *
			 *	\param [in] key
			 *		The key whose associated binary data
			 *		shall be retrieved.
			 *
			 *	\return
			 *		A vector of bytes if there was binary
			 *		data associated with \em key, \em null
			 *		otherwise.
			 */
			virtual Nullable<Vector<Byte>> GetBinary (const String & key) = 0;
			/**
			 *	When overriden in a derived class, fetches
			 *	binary data from the binary store.
			 *
			 *	\param [in] key
			 *		The key whose associated binary data
			 *		shall be retrieved.
			 *	\param [out] ptr
			 *		A pointer to the region of memory where
			 *		the binary data shall be stored.
			 *	\param [in,out] len
			 *		A pointer to the size of the region of
			 *		memory pointed to by \em ptr, in bytes.
			 *		If this call returns \em true this shall
			 *		be updated to the actual length of the
			 *		data associated with \em key in the
			 *		backing store, with all data up to the
			 *		size of the memory pointed to by \em ptr
			 *		retrieved and stored in \em ptr.
			 *
			 *	\return
			 *		\em true if there was data associated with
			 *		\em key in the backing store, \em false
			 *		otherwise.
			 */
			virtual bool GetBinary (const String & key, void * ptr, Word * len) = 0;
			/**
			 *	When overriden in a derived class, saves
			 *	binary data to the binary store.
			 *
			 *	\param [in] key
			 *		The key to which binary data shall
			 *		be saved.
			 *	\param [in] ptr
			 *		A pointer to the region of memory
			 *		which shall be saved.
			 *	\param [in] len
			 *		The length of the memory pointed to
			 *		by \em ptr.
			 */
			virtual void SaveBinary (const String & key, const void * ptr, Word len) = 0;
			/**
			 *	When overriden in a derived class, deletes
			 *	binary data from the binary store.
			 *
			 *	\param [in] key
			 *		The key whose associated binary data
			 *		shall be deleted.
			 */
			virtual void DeleteBinary (const String & key) = 0;

			virtual Nullable<String> RetrieveSetting (const String & setting) = 0;
			/**
			 *	Retrieves the value of a setting converted to
			 *	an arbitrary type.
			 *
			 *	\param [in] setting
			 *		The name of the setting to retrieve.
			 *
			 *	\return
			 *		The value of \em setting.  Will be null
			 *		if the setting does not exist, or if the
			 *		backing store supports storing null values
			 *		and the value is null.
			 */
			template <typename T=String>
			Nullable<T> GetSetting (const String & setting);
			/**
			 *	Retrieves the value of a setting converted
			 *	to an arbitrary type.
			 *
			 *	\tparam T
			 *		The type as which to retrieve the setting.
			 *
			 *	\param [in] setting
			 *		The name of the setting to retrieve.
			 *
			 *	\return
			 *		The value of \em setting, or \em default_value
			 *		if the value of \em setting does not exist, or
			 *		could not be converted to a \em T.
			 */
			template <typename T>
			T GetSetting (const String & setting, T default_value);
			/**
			 *	When overriden in a derived class, sets the
			 *	value of a setting.
			 *
			 *	\param [in] setting
			 *		The name of the setting whose value shall
			 *		be set.
			 *	\param [in] value
			 *		The value to set the setting to.
			 */
			virtual void SetSetting (const String & setting, const Nullable<String> & value) = 0;
			/**
			 *	When overriden in a derived class, deletes the
			 *	value of a setting.
			 *
			 *	\param [in] setting
			 *		The name of the setting whose value shall
			 *		be deleted.
			 */
			virtual void DeleteSetting (const String & setting) = 0;

			/**
			 *	When overriden in a derived class, inserts a
			 *	new pair into the key/value pair store.
			 *
			 *	\param [in] key
			 *		The key of the key/value pair to insert.
			 *	\param [in] value
			 *		The value of the key/value pair to insert.
			 */
			virtual void InsertValue (const String & key, const String & value) = 0;
			/**
			 *	When overriden in a derived class, deletes
			 *	pairs from the key/value store which have
			 *	a particular key and a particular value.
			 *
			 *	\param [in] key
			 *		The key which a key/value pair shall have
			 *		to qualify for deletion.
			 *	\param [in] value
			 *		The value which a key/value pair shall have
			 *		to qualify for deletion.
			 */
			virtual void DeleteValues (const String & key, const String & value) = 0;
			/**
			 *	When overriden in a derived class, deletes
			 *	all pairs from the key/value store which have
			 *	a particular key.
			 *
			 *	\param [in] key
			 *		The key which a key/value pair shall have
			 *		to qualify for deletion.
			 */
			virtual void DeleteValues (const String & key) = 0;
			/**
			 *	When overriden in a derived class, retrieves
			 *	all values associated with a given key from
			 *	the key/value store.
			 *
			 *	\param [in] key
			 *		The key whose associated values shall be
			 *		retrieved.
			 *
			 *	\return
			 *		A vector of strings containing the values
			 *		associated with \em key in the backing
			 *		store.
			 */
			virtual Vector<String> GetValues (const String & key) = 0;

	};

	template <typename T, typename=void>
	class SettingConverter {

		public:

			static Nullable<T> Get (String value) {

				return Nullable<T>();

			}

	};

	/**
	 *	\cond
	 */

	template <>
	class SettingConverter<String,void> {

		public:

			static Nullable<String> Get (String value) {

				return Nullable<String>(std::move(value));

			}

	};

	template <typename T>
	class SettingConverter<T,typename std::enable_if<std::is_integral<T>::value && !std::is_same<T,bool>::value>::type> {

		public:

			static Nullable<T> Get (String value) {

				Nullable<T> retr;

				T val;
				if (value.ToInteger(&val)) retr.Construct(val);

				return retr;

			}

	};

	template <typename T>
	class SettingConverter<T,typename std::enable_if<std::is_floating_point<T>::value>::type> {

		public:

			static Nullable<T> Get (String value) {

				Nullable<T> retr;

				auto c_str=value.ToCString();
				auto end_ptr=c_str.begin();
				T val=(
					std::is_same<T,Single>::value
						?	static_cast<T>(strtof(end_ptr,&end_ptr))
						:	(
								std::is_same<T,Double>::value
									?	static_cast<T>(strtod(end_ptr,&end_ptr))
									:	static_cast<T>(strtold(end_ptr,&end_ptr))
							)
				);

				if (end_ptr!=c_str.begin()) retr.Construct(val);

				return retr;

			}

	};

	template <>
	class SettingConverter<bool,void> {

		public:

			static bool Get (String value) {

				Nullable<bool> retr;

				if (Regex(
					"^\\s*(?:t(?:rue)?|y(?:es)?)\\s*$",
					RegexOptions().SetIgnoreCase()
				).IsMatch(value)) retr.Construct(true);
				else if (Regex(
					"^\\s*(?:no?|f(?:alse)?)\\s*$",
					RegexOptions().SetIgnoreCase()
				).IsMatch(value)) retr.Construct(false);

				return retr;

			}

	};

	template <typename T>
	Nullable<T> DataProvider::GetSetting (const String & setting) {

		auto value=RetrieveSetting(setting);

		return value.IsNull() ? Nullable<T>() : SettingConverter<typename std::decay<T>::type>::Get(
			std::move(*value)
		);

	}

	template <typename T>
	T DataProvider::GetSetting (const String & setting, T default_value) {

		auto value=GetSetting<T>(setting);

		return value.IsNull() ? default_value : std::move(*value);

	}

	/**
	 *	\endcond
	 */

}
<commit_msg>Data Provider Fix<commit_after>/**
 *	\file
 */

#pragma once

#include <rleahylib/rleahylib.hpp>
#include <cstdlib>
#include <type_traits>
#include <utility>

namespace MCPP {

	/**
	 *	Specifies an interface to which providers
	 *	that wish to provide data for the MCPP server
	 *	shall conform.
	 *
	 *	Supports the storage of settings (unique keys
	 *	mapped to values), key/value pairs (non-unique
	 *	keys mapped to values), and binary objects (unique
	 *	keys mapped to raw binary data) in addition to
	 *	chat logging and system logging.
	 */
	class DataProvider {

		protected:

			DataProvider () noexcept;

		public:

			/**
			 *	Gets a concrete DataProvider.
			 *
			 *	\return
			 *		A pointer to an object which
			 *		derives from DataProvider.
			 */
			static DataProvider * GetDataProvider ();
			/**
			 *	Maps a Service::LogType to a descriptive
			 *	string.
			 *
			 *	This function is not compiled into the
			 *	MCPP library, it must be compiled into
			 *	the data provider binary.
			 *
			 *	Include \em data_provider.o in your
			 *	data provider compilation.
			 *
			 *	\param [in] type
			 *		The type of event which is being
			 *		logged.
			 *
			 *	\return
			 *		A reference to an immutable string
			 *		which is a human readable label for
			 *		\em type.
			 */
			static const String & GetLogType (Service::LogType type) noexcept;

			DataProvider (const DataProvider &) = delete;
			DataProvider (DataProvider &&) = delete;
			DataProvider & operator = (const DataProvider &) = delete;
			DataProvider & operator = (DataProvider &&) = delete;

			/**
			 *	Destroys an instance of a derived class.
			 */
			virtual ~DataProvider () noexcept;

			/**
			 *	When overriden in a derived class, retrieves
			 *	information about that concrete implementation.
			 *
			 *	The returned value is a tuple, whose members
			 *	are a string (which is the name of the concrete
			 *	implementation) and a collection of key/value
			 *	pairs realized as a vector of 2-tuples containing
			 *	strings.  These key/value pairs contain labels and
			 *	values for pieces of information about the
			 *	concrete implementation.
			 *
			 *	\return
			 *		Information about a concrete implementation of
			 *		this abstract class.
			 */
			virtual Tuple<String,Vector<Tuple<String,String>>> GetInfo () = 0;

			/**
			 *	When overriden in a derived class, writes to
			 *	the log.
			 *
			 *	\param [in] log
			 *		The message to log.
			 *	\param [in] type
			 *		The type of message being logged.
			 */
			virtual void WriteLog (const String & log, Service::LogType type) = 0;
			/**
			 *	When overriden in a derived class, writes to
			 *	the chat log.
			 *
			 *	\param [in] from
			 *		The person sending the message.
			 *	\param [in] to
			 *		A vector of strings representing the
			 *		recipients of the message.  If everyone
			 *		was a recipient of the message (i.e.\ it
			 *		was a broadcast), pass an empty collection.
			 *	\param [in] message
			 *		The body of the message.
			 *	\param [in] notes
			 *		Any notes about this message.
			 */
			virtual void WriteChatLog (const String & from, const Vector<String> & to, const String & message, const Nullable<String> & notes) = 0;

			/**
			 *	When overriden in a derived class, fetches
			 *	binary data from the binary store.
			 *
			 *	\param [in] key
			 *		The key whose associated binary data
			 *		shall be retrieved.
			 *
			 *	\return
			 *		A vector of bytes if there was binary
			 *		data associated with \em key, \em null
			 *		otherwise.
			 */
			virtual Nullable<Vector<Byte>> GetBinary (const String & key) = 0;
			/**
			 *	When overriden in a derived class, fetches
			 *	binary data from the binary store.
			 *
			 *	\param [in] key
			 *		The key whose associated binary data
			 *		shall be retrieved.
			 *	\param [out] ptr
			 *		A pointer to the region of memory where
			 *		the binary data shall be stored.
			 *	\param [in,out] len
			 *		A pointer to the size of the region of
			 *		memory pointed to by \em ptr, in bytes.
			 *		If this call returns \em true this shall
			 *		be updated to the actual length of the
			 *		data associated with \em key in the
			 *		backing store, with all data up to the
			 *		size of the memory pointed to by \em ptr
			 *		retrieved and stored in \em ptr.
			 *
			 *	\return
			 *		\em true if there was data associated with
			 *		\em key in the backing store, \em false
			 *		otherwise.
			 */
			virtual bool GetBinary (const String & key, void * ptr, Word * len) = 0;
			/**
			 *	When overriden in a derived class, saves
			 *	binary data to the binary store.
			 *
			 *	\param [in] key
			 *		The key to which binary data shall
			 *		be saved.
			 *	\param [in] ptr
			 *		A pointer to the region of memory
			 *		which shall be saved.
			 *	\param [in] len
			 *		The length of the memory pointed to
			 *		by \em ptr.
			 */
			virtual void SaveBinary (const String & key, const void * ptr, Word len) = 0;
			/**
			 *	When overriden in a derived class, deletes
			 *	binary data from the binary store.
			 *
			 *	\param [in] key
			 *		The key whose associated binary data
			 *		shall be deleted.
			 */
			virtual void DeleteBinary (const String & key) = 0;

			virtual Nullable<String> RetrieveSetting (const String & setting) = 0;
			/**
			 *	Retrieves the value of a setting converted to
			 *	an arbitrary type.
			 *
			 *	\param [in] setting
			 *		The name of the setting to retrieve.
			 *
			 *	\return
			 *		The value of \em setting.  Will be null
			 *		if the setting does not exist, or if the
			 *		backing store supports storing null values
			 *		and the value is null.
			 */
			template <typename T=String>
			Nullable<T> GetSetting (const String & setting);
			/**
			 *	Retrieves the value of a setting converted
			 *	to an arbitrary type.
			 *
			 *	\tparam T
			 *		The type as which to retrieve the setting.
			 *
			 *	\param [in] setting
			 *		The name of the setting to retrieve.
			 *
			 *	\return
			 *		The value of \em setting, or \em default_value
			 *		if the value of \em setting does not exist, or
			 *		could not be converted to a \em T.
			 */
			template <typename T>
			T GetSetting (const String & setting, T default_value);
			/**
			 *	When overriden in a derived class, sets the
			 *	value of a setting.
			 *
			 *	\param [in] setting
			 *		The name of the setting whose value shall
			 *		be set.
			 *	\param [in] value
			 *		The value to set the setting to.
			 */
			virtual void SetSetting (const String & setting, const Nullable<String> & value) = 0;
			/**
			 *	When overriden in a derived class, deletes the
			 *	value of a setting.
			 *
			 *	\param [in] setting
			 *		The name of the setting whose value shall
			 *		be deleted.
			 */
			virtual void DeleteSetting (const String & setting) = 0;

			/**
			 *	When overriden in a derived class, inserts a
			 *	new pair into the key/value pair store.
			 *
			 *	\param [in] key
			 *		The key of the key/value pair to insert.
			 *	\param [in] value
			 *		The value of the key/value pair to insert.
			 */
			virtual void InsertValue (const String & key, const String & value) = 0;
			/**
			 *	When overriden in a derived class, deletes
			 *	pairs from the key/value store which have
			 *	a particular key and a particular value.
			 *
			 *	\param [in] key
			 *		The key which a key/value pair shall have
			 *		to qualify for deletion.
			 *	\param [in] value
			 *		The value which a key/value pair shall have
			 *		to qualify for deletion.
			 */
			virtual void DeleteValues (const String & key, const String & value) = 0;
			/**
			 *	When overriden in a derived class, deletes
			 *	all pairs from the key/value store which have
			 *	a particular key.
			 *
			 *	\param [in] key
			 *		The key which a key/value pair shall have
			 *		to qualify for deletion.
			 */
			virtual void DeleteValues (const String & key) = 0;
			/**
			 *	When overriden in a derived class, retrieves
			 *	all values associated with a given key from
			 *	the key/value store.
			 *
			 *	\param [in] key
			 *		The key whose associated values shall be
			 *		retrieved.
			 *
			 *	\return
			 *		A vector of strings containing the values
			 *		associated with \em key in the backing
			 *		store.
			 */
			virtual Vector<String> GetValues (const String & key) = 0;

	};

	template <typename T, typename=void>
	class SettingConverter {

		public:

			static Nullable<T> Get (String value) {

				return Nullable<T>();

			}

	};

	/**
	 *	\cond
	 */

	template <>
	class SettingConverter<String,void> {

		public:

			static Nullable<String> Get (String value) {

				return Nullable<String>(std::move(value));

			}

	};

	template <typename T>
	class SettingConverter<T,typename std::enable_if<std::is_integral<T>::value && !std::is_same<T,bool>::value>::type> {

		public:

			static Nullable<T> Get (String value) {

				Nullable<T> retr;

				T val;
				if (value.ToInteger(&val)) retr.Construct(val);

				return retr;

			}

	};

	template <typename T>
	class SettingConverter<T,typename std::enable_if<std::is_floating_point<T>::value>::type> {

		public:

			static Nullable<T> Get (String value) {

				Nullable<T> retr;

				auto c_str=value.ToCString();
				auto end_ptr=c_str.begin();
				T val=(
					std::is_same<T,Single>::value
						?	static_cast<T>(strtof(end_ptr,&end_ptr))
						:	(
								std::is_same<T,Double>::value
									?	static_cast<T>(strtod(end_ptr,&end_ptr))
									:	static_cast<T>(strtold(end_ptr,&end_ptr))
							)
				);

				if (end_ptr!=c_str.begin()) retr.Construct(val);

				return retr;

			}

	};

	template <>
	class SettingConverter<bool,void> {

		public:

			static Nullable<bool> Get (String value) {

				Nullable<bool> retr;

				if (Regex(
					"^\\s*(?:t(?:rue)?|y(?:es)?)\\s*$",
					RegexOptions().SetIgnoreCase()
				).IsMatch(value)) retr.Construct(true);
				else if (Regex(
					"^\\s*(?:no?|f(?:alse)?)\\s*$",
					RegexOptions().SetIgnoreCase()
				).IsMatch(value)) retr.Construct(false);

				return retr;

			}

	};

	template <typename T>
	Nullable<T> DataProvider::GetSetting (const String & setting) {

		auto value=RetrieveSetting(setting);

		return value.IsNull() ? Nullable<T>() : SettingConverter<typename std::decay<T>::type>::Get(
			std::move(*value)
		);

	}

	template <typename T>
	T DataProvider::GetSetting (const String & setting, T default_value) {

		auto value=GetSetting<T>(setting);

		return value.IsNull() ? default_value : std::move(*value);

	}

	/**
	 *	\endcond
	 */

}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include "neural_base.hpp"

namespace dll {

template <typename Desc>
struct lcn_layer : neural_base<lcn_layer<Desc>> {
    using desc = Desc;

    static constexpr const std::size_t K = desc::K;

    double sigma = 2.0;

    static_assert(K > 1, "The kernel size must be greater than 1");
    static_assert(K % 2 == 1, "The kernel size must be odd");

    lcn_layer() = default;

    static std::string to_short_string() {
        std::string desc("LCN: ");
        desc += std::to_string(K) + 'x' + std::to_string(K);
        return desc;
    }

    static void display() {
        std::cout << to_short_string() << std::endl;
    }

    static cpp14_constexpr double gaussian(double x, double y, double sigma) {
        auto Z = 2.0 * M_PI * sigma * sigma;
        return 1.0 / Z * std::exp(-(x * x + y * y) / (2.0 * sigma * sigma));
    }

    template <typename W>
    static etl::fast_dyn_matrix<W, K, K> filter(double sigma) {
        etl::fast_dyn_matrix<W, K, K> w;

        for (std::size_t i = 0; i < K; ++i) {
            for (std::size_t j = 0; j < K; ++j) {
                w(i, j) = gaussian(i, j, sigma);
            }
        }

        w /= etl::sum(w);

        return w;
    }

    template <typename Input, typename Output>
    void activate_hidden(Output& y, const Input& x) const {
        using weight_t = etl::value_t<Input>;

        auto w = filter<weight_t>(sigma);

        auto v = etl::force_temporary(x(0));
        auto o = etl::force_temporary(x(0));

        for (std::size_t c = 0; c < etl::dim<0>(x); ++c) {
            //1. For each pixel, remove mean of 9x9 neighborhood
            for (std::size_t j = 0; j < etl::dim<1>(x); ++j) {
                for (std::size_t k = 0; k < etl::dim<2>(x); ++k) {
                    weight_t sum(0.0);

                    for (std::size_t p = 0; p < K; ++p) {
                        if (j + p >= 0 && j + p < etl::dim<1>(x)) {
                            for (std::size_t q = 0; q < K; ++q) {
                                if (k + q >= 0 && k + q < etl::dim<2>(x)) {
                                    sum += w(p, q) * x(c, j + p, k + q);
                                }
                            }
                        }
                    }

                    v(j, k) = x(c, j, k) - sum;
                }
            }

            //2. Scale down norm of 9x9 patch if norm is bigger than 1

            for (std::size_t j = 0; j < etl::dim<1>(x); ++j) {
                for (std::size_t k = 0; k < etl::dim<2>(x); ++k) {
                    weight_t sum(0.0);

                    for (std::size_t p = 0; p < K; ++p) {
                        if (j + p >= 0 && j + p < etl::dim<1>(x)) {
                            for (std::size_t q = 0; q < K; ++q) {
                                if (k + q >= 0 && k + q < etl::dim<2>(x)) {
                                    sum += w(p, q) * x(c, j + p, k + q) * x(c, j + p, k + q);
                                }
                            }
                        }
                    }

                    o(j, k) = std::sqrt(sum);
                }
            }

            auto cst = etl::mean(o);
            y(c) = v / etl::max(o, cst);
        }
    }

    template <typename Input, typename Output>
    void batch_activate_hidden(Output& output, const Input& input) const {
        for (std::size_t b = 0; b < etl::dim<0>(input); ++b) {
            activate_hidden(output(b), input(b));
        }
    }

    template <typename I, typename O_A>
    void activate_many(const I& input, O_A& h_a) const {
        for (std::size_t i = 0; i < input.size(); ++i) {
            activate_one(input[i], h_a[i]);
        }
    }

    template <typename Input>
    static std::vector<Input> prepare_output(std::size_t samples) {
        return std::vector<Input>(samples);
    }

    template <typename Input>
    static Input prepare_one_output() {
        return {};
    }
};

} //end of dll namespace
<commit_msg>Review lcn<commit_after>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include "neural_base.hpp"

namespace dll {

template <typename Desc>
struct lcn_layer : neural_base<lcn_layer<Desc>> {
    using desc = Desc;

    static constexpr const std::size_t K = desc::K;
    static constexpr const std::size_t Mid = K / 2;

    double sigma = 2.0;

    static_assert(K > 1, "The kernel size must be greater than 1");
    static_assert(K % 2 == 1, "The kernel size must be odd");

    lcn_layer() = default;

    static std::string to_short_string() {
        std::string desc("LCN: ");
        desc += std::to_string(K) + 'x' + std::to_string(K);
        return desc;
    }

    static void display() {
        std::cout << to_short_string() << std::endl;
    }

    static cpp14_constexpr double gaussian(double x, double y, double sigma) {
        auto Z = 2.0 * M_PI * sigma * sigma;
        return (1.0 / Z) * std::exp(-((x * x + y * y) / (2.0 * sigma * sigma)));
    }

    template <typename W>
    static etl::fast_dyn_matrix<W, K, K> filter(double sigma) {
        etl::fast_dyn_matrix<W, K, K> w;

        for (std::size_t i = 0; i < K; ++i) {
            for (std::size_t j = 0; j < K; ++j) {
                w(i, j) = gaussian(double(i) - Mid, double(j) - Mid, sigma);
            }
        }

        w /= etl::sum(w);

        return w;
    }

    template <typename Input, typename Output>
    void activate_hidden(Output& y, const Input& x) const {
        using weight_t = etl::value_t<Input>;

        auto w = filter<weight_t>(sigma);

        auto v = etl::force_temporary(x(0));
        auto o = etl::force_temporary(x(0));

        for (std::size_t c = 0; c < etl::dim<0>(x); ++c) {
            //1. For each pixel, remove mean of 9x9 neighborhood
            for (std::size_t j = 0; j < etl::dim<1>(x); ++j) {
                for (std::size_t k = 0; k < etl::dim<2>(x); ++k) {
                    weight_t sum(0.0);

                    for (std::size_t p = 0; p < K; ++p) {
                        if (long(j) + p - Mid >= 0 && long(j) + p - Mid < etl::dim<1>(x)) {
                            for (std::size_t q = 0; q < K; ++q) {
                                if (long(k) + q - Mid >= 0 && long(k) + q - Mid < etl::dim<2>(x)) {
                                    sum += w(p, q) * x(c, j + p - Mid, k + q - Mid);
                                }
                            }
                        }
                    }

                    v(j, k) = x(c, j, k) - sum;
                }
            }

            //2. Scale down norm of 9x9 patch if norm is bigger than 1

            for (std::size_t j = 0; j < etl::dim<1>(x); ++j) {
                for (std::size_t k = 0; k < etl::dim<2>(x); ++k) {
                    weight_t sum(0.0);

                    for (std::size_t p = 0; p < K; ++p) {
                        if (long(j) + p - Mid >= 0 && long(j) + p - Mid < etl::dim<1>(x)) {
                            for (std::size_t q = 0; q < K; ++q) {
                                if (long(k) + q - Mid >= 0 && long(k) + q - Mid < etl::dim<2>(x)) {
                                    sum += w(p, q) * x(c, j + p - Mid, k + q - Mid) * x(c, j + p - Mid, k + q - Mid);
                                }
                            }
                        }
                    }

                    o(j, k) = std::sqrt(sum);
                }
            }

            auto cst = etl::mean(o);
            y(c) = v / etl::max(o, cst);
        }
    }

    template <typename Input, typename Output>
    void batch_activate_hidden(Output& output, const Input& input) const {
        for (std::size_t b = 0; b < etl::dim<0>(input); ++b) {
            activate_hidden(output(b), input(b));
        }
    }

    template <typename I, typename O_A>
    void activate_many(const I& input, O_A& h_a) const {
        for (std::size_t i = 0; i < input.size(); ++i) {
            activate_one(input[i], h_a[i]);
        }
    }

    template <typename Input>
    static std::vector<Input> prepare_output(std::size_t samples) {
        return std::vector<Input>(samples);
    }

    template <typename Input>
    static Input prepare_one_output() {
        return {};
    }
};

} //end of dll namespace
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include "neural_base.hpp"

namespace dll {

template <typename Desc>
struct lcn_layer : neural_base<lcn_layer<Desc>> {
    using desc = Desc;

    static constexpr const std::size_t K = desc::K;

    //TODO We can probably remove this completely
    static constexpr const std::size_t Mid = 0;

    double sigma = 2.0;

    static_assert(K > 1, "The kernel size must be greater than 1");
    static_assert(K % 2 == 1, "The kernel size must be odd");

    lcn_layer() = default;

    static std::string to_short_string() {
        std::string desc("LCN: ");
        desc += std::to_string(K) + 'x' + std::to_string(K);
        return desc;
    }

    static void display() {
        std::cout << to_short_string() << std::endl;
    }

    static cpp14_constexpr double gaussian(double x, double y, double sigma) {
        auto Z = 2.0 * M_PI * sigma * sigma;
        return 1.0 / Z * std::exp(-(x * x + y * y) / (2.0 * sigma * sigma));
    }

    template <typename W>
    static etl::fast_dyn_matrix<W, K, K> filter(double sigma) {
        etl::fast_dyn_matrix<W, K, K> w;

        for (std::size_t i = 0; i < K; ++i) {
            for (std::size_t j = 0; j < K; ++j) {
                w(i, j) = gaussian(static_cast<double>(i) - Mid, static_cast<double>(j) - Mid, sigma);
            }
        }

        w /= etl::sum(w);

        return w;
    }

    template <typename Input, typename Output>
    void activate_hidden(Output& y, const Input& x) const {
        using weight_t = etl::value_t<Input>;

        auto w = filter<weight_t>(sigma);

        auto v = etl::force_temporary(x(0));
        auto o = etl::force_temporary(x(0));

        for (std::size_t c = 0; c < etl::dim<0>(x); ++c) {
            //1. For each pixel, remove mean of 9x9 neighborhood
            for (std::size_t j = 0; j < etl::dim<1>(x); ++j) {
                for (std::size_t k = 0; k < etl::dim<2>(x); ++k) {
                    weight_t sum(0.0);

                    for (std::size_t p = 0; p < K; ++p) {
                        if (j + p >= Mid && j + p - Mid < etl::dim<1>(x)) {
                            for (std::size_t q = 0; q < K; ++q) {
                                if (k + q >= Mid && k + q - Mid < etl::dim<2>(x)) {
                                    sum += w(p, q) * x(c, j + p - Mid, k + q - Mid);
                                }
                            }
                        }
                    }

                    v(j, k) = x(c, j, k) - sum;
                }
            }

            //2. Scale down norm of 9x9 patch if norm is bigger than 1

            for (std::size_t j = 0; j < etl::dim<1>(x); ++j) {
                for (std::size_t k = 0; k < etl::dim<2>(x); ++k) {
                    weight_t sum(0.0);

                    for (std::size_t p = 0; p < K; ++p) {
                        if (j + p >= Mid && j + p - Mid < etl::dim<1>(x)) {
                            for (std::size_t q = 0; q < K; ++q) {
                                if (k + q >= Mid && k + q - Mid < etl::dim<2>(x)) {
                                    sum += w(p, q) * x(c, j + p - Mid, k + q - Mid) * x(c, j + p - Mid, k + q - Mid);
                                }
                            }
                        }
                    }

                    o(j, k) = std::sqrt(sum);
                }
            }

            auto cst = etl::mean(o);
            y(c) = v / etl::max(o, cst);
        }
    }

    template <typename Input, typename Output>
    void batch_activate_hidden(Output& output, const Input& input) const {
        for (std::size_t b = 0; b < etl::dim<0>(input); ++b) {
            activate_hidden(output(b), input(b));
        }
    }

    template <typename I, typename O_A>
    void activate_many(const I& input, O_A& h_a) const {
        for (std::size_t i = 0; i < input.size(); ++i) {
            activate_one(input[i], h_a[i]);
        }
    }

    template <typename Input>
    static std::vector<Input> prepare_output(std::size_t samples) {
        return std::vector<Input>(samples);
    }

    template <typename Input>
    static Input prepare_one_output() {
        return {};
    }
};

} //end of dll namespace
<commit_msg>Cleanup<commit_after>//=======================================================================
// Copyright (c) 2014-2016 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#pragma once

#include "neural_base.hpp"

namespace dll {

template <typename Desc>
struct lcn_layer : neural_base<lcn_layer<Desc>> {
    using desc = Desc;

    static constexpr const std::size_t K = desc::K;

    double sigma = 2.0;

    static_assert(K > 1, "The kernel size must be greater than 1");
    static_assert(K % 2 == 1, "The kernel size must be odd");

    lcn_layer() = default;

    static std::string to_short_string() {
        std::string desc("LCN: ");
        desc += std::to_string(K) + 'x' + std::to_string(K);
        return desc;
    }

    static void display() {
        std::cout << to_short_string() << std::endl;
    }

    static cpp14_constexpr double gaussian(double x, double y, double sigma) {
        auto Z = 2.0 * M_PI * sigma * sigma;
        return 1.0 / Z * std::exp(-(x * x + y * y) / (2.0 * sigma * sigma));
    }

    template <typename W>
    static etl::fast_dyn_matrix<W, K, K> filter(double sigma) {
        etl::fast_dyn_matrix<W, K, K> w;

        for (std::size_t i = 0; i < K; ++i) {
            for (std::size_t j = 0; j < K; ++j) {
                w(i, j) = gaussian(i, j, sigma);
            }
        }

        w /= etl::sum(w);

        return w;
    }

    template <typename Input, typename Output>
    void activate_hidden(Output& y, const Input& x) const {
        using weight_t = etl::value_t<Input>;

        auto w = filter<weight_t>(sigma);

        auto v = etl::force_temporary(x(0));
        auto o = etl::force_temporary(x(0));

        for (std::size_t c = 0; c < etl::dim<0>(x); ++c) {
            //1. For each pixel, remove mean of 9x9 neighborhood
            for (std::size_t j = 0; j < etl::dim<1>(x); ++j) {
                for (std::size_t k = 0; k < etl::dim<2>(x); ++k) {
                    weight_t sum(0.0);

                    for (std::size_t p = 0; p < K; ++p) {
                        if (j + p >= 0 && j + p < etl::dim<1>(x)) {
                            for (std::size_t q = 0; q < K; ++q) {
                                if (k + q >= 0 && k + q < etl::dim<2>(x)) {
                                    sum += w(p, q) * x(c, j + p, k + q);
                                }
                            }
                        }
                    }

                    v(j, k) = x(c, j, k) - sum;
                }
            }

            //2. Scale down norm of 9x9 patch if norm is bigger than 1

            for (std::size_t j = 0; j < etl::dim<1>(x); ++j) {
                for (std::size_t k = 0; k < etl::dim<2>(x); ++k) {
                    weight_t sum(0.0);

                    for (std::size_t p = 0; p < K; ++p) {
                        if (j + p >= 0 && j + p < etl::dim<1>(x)) {
                            for (std::size_t q = 0; q < K; ++q) {
                                if (k + q >= 0 && k + q < etl::dim<2>(x)) {
                                    sum += w(p, q) * x(c, j + p, k + q) * x(c, j + p, k + q);
                                }
                            }
                        }
                    }

                    o(j, k) = std::sqrt(sum);
                }
            }

            auto cst = etl::mean(o);
            y(c) = v / etl::max(o, cst);
        }
    }

    template <typename Input, typename Output>
    void batch_activate_hidden(Output& output, const Input& input) const {
        for (std::size_t b = 0; b < etl::dim<0>(input); ++b) {
            activate_hidden(output(b), input(b));
        }
    }

    template <typename I, typename O_A>
    void activate_many(const I& input, O_A& h_a) const {
        for (std::size_t i = 0; i < input.size(); ++i) {
            activate_one(input[i], h_a[i]);
        }
    }

    template <typename Input>
    static std::vector<Input> prepare_output(std::size_t samples) {
        return std::vector<Input>(samples);
    }

    template <typename Input>
    static Input prepare_one_output() {
        return {};
    }
};

} //end of dll namespace
<|endoftext|>


<commit_before>#ifndef GLHPP_FORMATS_HPP
#define GLHPP_FORMATS_HPP

namespace gl
{
namespace impl
{

	template<class I>
	struct ClientToGLType
	{
		static GLenum value;
	};

#ifndef GL_INT64_ARB
	#define GL_INT64_ARB 0x140E
#endif

#ifndef GL_UNSIGNED_INT64_ARB
	#define GL_UNSIGNED_INT64_ARB 0x140F
#endif

	template<> GLenum ClientToGLType<GLbyte>::value=GL_BYTE;
	template<> GLenum ClientToGLType<GLubyte>::value=GL_UNSIGNED_BYTE;
	template<> GLenum ClientToGLType<GLshort>::value=GL_SHORT;
	template<> GLenum ClientToGLType<GLushort>::value=GL_UNSIGNED_SHORT;
	template<> GLenum ClientToGLType<GLint>::value=GL_INT;
	template<> GLenum ClientToGLType<GLuint>::value=GL_UNSIGNED_INT;
	template<> GLenum ClientToGLType<GLint64>::value=GL_INT64_ARB;
	template<> GLenum ClientToGLType<GLuint64>::value=GL_UNSIGNED_INT64_ARB;
	//template<> GLenum ClientToGLType<GLhalf>::value=GL_HALF_FLOAT;
	template<> GLenum ClientToGLType<GLfloat>::value=GL_FLOAT;
	template<> GLenum ClientToGLType<GLdouble>::value=GL_DOUBLE;

	template<unsigned int l>
	struct ClientToChannelsFormat
	{
		static GLenum value;
	};
	template<> GLenum ClientToChannelsFormat<1>::value=GL_RED;
	template<> GLenum ClientToChannelsFormat<2>::value=GL_RG;
	template<> GLenum ClientToChannelsFormat<3>::value=GL_RGB;
	template<> GLenum ClientToChannelsFormat<4>::value=GL_RGBA;

	inline unsigned int FormatToChannels(GLenum format)
	{
		switch(format)
		{
			case GL_STENCIL_INDEX:
			case GL_DEPTH_COMPONENT:
			case GL_RED:
			case GL_GREEN:
			case GL_BLUE:
			case GL_RED_INTEGER:
			case GL_GREEN_INTEGER:
			case GL_BLUE_INTEGER:
				return 1;

			case GL_DEPTH_STENCIL:
			case GL_RG:
			case GL_RG_INTEGER:
				return 2;
			case GL_RGB:
			case GL_BGR:
			case GL_RGB_INTEGER:
			case GL_BGR_INTEGER:
				return 3;
			case GL_RGBA_INTEGER:
			case GL_BGRA_INTEGER:
			case GL_BGRA:
			case GL_RGBA:
				return 4;
		};
		return 0; //TODO not recognized?
	}
	inline bool TypeIsBasic(GLenum type)
	{
		switch(type)
		{
			case GL_BYTE:
			case GL_UNSIGNED_BYTE:
			case GL_SHORT:
			case GL_UNSIGNED_SHORT:
			case GL_INT:
			case GL_UNSIGNED_INT:
			case GL_INT64_ARB:
			case GL_UNSIGNED_INT64_ARB:
			case GL_HALF_FLOAT:
			case GL_FLOAT:
			case GL_DOUBLE:
				return true;
			default:
				return false;
		};
	}
	inline size_t ElementSize(GLenum format,GLenum type)
	{
		size_t out;
		switch(type)
		{
			case GL_UNSIGNED_BYTE:
			case GL_BYTE:
				out=1;break;
			case GL_UNSIGNED_SHORT:
			case GL_SHORT:
			case GL_HALF_FLOAT:
				out=2;break;
			case GL_UNSIGNED_INT:
			case GL_INT:
			case GL_FLOAT:
				out=4;break;
			case GL_INT64_ARB:
			case GL_UNSIGNED_INT64_ARB:
			case GL_DOUBLE:
				out=8;break;
			case GL_UNSIGNED_BYTE_3_3_2:			return 1;
			case GL_UNSIGNED_BYTE_2_3_3_REV:		return 1;
			case GL_UNSIGNED_SHORT_5_6_5:			return 2;
			case GL_UNSIGNED_SHORT_5_6_5_REV:		return 2;
			case GL_UNSIGNED_SHORT_4_4_4_4:			return 2;
			case GL_UNSIGNED_SHORT_4_4_4_4_REV:		return 2;
			case GL_UNSIGNED_SHORT_5_5_5_1:			return 2;
			case GL_UNSIGNED_SHORT_1_5_5_5_REV:		return 2;
			case GL_UNSIGNED_INT_8_8_8_8:			return 4;
			case GL_UNSIGNED_INT_8_8_8_8_REV:		return 4;
			case GL_UNSIGNED_INT_10_10_10_2:		return 4;
			case GL_UNSIGNED_INT_2_10_10_10_REV:	return 4;
			case GL_UNSIGNED_INT_24_8:				return 4;
			case GL_UNSIGNED_INT_10F_11F_11F_REV:	return 4;
			case GL_UNSIGNED_INT_5_9_9_9_REV:		return 4;
			case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:	return 8;
			default:
				return 0;
		};
		return out*FormatToChannels(format);
	}
}
}

#endif
<commit_msg>Stuff<commit_after>#ifndef GLHPP_FORMATS_HPP
#define GLHPP_FORMATS_HPP

namespace gl
{
namespace impl
{

	template<class I>
	struct ClientToGLType;

#ifndef GL_INT64_ARB
	#define GL_INT64_ARB 0x140E
#endif

#ifndef GL_UNSIGNED_INT64_ARB
	#define GL_UNSIGNED_INT64_ARB 0x140F
#endif

	template<> struct ClientToGLType<GLbyte> { static constexpr GLenum value=GL_BYTE; };
	template<> struct ClientToGLType<GLubyte> { static constexpr GLenum value=GL_UNSIGNED_BYTE; };
	template<> struct ClientToGLType<GLshort> { static constexpr GLenum value=GL_SHORT; };
	template<> struct ClientToGLType<GLushort> { static constexpr GLenum value=GL_UNSIGNED_SHORT; };
	template<> struct ClientToGLType<GLint> { static constexpr GLenum value=GL_INT; };
	template<> struct ClientToGLType<GLuint> { static constexpr GLenum value=GL_UNSIGNED_INT; };
	template<> struct ClientToGLType<GLfloat> { static constexpr GLenum value=GL_FLOAT; };
	template<> struct ClientToGLType<GLdouble> { static constexpr GLenum value=GL_DOUBLE; };

#ifdef GL_INT64_ARB
	template<> struct ClientToGLType<GLint64> { static constexpr GLenum value=GL_INT64_ARB; };
#endif
#ifdef GL_UNSIGNED_INT64_ARB
	template<> struct ClientToGLType<GLuint64> { static constexpr GLenum value=GL_UNSIGNED_INT64_ARB; };
#endif
#ifdef GL_HALF_FLOAT
	//template<> struct ClientToGLType<GLhalf> { static constexpr GLenum value=GL_HALF_FLOAT; };
#endif

	template<unsigned int l>
	struct ClientToChannelsFormat;

	template<> struct ClientToChannelsFormat<1> { static constexpr GLenum value=GL_RED; };
	template<> struct ClientToChannelsFormat<2> { static constexpr GLenum value=GL_RG; };
	template<> struct ClientToChannelsFormat<3> { static constexpr GLenum value=GL_RGB; };
	template<> struct ClientToChannelsFormat<4> { static constexpr GLenum value=GL_RGBA; };

	constexpr inline unsigned int FormatToChannels(GLenum format)
	{
		switch(format)
		{
			case GL_STENCIL_INDEX:
			case GL_DEPTH_COMPONENT:
			case GL_RED:
			case GL_GREEN:
			case GL_BLUE:
			case GL_RED_INTEGER:
			case GL_GREEN_INTEGER:
			case GL_BLUE_INTEGER:
				return 1;

			case GL_DEPTH_STENCIL:
			case GL_RG:
			case GL_RG_INTEGER:
				return 2;
			case GL_RGB:
			case GL_BGR:
			case GL_RGB_INTEGER:
			case GL_BGR_INTEGER:
				return 3;
			case GL_RGBA_INTEGER:
			case GL_BGRA_INTEGER:
			case GL_BGRA:
			case GL_RGBA:
				return 4;
		};
		return 0; //TODO not recognized?
	}
	constexpr inline bool TypeIsBasic(GLenum type)
	{
		switch(type)
		{
			case GL_BYTE:
			case GL_UNSIGNED_BYTE:
			case GL_SHORT:
			case GL_UNSIGNED_SHORT:
			case GL_INT:
			case GL_UNSIGNED_INT:
			case GL_INT64_ARB:
			case GL_UNSIGNED_INT64_ARB:
			case GL_HALF_FLOAT:
			case GL_FLOAT:
			case GL_DOUBLE:
				return true;
			default:
				return false;
		};
	}
	inline size_t ElementSize(GLenum format,GLenum type)
	{
		size_t out;
		switch(type)
		{
			case GL_UNSIGNED_BYTE:
			case GL_BYTE:
				out=1;break;
			case GL_UNSIGNED_SHORT:
			case GL_SHORT:
			case GL_HALF_FLOAT:
				out=2;break;
			case GL_UNSIGNED_INT:
			case GL_INT:
			case GL_FLOAT:
				out=4;break;
			case GL_INT64_ARB:
			case GL_UNSIGNED_INT64_ARB:
			case GL_DOUBLE:
				out=8;break;
			case GL_UNSIGNED_BYTE_3_3_2:			return 1;
			case GL_UNSIGNED_BYTE_2_3_3_REV:		return 1;
			case GL_UNSIGNED_SHORT_5_6_5:			return 2;
			case GL_UNSIGNED_SHORT_5_6_5_REV:		return 2;
			case GL_UNSIGNED_SHORT_4_4_4_4:			return 2;
			case GL_UNSIGNED_SHORT_4_4_4_4_REV:		return 2;
			case GL_UNSIGNED_SHORT_5_5_5_1:			return 2;
			case GL_UNSIGNED_SHORT_1_5_5_5_REV:		return 2;
			case GL_UNSIGNED_INT_8_8_8_8:			return 4;
			case GL_UNSIGNED_INT_8_8_8_8_REV:		return 4;
			case GL_UNSIGNED_INT_10_10_10_2:		return 4;
			case GL_UNSIGNED_INT_2_10_10_10_REV:	return 4;
			case GL_UNSIGNED_INT_24_8:				return 4;
			case GL_UNSIGNED_INT_10F_11F_11F_REV:	return 4;
			case GL_UNSIGNED_INT_5_9_9_9_REV:		return 4;
			case GL_FLOAT_32_UNSIGNED_INT_24_8_REV:	return 8;
			default:
				return 0;
		};
		return out*FormatToChannels(format);
	}
}
}

#endif
<|endoftext|>


<commit_before>#include <znc/main.h>
#include <znc/User.h>
#include <znc/IRCNetwork.h>
#include <znc/Modules.h>
#include <znc/Nick.h>
#include <znc/Chan.h>
#include <znc/IRCSock.h>

#include <limits>

#include "twitchtmi.h"
#include "jload.h"

TwitchTMI::~TwitchTMI()
{

}

bool TwitchTMI::OnLoad(const CString& sArgsi, CString& sMessage)
{
	OnBoot();

	if(GetNetwork())
	{
		for(CChan *ch: GetNetwork()->GetChans())
		{
			ch->SetTopic(CString());

			CString chname = ch->GetName().substr(1);
			CThreadPool::Get().addJob(new TwitchTMIJob(this, chname));
		}
	}

	if(GetArgs().Token(0) != "FrankerZ")
		lastFrankerZ = std::numeric_limits<decltype(lastFrankerZ)>::max();

	PutIRC("CAP REQ :twitch.tv/membership");

	return true;
}

bool TwitchTMI::OnBoot()
{
	initCurl();

	timer = new TwitchTMIUpdateTimer(this);
	AddTimer(timer);

	return true;
}

void TwitchTMI::OnIRCConnected()
{
	PutIRC("CAP REQ :twitch.tv/membership");
}

CModule::EModRet TwitchTMI::OnUserRaw(CString &sLine)
{
	if(sLine.Left(5).Equals("WHO #"))
		return CModule::HALT;

	if(sLine.Left(5).Equals("AWAY "))
		return CModule::HALT;

	if(sLine.Left(12).Equals("TWITCHCLIENT"))
		return CModule::HALT;

	if(sLine.Left(9).Equals("JTVCLIENT"))
		return CModule::HALT;

	return CModule::CONTINUE;
}

CModule::EModRet TwitchTMI::OnUserJoin(CString& sChannel, CString& sKey)
{
	CString chname = sChannel.substr(1);
	CThreadPool::Get().addJob(new TwitchTMIJob(this, chname));

	return CModule::CONTINUE;
}

CModule::EModRet TwitchTMI::OnPrivMsg(CNick& nick, CString& sMessage)
{
	if(nick.GetNick().Equals("jtv", true))
		return CModule::HALT;

	return CModule::CONTINUE;
}

CModule::EModRet TwitchTMI::OnChanMsg(CNick& nick, CChan& channel, CString& sMessage)
{
	if(nick.GetNick().Equals("jtv", true))
		return CModule::HALT;

	if(sMessage == "FrankerZ" && std::time(nullptr) - lastFrankerZ > 10)
	{
		std::stringstream ss1, ss2;
		CString mynick = GetNetwork()->GetIRCNick().GetNickMask();

		ss1 << "PRIVMSG " << channel.GetName() << " :FrankerZ";
		ss2 << ":" << mynick << " PRIVMSG " << channel.GetName() << " :";

		PutIRC(ss1.str());
		CString s2 = ss2.str();

		CThreadPool::Get().addJob(new GenericJob([]() {}, [this, s2, &channel]()
		{
			PutUser(s2 + "FrankerZ");

			if(!channel.AutoClearChanBuffer() || !GetNetwork()->IsUserOnline() || channel.IsDetached()) {
				channel.AddBuffer(s2+ "{text}", "FrankerZ");
			}
		}));

		lastFrankerZ = std::time(nullptr);
	}

	return CModule::CONTINUE;
}

bool TwitchTMI::OnServerCapAvailable(const CString &sCap)
{
	if(sCap == "twitch.tv/membership")
	{
		CUtils::PrintMessage("TwitchTMI: Requesting twitch.tv/membership cap");
		return true;
	}

	CUtils::PrintMessage(CString("TwitchTMI: Not requesting ") + sCap + " cap");

	return false;
}

TwitchTMIUpdateTimer::TwitchTMIUpdateTimer(TwitchTMI *tmod)
	:CTimer(tmod, 30, 0, "TwitchTMIUpdateTimer", "Downloads Twitch information")
	,mod(tmod)
{
}

void TwitchTMIUpdateTimer::RunJob()
{
	if(!mod->GetNetwork())
		return;

	for(CChan *chan: mod->GetNetwork()->GetChans())
	{
		CString chname = chan->GetName().substr(1);
		CThreadPool::Get().addJob(new TwitchTMIJob(mod, chname));
	}
}

void TwitchTMIJob::runThread()
{
	std::stringstream ss;
	ss << "https://api.twitch.tv/kraken/channels/" << channel;

	CString url = ss.str();

	Json::Value root = getJsonFromUrl(url.c_str(), "Accept: application/vnd.twitchtv.v3+json");

	if(root.isNull())
	{
		return;
	}

	Json::Value &titleVal = root["status"];
	title = CString();

	if(!titleVal.isString())
		titleVal = root["title"];

	if(!titleVal.isString())
		return;

	title = titleVal.asString();
	title.Trim();
}

void TwitchTMIJob::runMain()
{
	if(title.empty())
		return;

	CChan *chan = mod->GetNetwork()->FindChan(CString("#") + channel);

	if(!chan)
		return;

	if(chan->GetTopic() != title)
	{
		chan->SetTopic(title);
		chan->SetTopicOwner("jtv");
		chan->SetTopicDate((unsigned long)time(nullptr));

		std::stringstream ss;
		ss << ":jtv TOPIC #" << channel << " :" << title;

		mod->PutUser(ss.str());
	}
}

template<> void TModInfo<TwitchTMI>(CModInfo &info)
{
	info.SetWikiPage("Twitch");
	info.SetHasArgs(false);
}

NETWORKMODULEDEFS(TwitchTMI, "Twitch IRC helper module")
<commit_msg>Does have args now<commit_after>#include <znc/main.h>
#include <znc/User.h>
#include <znc/IRCNetwork.h>
#include <znc/Modules.h>
#include <znc/Nick.h>
#include <znc/Chan.h>
#include <znc/IRCSock.h>

#include <limits>

#include "twitchtmi.h"
#include "jload.h"

TwitchTMI::~TwitchTMI()
{

}

bool TwitchTMI::OnLoad(const CString& sArgsi, CString& sMessage)
{
	OnBoot();

	if(GetNetwork())
	{
		for(CChan *ch: GetNetwork()->GetChans())
		{
			ch->SetTopic(CString());

			CString chname = ch->GetName().substr(1);
			CThreadPool::Get().addJob(new TwitchTMIJob(this, chname));
		}
	}

	if(GetArgs().Token(0) != "FrankerZ")
		lastFrankerZ = std::numeric_limits<decltype(lastFrankerZ)>::max();

	PutIRC("CAP REQ :twitch.tv/membership");

	return true;
}

bool TwitchTMI::OnBoot()
{
	initCurl();

	timer = new TwitchTMIUpdateTimer(this);
	AddTimer(timer);

	return true;
}

void TwitchTMI::OnIRCConnected()
{
	PutIRC("CAP REQ :twitch.tv/membership");
}

CModule::EModRet TwitchTMI::OnUserRaw(CString &sLine)
{
	if(sLine.Left(5).Equals("WHO #"))
		return CModule::HALT;

	if(sLine.Left(5).Equals("AWAY "))
		return CModule::HALT;

	if(sLine.Left(12).Equals("TWITCHCLIENT"))
		return CModule::HALT;

	if(sLine.Left(9).Equals("JTVCLIENT"))
		return CModule::HALT;

	return CModule::CONTINUE;
}

CModule::EModRet TwitchTMI::OnUserJoin(CString& sChannel, CString& sKey)
{
	CString chname = sChannel.substr(1);
	CThreadPool::Get().addJob(new TwitchTMIJob(this, chname));

	return CModule::CONTINUE;
}

CModule::EModRet TwitchTMI::OnPrivMsg(CNick& nick, CString& sMessage)
{
	if(nick.GetNick().Equals("jtv", true))
		return CModule::HALT;

	return CModule::CONTINUE;
}

CModule::EModRet TwitchTMI::OnChanMsg(CNick& nick, CChan& channel, CString& sMessage)
{
	if(nick.GetNick().Equals("jtv", true))
		return CModule::HALT;

	if(sMessage == "FrankerZ" && std::time(nullptr) - lastFrankerZ > 10)
	{
		std::stringstream ss1, ss2;
		CString mynick = GetNetwork()->GetIRCNick().GetNickMask();

		ss1 << "PRIVMSG " << channel.GetName() << " :FrankerZ";
		ss2 << ":" << mynick << " PRIVMSG " << channel.GetName() << " :";

		PutIRC(ss1.str());
		CString s2 = ss2.str();

		CThreadPool::Get().addJob(new GenericJob([]() {}, [this, s2, &channel]()
		{
			PutUser(s2 + "FrankerZ");

			if(!channel.AutoClearChanBuffer() || !GetNetwork()->IsUserOnline() || channel.IsDetached()) {
				channel.AddBuffer(s2+ "{text}", "FrankerZ");
			}
		}));

		lastFrankerZ = std::time(nullptr);
	}

	return CModule::CONTINUE;
}

bool TwitchTMI::OnServerCapAvailable(const CString &sCap)
{
	if(sCap == "twitch.tv/membership")
	{
		CUtils::PrintMessage("TwitchTMI: Requesting twitch.tv/membership cap");
		return true;
	}

	CUtils::PrintMessage(CString("TwitchTMI: Not requesting ") + sCap + " cap");

	return false;
}

TwitchTMIUpdateTimer::TwitchTMIUpdateTimer(TwitchTMI *tmod)
	:CTimer(tmod, 30, 0, "TwitchTMIUpdateTimer", "Downloads Twitch information")
	,mod(tmod)
{
}

void TwitchTMIUpdateTimer::RunJob()
{
	if(!mod->GetNetwork())
		return;

	for(CChan *chan: mod->GetNetwork()->GetChans())
	{
		CString chname = chan->GetName().substr(1);
		CThreadPool::Get().addJob(new TwitchTMIJob(mod, chname));
	}
}

void TwitchTMIJob::runThread()
{
	std::stringstream ss;
	ss << "https://api.twitch.tv/kraken/channels/" << channel;

	CString url = ss.str();

	Json::Value root = getJsonFromUrl(url.c_str(), "Accept: application/vnd.twitchtv.v3+json");

	if(root.isNull())
	{
		return;
	}

	Json::Value &titleVal = root["status"];
	title = CString();

	if(!titleVal.isString())
		titleVal = root["title"];

	if(!titleVal.isString())
		return;

	title = titleVal.asString();
	title.Trim();
}

void TwitchTMIJob::runMain()
{
	if(title.empty())
		return;

	CChan *chan = mod->GetNetwork()->FindChan(CString("#") + channel);

	if(!chan)
		return;

	if(chan->GetTopic() != title)
	{
		chan->SetTopic(title);
		chan->SetTopicOwner("jtv");
		chan->SetTopicDate((unsigned long)time(nullptr));

		std::stringstream ss;
		ss << ":jtv TOPIC #" << channel << " :" << title;

		mod->PutUser(ss.str());
	}
}

template<> void TModInfo<TwitchTMI>(CModInfo &info)
{
	info.SetWikiPage("Twitch");
	info.SetHasArgs(true);
}

NETWORKMODULEDEFS(TwitchTMI, "Twitch IRC helper module")
<|endoftext|>


<commit_before>/*
 * opencog/persist/PersistModule.cc
 *
 * Copyright (C) 2008 by Singularity Institute for Artificial Intelligence
 * All Rights Reserved
 *
 * Written by Gustavo Gama <gama@vettalabs.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * 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 Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "PersistModule.h"
#include "AtomStorage.h"

#include <opencog/atomspace/AtomSpaceAsync.h>
#include <opencog/atomspace/AtomSpace.h>
#include <opencog/atomspace/BackingStore.h>
#include <opencog/guile/SchemePrimitive.h>
#include <opencog/server/CogServer.h>

using namespace opencog;

namespace opencog {
class SQLBackingStore : public BackingStore
{
	private:
		AtomStorage *store;
	public:
		SQLBackingStore();
		void set_store(AtomStorage *);

		virtual Node * getNode(Type, const char *) const;
		virtual Link * getLink(Type, const std::vector<Handle>&) const;
		virtual Atom * getAtom(Handle) const;
		virtual std::vector<Handle> getIncomingSet(Handle) const;
		virtual void storeAtom(Handle);
};
};

SQLBackingStore::SQLBackingStore()
{
	store = NULL;
}

void SQLBackingStore::set_store(AtomStorage *as)
{
	store = as;
}

Node * SQLBackingStore::getNode(Type t, const char *name) const
{
	return store->getNode(t, name);
}

Link * SQLBackingStore::getLink(Type t, const std::vector<Handle>& oset) const
{
	return store->getLink(t, oset);
}

Atom * SQLBackingStore::getAtom(Handle h) const
{
	return store->getAtom(h);
}

std::vector<Handle> SQLBackingStore::getIncomingSet(Handle h) const
{
	return store->getIncomingSet(h);
}

void SQLBackingStore::storeAtom(Handle h)
{
	store->storeAtom(h);
}

DECLARE_MODULE(PersistModule);

PersistModule::PersistModule(void) : store(NULL)
{
	backing = new SQLBackingStore();
	do_close_register();
	do_load_register();
	do_open_register();
	do_store_register();

#ifdef HAVE_GUILE
	// XXX These probably should be declared by the atom-space directly,
	// instead of being declared here ... but I guess this is an OK
	// home for now.
	define_scheme_primitive("fetch-atom", &PersistModule::fetch_atom, this);
	define_scheme_primitive("fetch-incoming-set", &PersistModule::fetch_incoming_set, this);
	define_scheme_primitive("store-atom", &PersistModule::store_atom, this);
#endif
}

PersistModule::~PersistModule()
{
	do_close_unregister();
	do_load_unregister();
	do_open_unregister();
	do_store_unregister();
	delete backing;
}

void PersistModule::init(void)
{
}

std::string PersistModule::do_close(Request *dummy, std::list<std::string> args)
{
	if (!args.empty())
		return "sql-close: Wrong num args";

	if (store == NULL)
		return "sql-close: database not open";

	atomspace().atomSpaceAsync->unregisterBackingStore(backing);

	backing->set_store(NULL);
	delete store;
	store = NULL;
	return "database closed";
}

std::string PersistModule::do_load(Request *dummy, std::list<std::string> args)
{
	if (!args.empty())
		return "sql-load: Wrong num args";

	if (store == NULL)
		return "sql-load: database not open";

	store->load(const_cast<AtomTable&>(atomspace().atomSpaceAsync->getAtomTable()));

	return "database load started";
}

std::string PersistModule::do_open(Request *dummy, std::list<std::string> args)
{
	if (args.size() != 3)
		return "sql-open: Wrong num args";

	std::string dbname   = args.front(); args.pop_front();
	std::string username = args.front(); args.pop_front();
	std::string auth	   = args.front(); args.pop_front();

	store = new AtomStorage(dbname, username, auth);
	if (!store)
		return "sql-open: Unable to open the database";

	if (!store->connected())
	{
		delete store;
		store = NULL;
		return "sql-open: Unable to connect to the database";
	}

	// reserve() is critical here, to reserve UUID range.
	store->reserve();
	backing->set_store(store);
	atomspace().atomSpaceAsync->registerBackingStore(backing);

	return "database opened";
}

std::string PersistModule::do_store(Request *dummy, std::list<std::string> args)
{
	if (!args.empty())
		return "sql-store: Wrong num args";

	if (store == NULL)
		return "sql-store: database not open";

	store->store(const_cast<AtomTable&>(atomspace().atomSpaceAsync->getAtomTable()));

	return "database store started";
}

Handle PersistModule::fetch_atom(Handle h)
{
	AtomSpace *as = &atomspace();
	h = as->fetchAtom(h);
	return h;
}

Handle PersistModule::fetch_incoming_set(Handle h)
{
	AtomSpace *as = &atomspace();
	// The "true" flag here means "fetch resursive".
	h = as->fetchIncomingSet(h, true);
	return h;
}

/**
 * Store the single atom to the backing store hanging off the atom-space
 */
Handle PersistModule::store_atom(Handle h)
{
	AtomSpace *as = &atomspace();
	as->storeAtom(h);
	return h;
}

<commit_msg>fix spelling in documentation<commit_after>/*
 * opencog/persist/PersistModule.cc
 *
 * Copyright (C) 2008 by Singularity Institute for Artificial Intelligence
 * All Rights Reserved
 *
 * Written by Gustavo Gama <gama@vettalabs.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * 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 Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include "PersistModule.h"
#include "AtomStorage.h"

#include <opencog/atomspace/AtomSpaceAsync.h>
#include <opencog/atomspace/AtomSpace.h>
#include <opencog/atomspace/BackingStore.h>
#include <opencog/guile/SchemePrimitive.h>
#include <opencog/server/CogServer.h>

using namespace opencog;

namespace opencog {
class SQLBackingStore : public BackingStore
{
	private:
		AtomStorage *store;
	public:
		SQLBackingStore();
		void set_store(AtomStorage *);

		virtual Node * getNode(Type, const char *) const;
		virtual Link * getLink(Type, const std::vector<Handle>&) const;
		virtual Atom * getAtom(Handle) const;
		virtual std::vector<Handle> getIncomingSet(Handle) const;
		virtual void storeAtom(Handle);
};
};

SQLBackingStore::SQLBackingStore()
{
	store = NULL;
}

void SQLBackingStore::set_store(AtomStorage *as)
{
	store = as;
}

Node * SQLBackingStore::getNode(Type t, const char *name) const
{
	return store->getNode(t, name);
}

Link * SQLBackingStore::getLink(Type t, const std::vector<Handle>& oset) const
{
	return store->getLink(t, oset);
}

Atom * SQLBackingStore::getAtom(Handle h) const
{
	return store->getAtom(h);
}

std::vector<Handle> SQLBackingStore::getIncomingSet(Handle h) const
{
	return store->getIncomingSet(h);
}

void SQLBackingStore::storeAtom(Handle h)
{
	store->storeAtom(h);
}

DECLARE_MODULE(PersistModule);

PersistModule::PersistModule(void) : store(NULL)
{
	backing = new SQLBackingStore();
	do_close_register();
	do_load_register();
	do_open_register();
	do_store_register();

#ifdef HAVE_GUILE
	// XXX These probably should be declared by the atom-space directly,
	// instead of being declared here ... but I guess this is an OK
	// home for now.
	define_scheme_primitive("fetch-atom", &PersistModule::fetch_atom, this);
	define_scheme_primitive("fetch-incoming-set", &PersistModule::fetch_incoming_set, this);
	define_scheme_primitive("store-atom", &PersistModule::store_atom, this);
#endif
}

PersistModule::~PersistModule()
{
	do_close_unregister();
	do_load_unregister();
	do_open_unregister();
	do_store_unregister();
	delete backing;
}

void PersistModule::init(void)
{
}

std::string PersistModule::do_close(Request *dummy, std::list<std::string> args)
{
	if (!args.empty())
		return "sql-close: Wrong num args";

	if (store == NULL)
		return "sql-close: database not open";

	atomspace().atomSpaceAsync->unregisterBackingStore(backing);

	backing->set_store(NULL);
	delete store;
	store = NULL;
	return "database closed";
}

std::string PersistModule::do_load(Request *dummy, std::list<std::string> args)
{
	if (!args.empty())
		return "sql-load: Wrong num args";

	if (store == NULL)
		return "sql-load: database not open";

	store->load(const_cast<AtomTable&>(atomspace().atomSpaceAsync->getAtomTable()));

	return "database load started";
}

std::string PersistModule::do_open(Request *dummy, std::list<std::string> args)
{
	if (args.size() != 3)
		return "sql-open: Wrong num args";

	std::string dbname   = args.front(); args.pop_front();
	std::string username = args.front(); args.pop_front();
	std::string auth	   = args.front(); args.pop_front();

	store = new AtomStorage(dbname, username, auth);
	if (!store)
		return "sql-open: Unable to open the database";

	if (!store->connected())
	{
		delete store;
		store = NULL;
		return "sql-open: Unable to connect to the database";
	}

	// reserve() is critical here, to reserve UUID range.
	store->reserve();
	backing->set_store(store);
	atomspace().atomSpaceAsync->registerBackingStore(backing);

	return "database opened";
}

std::string PersistModule::do_store(Request *dummy, std::list<std::string> args)
{
	if (!args.empty())
		return "sql-store: Wrong num args";

	if (store == NULL)
		return "sql-store: database not open";

	store->store(const_cast<AtomTable&>(atomspace().atomSpaceAsync->getAtomTable()));

	return "database store started";
}

Handle PersistModule::fetch_atom(Handle h)
{
	AtomSpace *as = &atomspace();
	h = as->fetchAtom(h);
	return h;
}

Handle PersistModule::fetch_incoming_set(Handle h)
{
	AtomSpace *as = &atomspace();
	// The "true" flag here means "fetch recursive".
	h = as->fetchIncomingSet(h, true);
	return h;
}

/**
 * Store the single atom to the backing store hanging off the atom-space
 */
Handle PersistModule::store_atom(Handle h)
{
	AtomSpace *as = &atomspace();
	as->storeAtom(h);
	return h;
}

<|endoftext|>


<commit_before>#include "includes.h"

String::String(const string &value) : NativeObject(OBJ_STRING), _value(value)
{
}

String::~String()
{
}

NativeObject_p String::equal(const NativeObject_p other) const
{
  if(!IS_STRING(other))
    return nil;

  String_p other_string = (String_p)other;
  if(this->_value == other_string->_value)
    return t;
  return nil;
}

FancyObject_p String::eval(Scope *scope)
{
  return StringClass->create_instance(this);
}

string String::to_s() const
{
  return "\"" + this->_value + "\"";
}

string String::value() const
{
  return this->_value;
}

map<string, String_p> String::value_cache;
String_p String::from_value(const string &value)
{
  if(value_cache.find(value) != value_cache.end()) {
    return value_cache[value];
  } else {
    // insert new value into value_cache & return new number value
    String_p new_string = new String(value);
    value_cache[value] = new_string;
    return new_string;
  }
}
<commit_msg>String#to_s() doesn't return string with hyphens<commit_after>#include "includes.h"

String::String(const string &value) : NativeObject(OBJ_STRING), _value(value)
{
}

String::~String()
{
}

NativeObject_p String::equal(const NativeObject_p other) const
{
  if(!IS_STRING(other))
    return nil;

  String_p other_string = (String_p)other;
  if(this->_value == other_string->_value)
    return t;
  return nil;
}

FancyObject_p String::eval(Scope *scope)
{
  return StringClass->create_instance(this);
}

string String::to_s() const
{
  return this->_value;
}

string String::value() const
{
  return this->_value;
}

map<string, String_p> String::value_cache;
String_p String::from_value(const string &value)
{
  if(value_cache.find(value) != value_cache.end()) {
    return value_cache[value];
  } else {
    // insert new value into value_cache & return new number value
    String_p new_string = new String(value);
    value_cache[value] = new_string;
    return new_string;
  }
}
<|endoftext|>


<commit_before>#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

bool socketError = false;

int DDV_Listen(int port){
  int s = socket(AF_INET, SOCK_STREAM, 0);

  struct sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_port = htons(port);//port 8888
  inet_pton(AF_INET, "0.0.0.0", &addr.sin_addr);//listen on all interfaces
  int ret = bind(s, (sockaddr*)&addr, sizeof(addr));//bind to all interfaces, chosen port
  if (ret == 0){
    ret = listen(s, 100);//start listening, backlog of 100 allowed
    if (ret == 0){
      return s;
    }else{
      printf("Listen failed! Error: %s\n", strerror(errno));
      close(s);
      return 0;
    }
  }else{
    printf("Binding failed! Error: %s\n", strerror(errno));
    close(s);
    return 0;
  }
}

int DDV_Accept(int sock){
  return accept(sock, 0, 0);
}

bool DDV_write(char * buffer, int width, int count, int sock){
  bool r = (send(sock, buffer, width*count, 0) == width*count);
  if (!r){socketError = true}
  return r;
}

bool DDV_read(char * buffer, int width, int count, int sock){
  bool r = (recv(sock, buffer, width*count, 0) == width*count);
  if (!r){socketError = true}
  return r;
}
<commit_msg>Nog een poging...<commit_after>#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>

bool socketError = false;

int DDV_Listen(int port){
  int s = socket(AF_INET, SOCK_STREAM, 0);

  struct sockaddr_in addr;
  addr.sin_family = AF_INET;
  addr.sin_port = htons(port);//port 8888
  inet_pton(AF_INET, "0.0.0.0", &addr.sin_addr);//listen on all interfaces
  int ret = bind(s, (sockaddr*)&addr, sizeof(addr));//bind to all interfaces, chosen port
  if (ret == 0){
    ret = listen(s, 100);//start listening, backlog of 100 allowed
    if (ret == 0){
      return s;
    }else{
      printf("Listen failed! Error: %s\n", strerror(errno));
      close(s);
      return 0;
    }
  }else{
    printf("Binding failed! Error: %s\n", strerror(errno));
    close(s);
    return 0;
  }
}

int DDV_Accept(int sock){
  return accept(sock, 0, 0);
}

bool DDV_write(void * buffer, int width, int count, int sock){
  bool r = (send(sock, buffer, width*count, 0) == width*count);
  if (!r){socketError = true}
  return r;
}

bool DDV_read(void * buffer, int width, int count, int sock){
  bool r = (recv(sock, buffer, width*count, 0) == width*count);
  if (!r){socketError = true}
  return r;
}
<|endoftext|>


<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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 "Mutex.h"
#include "Util.h"

#include <assert.h>
#include <pthread.h>
#include <signal.h>

using boost::shared_ptr;

namespace apache { namespace thrift { namespace concurrency {

#ifndef THRIFT_NO_CONTENTION_PROFILING

static sig_atomic_t mutexProfilingSampleRate = 0;
static MutexWaitCallback mutexProfilingCallback = 0;

volatile static sig_atomic_t mutexProfilingCounter = 0;

void enableMutexProfiling(int32_t profilingSampleRate,
                          MutexWaitCallback callback) {
  mutexProfilingSampleRate = profilingSampleRate;
  mutexProfilingCallback = callback;
}

#define PROFILE_MUTEX_START_LOCK() \
    int64_t _lock_startTime = maybeGetProfilingStartTime();

#define PROFILE_MUTEX_NOT_LOCKED() \
  do { \
    if (_lock_startTime > 0) { \
      int64_t endTime = Util::currentTimeUsec(); \
      (*mutexProfilingCallback)(this, endTime - _lock_startTime); \
    } \
  } while (0)

#define PROFILE_MUTEX_LOCKED() \
  do { \
    profileTime_ = _lock_startTime; \
    if (profileTime_ > 0) { \
      profileTime_ = Util::currentTimeUsec() - profileTime_; \
    } \
  } while (0)

#define PROFILE_MUTEX_START_UNLOCK() \
  int64_t _temp_profileTime = profileTime_; \
  profileTime_ = 0;

#define PROFILE_MUTEX_UNLOCKED() \
  do { \
    if (_temp_profileTime > 0) { \
      (*mutexProfilingCallback)(this, _temp_profileTime); \
    } \
  } while (0)

static inline int64_t maybeGetProfilingStartTime() {
  if (mutexProfilingSampleRate && mutexProfilingCallback) {
    // This block is unsynchronized, but should produce a reasonable sampling
    // rate on most architectures.  The main race conditions are the gap
    // between the decrement and the test, the non-atomicity of decrement, and
    // potential caching of different values at different CPUs.
    //
    // - if two decrements race, the likeliest result is that the counter
    //      decrements slowly (perhaps much more slowly) than intended.
    //
    // - many threads could potentially decrement before resetting the counter
    //      to its large value, causing each additional incoming thread to
    //      profile every call.  This situation is unlikely to persist for long
    //      as the critical gap is quite short, but profiling could be bursty.
    sig_atomic_t localValue = --mutexProfilingCounter;
    if (localValue <= 0) {
      mutexProfilingCounter = mutexProfilingSampleRate;
      return Util::currentTimeUsec();
    }
  }

  return 0;
}

#else
#  define PROFILE_MUTEX_START_LOCK()
#  define PROFILE_MUTEX_NOT_LOCKED()
#  define PROFILE_MUTEX_LOCKED()
#  define PROFILE_MUTEX_START_UNLOCK()
#  define PROFILE_MUTEX_UNLOCKED()
#endif // THRIFT_NO_CONTENTION_PROFILING

/**
 * Implementation of Mutex class using POSIX mutex
 *
 * @version $Id:$
 */
class Mutex::impl {
 public:
  impl(Initializer init) : initialized_(false) {
#ifndef THRIFT_NO_CONTENTION_PROFILING
    profileTime_ = 0;
#endif
    init(&pthread_mutex_);
    initialized_ = true;
  }

  ~impl() {
    if (initialized_) {
      initialized_ = false;
      int ret = pthread_mutex_destroy(&pthread_mutex_);
      assert(ret == 0);
    }
  }

  void lock() const {
    PROFILE_MUTEX_START_LOCK();
    pthread_mutex_lock(&pthread_mutex_);
    PROFILE_MUTEX_LOCKED();
  }

  bool trylock() const { return (0 == pthread_mutex_trylock(&pthread_mutex_)); }

  bool timedlock(int64_t milliseconds) const {
    PROFILE_MUTEX_START_LOCK();

    struct timespec ts;
    Util::toTimespec(ts, milliseconds);
    int ret = pthread_mutex_timedlock(&pthread_mutex_, &ts);
    if (ret == 0) {
      PROFILE_MUTEX_LOCKED();
      return true;
    }

    PROFILE_MUTEX_NOT_LOCKED();
    return false;
  }

  void unlock() const {
    PROFILE_MUTEX_START_UNLOCK();
    pthread_mutex_unlock(&pthread_mutex_);
    PROFILE_MUTEX_UNLOCKED();
  }

  void* getUnderlyingImpl() const { return (void*) &pthread_mutex_; }

 private:
  mutable pthread_mutex_t pthread_mutex_;
  mutable bool initialized_;
#ifndef THRIFT_NO_CONTENTION_PROFILING
  mutable int64_t profileTime_;
#endif
};

Mutex::Mutex(Initializer init) : impl_(new Mutex::impl(init)) {}

void* Mutex::getUnderlyingImpl() const { return impl_->getUnderlyingImpl(); }

void Mutex::lock() const { impl_->lock(); }

bool Mutex::trylock() const { return impl_->trylock(); }

bool Mutex::timedlock(int64_t ms) const { return impl_->timedlock(ms); }

void Mutex::unlock() const { impl_->unlock(); }

void Mutex::DEFAULT_INITIALIZER(void* arg) {
  pthread_mutex_t* pthread_mutex = (pthread_mutex_t*)arg;
  int ret = pthread_mutex_init(pthread_mutex, NULL);
  assert(ret == 0);
}

static void init_with_kind(pthread_mutex_t* mutex, int kind) {
  pthread_mutexattr_t mutexattr;
  int ret = pthread_mutexattr_init(&mutexattr);
  assert(ret == 0);

  // Apparently, this can fail.  Should we really be aborting?
  ret = pthread_mutexattr_settype(&mutexattr, kind);
  assert(ret == 0);

  ret = pthread_mutex_init(mutex, &mutexattr);
  assert(ret == 0);

  ret = pthread_mutexattr_destroy(&mutexattr);
  assert(ret == 0);
}

#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
void Mutex::ADAPTIVE_INITIALIZER(void* arg) {
  // From mysql source: mysys/my_thr_init.c
  // Set mutex type to "fast" a.k.a "adaptive"
  //
  // In this case the thread may steal the mutex from some other thread
  // that is waiting for the same mutex. This will save us some
  // context switches but may cause a thread to 'starve forever' while
  // waiting for the mutex (not likely if the code within the mutex is
  // short).
  init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_ADAPTIVE_NP);
}
#endif

#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
void Mutex::RECURSIVE_INITIALIZER(void* arg) {
  init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_RECURSIVE_NP);
}
#endif

/**
 * Implementation of ReadWriteMutex class using POSIX rw lock
 *
 * @version $Id:$
 */
class ReadWriteMutex::impl {
public:
  impl() : initialized_(false) {
#ifndef THRIFT_NO_CONTENTION_PROFILING
    profileTime_ = 0;
#endif
    int ret = pthread_rwlock_init(&rw_lock_, NULL);
    assert(ret == 0);
    initialized_ = true;
  }

  ~impl() {
    if(initialized_) {
      initialized_ = false;
      int ret = pthread_rwlock_destroy(&rw_lock_);
      assert(ret == 0);
    }
  }

  void acquireRead() const {
    PROFILE_MUTEX_START_LOCK();
    pthread_rwlock_rdlock(&rw_lock_);
    PROFILE_MUTEX_NOT_LOCKED();  // not exclusive, so use not-locked path
  }

  void acquireWrite() const {
    PROFILE_MUTEX_START_LOCK();
    pthread_rwlock_wrlock(&rw_lock_);
    PROFILE_MUTEX_LOCKED();
  }

  bool attemptRead() const { return pthread_rwlock_tryrdlock(&rw_lock_); }

  bool attemptWrite() const { return pthread_rwlock_trywrlock(&rw_lock_); }

  void release() const {
    PROFILE_MUTEX_START_UNLOCK();
    pthread_rwlock_unlock(&rw_lock_);
    PROFILE_MUTEX_UNLOCKED();
  }

private:
  mutable pthread_rwlock_t rw_lock_;
  mutable bool initialized_;
#ifndef THRIFT_NO_CONTENTION_PROFILING
  mutable int64_t profileTime_;
#endif
};

ReadWriteMutex::ReadWriteMutex() : impl_(new ReadWriteMutex::impl()) {}

void ReadWriteMutex::acquireRead() const { impl_->acquireRead(); }

void ReadWriteMutex::acquireWrite() const { impl_->acquireWrite(); }

bool ReadWriteMutex::attemptRead() const { return impl_->attemptRead(); }

bool ReadWriteMutex::attemptWrite() const { return impl_->attemptWrite(); }

void ReadWriteMutex::release() const { impl_->release(); }

}}} // apache::thrift::concurrency

<commit_msg>THRIFT-736. cpp: Check for availability of pthread_mutex_timedlock<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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 "Mutex.h"
#include "Util.h"

#include <assert.h>
#include <pthread.h>
#include <signal.h>

using boost::shared_ptr;

namespace apache { namespace thrift { namespace concurrency {

#ifndef THRIFT_NO_CONTENTION_PROFILING

static sig_atomic_t mutexProfilingSampleRate = 0;
static MutexWaitCallback mutexProfilingCallback = 0;

volatile static sig_atomic_t mutexProfilingCounter = 0;

void enableMutexProfiling(int32_t profilingSampleRate,
                          MutexWaitCallback callback) {
  mutexProfilingSampleRate = profilingSampleRate;
  mutexProfilingCallback = callback;
}

#define PROFILE_MUTEX_START_LOCK() \
    int64_t _lock_startTime = maybeGetProfilingStartTime();

#define PROFILE_MUTEX_NOT_LOCKED() \
  do { \
    if (_lock_startTime > 0) { \
      int64_t endTime = Util::currentTimeUsec(); \
      (*mutexProfilingCallback)(this, endTime - _lock_startTime); \
    } \
  } while (0)

#define PROFILE_MUTEX_LOCKED() \
  do { \
    profileTime_ = _lock_startTime; \
    if (profileTime_ > 0) { \
      profileTime_ = Util::currentTimeUsec() - profileTime_; \
    } \
  } while (0)

#define PROFILE_MUTEX_START_UNLOCK() \
  int64_t _temp_profileTime = profileTime_; \
  profileTime_ = 0;

#define PROFILE_MUTEX_UNLOCKED() \
  do { \
    if (_temp_profileTime > 0) { \
      (*mutexProfilingCallback)(this, _temp_profileTime); \
    } \
  } while (0)

static inline int64_t maybeGetProfilingStartTime() {
  if (mutexProfilingSampleRate && mutexProfilingCallback) {
    // This block is unsynchronized, but should produce a reasonable sampling
    // rate on most architectures.  The main race conditions are the gap
    // between the decrement and the test, the non-atomicity of decrement, and
    // potential caching of different values at different CPUs.
    //
    // - if two decrements race, the likeliest result is that the counter
    //      decrements slowly (perhaps much more slowly) than intended.
    //
    // - many threads could potentially decrement before resetting the counter
    //      to its large value, causing each additional incoming thread to
    //      profile every call.  This situation is unlikely to persist for long
    //      as the critical gap is quite short, but profiling could be bursty.
    sig_atomic_t localValue = --mutexProfilingCounter;
    if (localValue <= 0) {
      mutexProfilingCounter = mutexProfilingSampleRate;
      return Util::currentTimeUsec();
    }
  }

  return 0;
}

#else
#  define PROFILE_MUTEX_START_LOCK()
#  define PROFILE_MUTEX_NOT_LOCKED()
#  define PROFILE_MUTEX_LOCKED()
#  define PROFILE_MUTEX_START_UNLOCK()
#  define PROFILE_MUTEX_UNLOCKED()
#endif // THRIFT_NO_CONTENTION_PROFILING

/**
 * Implementation of Mutex class using POSIX mutex
 *
 * @version $Id:$
 */
class Mutex::impl {
 public:
  impl(Initializer init) : initialized_(false) {
#ifndef THRIFT_NO_CONTENTION_PROFILING
    profileTime_ = 0;
#endif
    init(&pthread_mutex_);
    initialized_ = true;
  }

  ~impl() {
    if (initialized_) {
      initialized_ = false;
      int ret = pthread_mutex_destroy(&pthread_mutex_);
      assert(ret == 0);
    }
  }

  void lock() const {
    PROFILE_MUTEX_START_LOCK();
    pthread_mutex_lock(&pthread_mutex_);
    PROFILE_MUTEX_LOCKED();
  }

  bool trylock() const { return (0 == pthread_mutex_trylock(&pthread_mutex_)); }

  bool timedlock(int64_t milliseconds) const {
#if defined(_POSIX_TIMEOUTS) && _POSIX_TIMEOUTS >= 200112L
    PROFILE_MUTEX_START_LOCK();

    struct timespec ts;
    Util::toTimespec(ts, milliseconds);
    int ret = pthread_mutex_timedlock(&pthread_mutex_, &ts);
    if (ret == 0) {
      PROFILE_MUTEX_LOCKED();
      return true;
    }

    PROFILE_MUTEX_NOT_LOCKED();
    return false;
#else
    // If pthread_mutex_timedlock isn't supported, the safest thing to do
    // is just do a nonblocking trylock.
    return trylock();
#endif
  }

  void unlock() const {
    PROFILE_MUTEX_START_UNLOCK();
    pthread_mutex_unlock(&pthread_mutex_);
    PROFILE_MUTEX_UNLOCKED();
  }

  void* getUnderlyingImpl() const { return (void*) &pthread_mutex_; }

 private:
  mutable pthread_mutex_t pthread_mutex_;
  mutable bool initialized_;
#ifndef THRIFT_NO_CONTENTION_PROFILING
  mutable int64_t profileTime_;
#endif
};

Mutex::Mutex(Initializer init) : impl_(new Mutex::impl(init)) {}

void* Mutex::getUnderlyingImpl() const { return impl_->getUnderlyingImpl(); }

void Mutex::lock() const { impl_->lock(); }

bool Mutex::trylock() const { return impl_->trylock(); }

bool Mutex::timedlock(int64_t ms) const { return impl_->timedlock(ms); }

void Mutex::unlock() const { impl_->unlock(); }

void Mutex::DEFAULT_INITIALIZER(void* arg) {
  pthread_mutex_t* pthread_mutex = (pthread_mutex_t*)arg;
  int ret = pthread_mutex_init(pthread_mutex, NULL);
  assert(ret == 0);
}

static void init_with_kind(pthread_mutex_t* mutex, int kind) {
  pthread_mutexattr_t mutexattr;
  int ret = pthread_mutexattr_init(&mutexattr);
  assert(ret == 0);

  // Apparently, this can fail.  Should we really be aborting?
  ret = pthread_mutexattr_settype(&mutexattr, kind);
  assert(ret == 0);

  ret = pthread_mutex_init(mutex, &mutexattr);
  assert(ret == 0);

  ret = pthread_mutexattr_destroy(&mutexattr);
  assert(ret == 0);
}

#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
void Mutex::ADAPTIVE_INITIALIZER(void* arg) {
  // From mysql source: mysys/my_thr_init.c
  // Set mutex type to "fast" a.k.a "adaptive"
  //
  // In this case the thread may steal the mutex from some other thread
  // that is waiting for the same mutex. This will save us some
  // context switches but may cause a thread to 'starve forever' while
  // waiting for the mutex (not likely if the code within the mutex is
  // short).
  init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_ADAPTIVE_NP);
}
#endif

#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP
void Mutex::RECURSIVE_INITIALIZER(void* arg) {
  init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_RECURSIVE_NP);
}
#endif

/**
 * Implementation of ReadWriteMutex class using POSIX rw lock
 *
 * @version $Id:$
 */
class ReadWriteMutex::impl {
public:
  impl() : initialized_(false) {
#ifndef THRIFT_NO_CONTENTION_PROFILING
    profileTime_ = 0;
#endif
    int ret = pthread_rwlock_init(&rw_lock_, NULL);
    assert(ret == 0);
    initialized_ = true;
  }

  ~impl() {
    if(initialized_) {
      initialized_ = false;
      int ret = pthread_rwlock_destroy(&rw_lock_);
      assert(ret == 0);
    }
  }

  void acquireRead() const {
    PROFILE_MUTEX_START_LOCK();
    pthread_rwlock_rdlock(&rw_lock_);
    PROFILE_MUTEX_NOT_LOCKED();  // not exclusive, so use not-locked path
  }

  void acquireWrite() const {
    PROFILE_MUTEX_START_LOCK();
    pthread_rwlock_wrlock(&rw_lock_);
    PROFILE_MUTEX_LOCKED();
  }

  bool attemptRead() const { return pthread_rwlock_tryrdlock(&rw_lock_); }

  bool attemptWrite() const { return pthread_rwlock_trywrlock(&rw_lock_); }

  void release() const {
    PROFILE_MUTEX_START_UNLOCK();
    pthread_rwlock_unlock(&rw_lock_);
    PROFILE_MUTEX_UNLOCKED();
  }

private:
  mutable pthread_rwlock_t rw_lock_;
  mutable bool initialized_;
#ifndef THRIFT_NO_CONTENTION_PROFILING
  mutable int64_t profileTime_;
#endif
};

ReadWriteMutex::ReadWriteMutex() : impl_(new ReadWriteMutex::impl()) {}

void ReadWriteMutex::acquireRead() const { impl_->acquireRead(); }

void ReadWriteMutex::acquireWrite() const { impl_->acquireWrite(); }

bool ReadWriteMutex::attemptRead() const { return impl_->attemptRead(); }

bool ReadWriteMutex::attemptWrite() const { return impl_->attemptWrite(); }

void ReadWriteMutex::release() const { impl_->release(); }

}}} // apache::thrift::concurrency

<|endoftext|>


<commit_before>//
// Copyright (C) 2014
// Alessio Sclocco <a.sclocco@vu.nl>
//
// 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 <iostream>
using std::cout;
using std::cerr;
using std::endl;
#include <string>
using std::string;
#include <exception>
using std::exception;

#include <ArgumentList.hpp>
using isa::utils::ArgumentList;
#include <utils.hpp>
using isa::utils::toStringValue;
using isa::utils::replace;

void generatorPhi(const unsigned int nrSamplesPerThread, const unsigned int nrDMsPerThread);
void generatorAVX();

int main(int argc, char * argv[]) {
	bool usePhi = false;
	unsigned int nrSamplesPerThread = 0;
	unsigned int nrDMsPerThread = 0;

	try {
		ArgumentList args(argc, argv);

		usePhi = args.getSwitch("-phi");
		nrSamplesPerThread = args.getSwitchArgument< unsigned int >("-spt");
		nrDMsPerThread = args.getSwitchArgument< unsigned int >("-dpt");
	} catch ( exception & err ) {
		cerr << err.what() << endl;
		return 1;
	}

	if ( usePhi ) {
		generatorPhi(nrSamplesPerThread, nrDMsPerThread);
	}

	return 0;
}

void generatorPhi(const unsigned int nrSamplesPerThread, const unsigned int nrDMsPerThread) {
	string * code = new string();
	*code = "namespace PulsarSearch {\n"
		"template< typename T > void dedispersionPhi(const unsigned int nrSamplesPerChannel, const unsigned int nrDMs, const unsigned int nrSamplesPerSecond, const unsigned int nrChannels, const unsigned int nrSamplesPerPaddedSecond, const T  * const __restrict__ input, T * const __restrict__ output, const unsigned int * const __restrict__ shifts) {\n"
		"#pragma omp parallel for schedule(static)\n"
		"for ( unsigned int dm = 0; dm < nrDMs / " + toStringValue< unsigned int >(nrDMsPerThread) +  "; dm++ ) {\n"
			"#pragma omp parallel for schedule(static)\n"
			"for ( unsigned int sample = 0; sample < nrSamplesPerSecond / " + toStringValue< unsigned int >(nrSamplesPerThread) + "; sample += 16 ) {\n"
				"<%DEFS%>"
				"\n"
				"for ( unsigned int channel = 0; channel < nrChannels; channel++ ) {\n"
					"<%SHIFTS%>"
					"__m512 dispersedSample;\n"
					"\n"
					"<%SUMS%>"
				"}\n"
				"\n"
				"<%STORES%>"

			"}\n"
		"}\n"
	"}\n"
	"}";
	string defsTemplate = "__m512 dedispersedSample<%NUM%>DM<%DM_NUM%> = _mm512_setzero_ps();\n";
	string shiftsTemplate = "unsigned int shiftDM<%DM_NUM%> = shifts[((dm + <%DM_NUM%>) * nrChannels) + channel];";
	string sumsTemplate = "dispersedSample = _mm512_loadunpacklo_ps(dispersedSample, &(input[(channel * nrSamplesPerChannel) + ((sample + <%OFFSET%>) + shiftDM<%DM_NUM%>)]));\n"
		"dispersedSample = _mm512_loadunpackhi_ps(dispersedSample, &(input[(channel * nrSamplesPerChannel) + ((sample + <%OFFSET%>) + shiftDM<%DM_NUM%>)]) + 16);\n"
		"dedispersedSample<%NUM%>DM<%DM_NUM%> = _mm512_add_ps(dedispersedSample<%NUM%>DM<%DM_NUM%>, dispersedSample);\n";
	string storesTemplate = "_mm512_packstorelo_ps(&(output[((dm + <%DM_NUM%>) * nrSamplesPerPaddedSecond) + (sample + <%OFFSET%>)]), dedispersedSample<%NUM%>DM<%DM_NUM%>);\n"
		"_mm512_packstorehi_ps(&(output[((dm + <%DM_NUM%>) * nrSamplesPerPaddedSecond) + (sample + <%OFFSET%>)]) + 16, dedispersedSample<%NUM%>DM<%DM_NUM%>);\n";

	string * defs = new string();
	string * shifts = new string();
	string * sums = new string();
	string * stores = new string();
	for ( unsigned int dm = 0; dm < nrDMsPerThread; dm++ ) {
		string dm_s = toStringValue< unsigned int >(dm);
		string * temp = 0;

		temp = replace(&shiftsTemplate, "<%DM_NUM%>", dm_s);
		shifts->append(*temp);
		delete temp;
	}
	for ( unsigned int sample = 0; sample < nrSamplesPerThread; sample++ ) {
		string sample_s = toStringValue< unsigned int >(sample);
		string offset_s = toStringValue< unsigned int >(sample * 16);
		string * defsDM = new string();
		string * sumsDM = new string();
		string * storesDM = new string();

		for ( unsigned int dm = 0; dm < nrDMsPerThread; dm++ ) {
			string dm_s = toStringValue< unsigned int >(dm);
			string * temp = 0;

			temp = replace(&defsTemplate, "<%DM_NUM%>", dm_s);
			defsDM->append(*temp);
			delete temp;
			temp = replace(&sumsTemplate, "<%DM_NUM%>", dm_s);
			sumsDM->append(*temp);
			delete temp;
			temp = replace(&storesTemplate, "<%DM_NUM%>", dm_s);
			storesDM->append(*temp);
			delete temp;
		}
		defsDM = replace(defsDM, "<%NUM%>", sample_s, true);
		defs->append(*defsDM);
		delete defsDM;
		sumsDM = replace(sumsDM, "<%NUM%>", sample_s, true);
		sumsDM = replace(sumsDM, "<%OFFSET%>", offset_s, true);
		sums->append(*sumsDM);
		delete sumsDM;
		storesDM = replace(storesDM, "<%NUM%>", sample_s, true);
		storesDM = replace(storesDM, "<%OFFSET%>", offset_s, true);
		stores->append(*storesDM);
		delete storesDM;
	}
	code = replace(code, "<%DEFS%>", *defs, true);
	code = replace(code, "<%SHIFTS%>", *shifts, true);
	code = replace(code, "<%SUMS%>", *sums, true);
	code = replace(code, "<%STORES%>", *stores, true);
	delete defs;
	delete shifts;
	delete sums;
	delete stores;

	cout << *code << endl;
}

void generatorAVX() {

}
<commit_msg>The generator produces valid code for the Phi.<commit_after>//
// Copyright (C) 2014
// Alessio Sclocco <a.sclocco@vu.nl>
//
// 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 <iostream>
using std::cout;
using std::cerr;
using std::endl;
#include <string>
using std::string;
#include <exception>
using std::exception;

#include <ArgumentList.hpp>
using isa::utils::ArgumentList;
#include <utils.hpp>
using isa::utils::toStringValue;
using isa::utils::replace;

void generatorPhi(const unsigned int nrSamplesPerThread, const unsigned int nrDMsPerThread);
void generatorAVX();

int main(int argc, char * argv[]) {
	bool usePhi = false;
	unsigned int nrSamplesPerThread = 0;
	unsigned int nrDMsPerThread = 0;

	try {
		ArgumentList args(argc, argv);

		usePhi = args.getSwitch("-phi");
		nrSamplesPerThread = args.getSwitchArgument< unsigned int >("-spt");
		nrDMsPerThread = args.getSwitchArgument< unsigned int >("-dpt");
	} catch ( exception & err ) {
		cerr << err.what() << endl;
		return 1;
	}

	if ( usePhi ) {
		generatorPhi(nrSamplesPerThread, nrDMsPerThread);
	}

	return 0;
}

void generatorPhi(const unsigned int nrSamplesPerThread, const unsigned int nrDMsPerThread) {
	string * code = new string();
	*code = "namespace PulsarSearch {\n"
		"template< typename T > void dedispersionPhi(const unsigned int nrSamplesPerChannel, const unsigned int nrDMs, const unsigned int nrSamplesPerSecond, const unsigned int nrChannels, const unsigned int nrSamplesPerPaddedSecond, const T  * const __restrict__ input, T * const __restrict__ output, const unsigned int * const __restrict__ shifts) {\n"
		"#pragma omp parallel for schedule(static)\n"
		"for ( unsigned int dm = 0; dm < nrDMs; dm += " + toStringValue< unsigned int >(nrDMsPerThread) + " ) {\n"
			"#pragma omp parallel for schedule(static)\n"
			"for ( unsigned int sample = 0; sample < nrSamplesPerSecond; sample += 16 * " + toStringValue< unsigned int >(nrSamplesPerThread) + ") {\n"
				"<%DEFS%>"
				"\n"
				"for ( unsigned int channel = 0; channel < nrChannels; channel++ ) {\n"
					"<%SHIFTS%>"
					"__m512 dispersedSample;\n"
					"\n"
					"<%SUMS%>"
				"}\n"
				"\n"
				"<%STORES%>"

			"}\n"
		"}\n"
	"}\n"
	"}";
	string defsTemplate = "__m512 dedispersedSample<%NUM%>DM<%DM_NUM%> = _mm512_setzero_ps();\n";
	string shiftsTemplate = "unsigned int shiftDM<%DM_NUM%> = shifts[((dm + <%DM_NUM%>) * nrChannels) + channel];";
	string sumsTemplate = "dispersedSample = _mm512_loadunpacklo_ps(dispersedSample, &(input[(channel * nrSamplesPerChannel) + ((sample + <%OFFSET%>) + shiftDM<%DM_NUM%>)]));\n"
		"dispersedSample = _mm512_loadunpackhi_ps(dispersedSample, &(input[(channel * nrSamplesPerChannel) + ((sample + <%OFFSET%>) + shiftDM<%DM_NUM%>)]) + 16);\n"
		"dedispersedSample<%NUM%>DM<%DM_NUM%> = _mm512_add_ps(dedispersedSample<%NUM%>DM<%DM_NUM%>, dispersedSample);\n";
	string storesTemplate = "_mm512_packstorelo_ps(&(output[((dm + <%DM_NUM%>) * nrSamplesPerPaddedSecond) + (sample + <%OFFSET%>)]), dedispersedSample<%NUM%>DM<%DM_NUM%>);\n"
		"_mm512_packstorehi_ps(&(output[((dm + <%DM_NUM%>) * nrSamplesPerPaddedSecond) + (sample + <%OFFSET%>)]) + 16, dedispersedSample<%NUM%>DM<%DM_NUM%>);\n";

	string * defs = new string();
	string * shifts = new string();
	string * sums = new string();
	string * stores = new string();
	for ( unsigned int dm = 0; dm < nrDMsPerThread; dm++ ) {
		string dm_s = toStringValue< unsigned int >(dm);
		string * temp = 0;

		temp = replace(&shiftsTemplate, "<%DM_NUM%>", dm_s);
		shifts->append(*temp);
		delete temp;
	}
	for ( unsigned int sample = 0; sample < nrSamplesPerThread; sample++ ) {
		string sample_s = toStringValue< unsigned int >(sample);
		string offset_s = toStringValue< unsigned int >(sample * 16);
		string * defsDM = new string();
		string * sumsDM = new string();
		string * storesDM = new string();

		for ( unsigned int dm = 0; dm < nrDMsPerThread; dm++ ) {
			string dm_s = toStringValue< unsigned int >(dm);
			string * temp = 0;

			temp = replace(&defsTemplate, "<%DM_NUM%>", dm_s);
			defsDM->append(*temp);
			delete temp;
			temp = replace(&sumsTemplate, "<%DM_NUM%>", dm_s);
			sumsDM->append(*temp);
			delete temp;
			temp = replace(&storesTemplate, "<%DM_NUM%>", dm_s);
			storesDM->append(*temp);
			delete temp;
		}
		defsDM = replace(defsDM, "<%NUM%>", sample_s, true);
		defs->append(*defsDM);
		delete defsDM;
		sumsDM = replace(sumsDM, "<%NUM%>", sample_s, true);
		sumsDM = replace(sumsDM, "<%OFFSET%>", offset_s, true);
		sums->append(*sumsDM);
		delete sumsDM;
		storesDM = replace(storesDM, "<%NUM%>", sample_s, true);
		storesDM = replace(storesDM, "<%OFFSET%>", offset_s, true);
		stores->append(*storesDM);
		delete storesDM;
	}
	code = replace(code, "<%DEFS%>", *defs, true);
	code = replace(code, "<%SHIFTS%>", *shifts, true);
	code = replace(code, "<%SUMS%>", *sums, true);
	code = replace(code, "<%STORES%>", *stores, true);
	delete defs;
	delete shifts;
	delete sums;
	delete stores;

	cout << *code << endl;
}

void generatorAVX() {

}
<|endoftext|>