<commit_before>/*
 *    _aaaa,  _aa.  sa,  aaa              _aaaa,_  ac  .aa.   .aa.  .aa,  _a, sa
 *  .wWV!!!T  |Wm;  dQ[  $WF            _mWT!"?Y  ]QE  :Q#:   ]QW[  :WWk. ]Q[ dW
 * .jWf       :WW: .dQ[  dQ[           .mW(       )WE  :Q#:  .mSQh. :mWQa.]W[ dQ
 * |QW:       :Wm;  mQ[  dQ[           ]Qk        )Qmi_aQW:  <B:$Qc :WBWQ()W[ dQ
 * |W#:  .ww  ;WW;  dQ[  dQ[  .......  ]Qk        )QB?YYW#:  jf ]Qp.:mE)Qm]Q[ )W
 * +WQ;  :Wm  |Wm; .mQ[  dQ[ :qgggggga ]Qm.       ]WE  :Q# :=QasuQm;:Wk 3QQW[ )Y
 *  ]Wmi.:Wm  +$Q; .mW(  dQ[  !"!!"!!^ dQk,  ._   ]WE  :Q# :3D"!!$Qc.Wk -$WQ[
 *   "?????? ` "?!=m?!   ??'            -??????!  -?!  -?? -?'   "?"-?"  "??' "?
 *
 * Copyright (c) 2004 darkbits                              Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of darkbits nor the     :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                     ^
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef GCN_PLATFORM_HPP
#define GCN_PLATFORM_HPP

#if defined(_WIN32) && defined(GUICHAN_BUILD)
#define DECLSPEC _declspec(dllexport)
#endif

#ifndef DECLSPEC
#define DECLSPEC
#endif

#endif // end GCN_PLATFORM_HPP<commit_msg>Added missing new line<commit_after>/*
 *    _aaaa,  _aa.  sa,  aaa              _aaaa,_  ac  .aa.   .aa.  .aa,  _a, sa
 *  .wWV!!!T  |Wm;  dQ[  $WF            _mWT!"?Y  ]QE  :Q#:   ]QW[  :WWk. ]Q[ dW
 * .jWf       :WW: .dQ[  dQ[           .mW(       )WE  :Q#:  .mSQh. :mWQa.]W[ dQ
 * |QW:       :Wm;  mQ[  dQ[           ]Qk        )Qmi_aQW:  <B:$Qc :WBWQ()W[ dQ
 * |W#:  .ww  ;WW;  dQ[  dQ[  .......  ]Qk        )QB?YYW#:  jf ]Qp.:mE)Qm]Q[ )W
 * +WQ;  :Wm  |Wm; .mQ[  dQ[ :qgggggga ]Qm.       ]WE  :Q# :=QasuQm;:Wk 3QQW[ )Y
 *  ]Wmi.:Wm  +$Q; .mW(  dQ[  !"!!"!!^ dQk,  ._   ]WE  :Q# :3D"!!$Qc.Wk -$WQ[
 *   "?????? ` "?!=m?!   ??'            -??????!  -?!  -?? -?'   "?"-?"  "??' "?
 *
 * Copyright (c) 2004 darkbits                              Js_./
 * Per Larsson a.k.a finalman                          _RqZ{a<^_aa
 * Olof Naessn a.k.a jansem/yakslem                _asww7!uY`>  )\a//
 *                                                 _Qhm`] _f "'c  1!5m
 * Visit: http://guichan.darkbits.org             )Qk<P ` _: :+' .'  "{[
 *                                               .)j(] .d_/ '-(  P .   S
 * License: (BSD)                                <Td/Z <fP"5(\"??"\a.  .L
 * Redistribution and use in source and          _dV>ws?a-?'      ._/L  #'
 * binary forms, with or without                 )4d[#7r, .   '     )d`)[
 * modification, are permitted provided         _Q-5'5W..j/?'   -?!\)cam'
 * that the following conditions are met:       j<<WP+k/);.        _W=j f
 * 1. Redistributions of source code must       .$%w\/]Q  . ."'  .  mj$
 *    retain the above copyright notice,        ]E.pYY(Q]>.   a     J@\
 *    this list of conditions and the           j(]1u<sE"L,. .   ./^ ]{a
 *    following disclaimer.                     4'_uomm\.  )L);-4     (3=
 * 2. Redistributions in binary form must        )_]X{Z('a_"a7'<a"a,  ]"[
 *    reproduce the above copyright notice,       #}<]m7`Za??4,P-"'7. ).m
 *    this list of conditions and the            ]d2e)Q(<Q(  ?94   b-  LQ/
 *    following disclaimer in the                <B!</]C)d_, '(<' .f. =C+m
 *    documentation and/or other materials      .Z!=J ]e []('-4f _ ) -.)m]'
 *    provided with the distribution.          .w[5]' _[ /.)_-"+?   _/ <W"
 * 3. Neither the name of darkbits nor the     :$we` _! + _/ .        j?
 *    names of its contributors may be used     =3)= _f  (_yQmWW$#(    "
 *    to endorse or promote products derived     -   W,  sQQQQmZQ#Wwa]..
 *    from this software without specific        (js, \[QQW$QWW#?!V"".
 *    prior written permission.                    ]y:.<\..          .
 *                                                 -]n w/ '         [.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT       )/ )/           !
 * HOLDERS AND CONTRIBUTORS "AS IS" AND ANY         <  (; sac    ,    '
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING,               ]^ .-  %
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF            c <   r
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR            aga<  <La
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE          5%  )P'-3L
 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR        _bQf` y`..)a
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,          ,J?4P'.P"_(\?d'.,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES               _Pa,)!f/<[]/  ?"
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT      _2-..:. .r+_,.. .
 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,     ?a.<%"'  " -'.a_ _,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION)                     ^
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef GCN_PLATFORM_HPP
#define GCN_PLATFORM_HPP

#if defined(_WIN32) && defined(GUICHAN_BUILD)
#define DECLSPEC _declspec(dllexport)
#endif

#ifndef DECLSPEC
#define DECLSPEC
#endif

#endif // end GCN_PLATFORM_HPP
<|endoftext|>


<commit_before>/*
 * This file is part of liblcf. Copyright (c) 2017 liblcf authors.
 * https://github.com/EasyRPG/liblcf - https://easyrpg.org
 *
 * liblcf is Free/Libre Open Source Software, released under the MIT License.
 * For the full copyright and license information, please view the COPYING
 * file that was distributed with this source code.
 */

#include "lcf_options.h"
#include "rpg_actor.h"
#include "rpg_mapinfo.h"
#include "rpg_system.h"
#include "rpg_save.h"
#include "rpg_savemapinfo.h"
#include "data.h"

void RPG::SaveActor::Fixup(int actor_id) {
	ID = actor_id;

	const RPG::Actor& actor = Data::actors[actor_id - 1];

	if (name == "\x1") {
		name = actor.name;
	}
	if (title == "\x1") {
		title = actor.title;
	}
	if (sprite_name.empty()) {
		sprite_name = actor.character_name;
		sprite_id = actor.character_index;
		sprite_flags = actor.transparent ? 3 : 0;
	}
	if (face_name.empty()) {
		face_name = actor.face_name;
		face_id = actor.face_index;
	}
}

void RPG::SaveMapEvent::Fixup(const RPG::EventPage& page) {
	if (move_frequency == -1) {
		move_frequency = page.move_frequency;
	}
	if (move_speed == -1) {
		move_speed = page.move_speed;
	}
	if (sprite_name.empty()) {
		sprite_name = page.character_name;
	}
	if (sprite_id == -1) {
		sprite_id = page.character_index;
	}
}

void RPG::SaveSystem::Fixup() {
	const RPG::System& system = Data::system;

	if (graphics_name.empty()) {
		graphics_name = system.system_name;
	}
	if (switches.size() < Data::switches.size()) {
		switches.resize(Data::switches.size());
	}
	if (variables.size() < Data::variables.size()) {
		variables.resize(Data::variables.size());
	}
	if (battle_music.name.empty()) {
		battle_music.name = system.battle_music.name;
	}
	if (battle_end_music.name.empty()) {
		battle_end_music.name = system.battle_end_music.name;
	}
	if (inn_music.name.empty()) {
		inn_music.name = system.inn_music.name;
	}
	if (title_music.name.empty()) {
		title_music.name = system.title_music.name;
	}
	if (boat_music.name.empty()) {
		boat_music.name = system.boat_music.name;
	}
	if (ship_music.name.empty()) {
		ship_music.name = system.ship_music.name;
	}
	if (airship_music.name.empty()) {
		airship_music.name = system.airship_music.name;
	}
	if (gameover_music.name.empty()) {
		gameover_music.name = system.gameover_music.name;
	}
	if (cursor_se.name.empty()) {
		cursor_se.name = system.cursor_se.name;
	}
	if (decision_se.name.empty()) {
		decision_se.name = system.decision_se.name;
	}
	if (cancel_se.name.empty()) {
		cancel_se.name = system.cancel_se.name;
	}
	if (buzzer_se.name.empty()) {
		buzzer_se.name = system.buzzer_se.name;
	}
	if (battle_se.name.empty()) {
		battle_se.name = system.battle_se.name;
	}
	if (escape_se.name.empty()) {
		escape_se.name = system.escape_se.name;
	}
	if (enemy_attack_se.name.empty()) {
		enemy_attack_se.name = system.enemy_attack_se.name;
	}
	if (enemy_damaged_se.name.empty()) {
		enemy_damaged_se.name = system.enemy_damaged_se.name;
	}
	if (actor_damaged_se.name.empty()) {
		actor_damaged_se.name = system.actor_damaged_se.name;
	}
	if (dodge_se.name.empty()) {
		dodge_se.name = system.dodge_se.name;
	}
	if (enemy_death_se.name.empty()) {
		enemy_death_se.name = system.enemy_death_se.name;
	}
	if (item_se.name.empty()) {
		item_se.name = system.item_se.name;
	}
	if (message_stretch == -1) {
		message_stretch = system.message_stretch;
	}
}

void RPG::SaveMapInfo::Fixup(const RPG::Map& map) {
	if (chipset_id <= 0) {
		chipset_id = map.chipset_id;
	}
}
<commit_msg>Fix how SaveGame Music and sfx are loaded<commit_after>/*
 * This file is part of liblcf. Copyright (c) 2017 liblcf authors.
 * https://github.com/EasyRPG/liblcf - https://easyrpg.org
 *
 * liblcf is Free/Libre Open Source Software, released under the MIT License.
 * For the full copyright and license information, please view the COPYING
 * file that was distributed with this source code.
 */

#include "lcf_options.h"
#include "rpg_actor.h"
#include "rpg_mapinfo.h"
#include "rpg_system.h"
#include "rpg_save.h"
#include "rpg_savemapinfo.h"
#include "data.h"

void RPG::SaveActor::Fixup(int actor_id) {
	ID = actor_id;

	const RPG::Actor& actor = Data::actors[actor_id - 1];

	if (name == "\x1") {
		name = actor.name;
	}
	if (title == "\x1") {
		title = actor.title;
	}
	if (sprite_name.empty()) {
		sprite_name = actor.character_name;
		sprite_id = actor.character_index;
		sprite_flags = actor.transparent ? 3 : 0;
	}
	if (face_name.empty()) {
		face_name = actor.face_name;
		face_id = actor.face_index;
	}
}

void RPG::SaveMapEvent::Fixup(const RPG::EventPage& page) {
	if (move_frequency == -1) {
		move_frequency = page.move_frequency;
	}
	if (move_speed == -1) {
		move_speed = page.move_speed;
	}
	if (sprite_name.empty()) {
		sprite_name = page.character_name;
	}
	if (sprite_id == -1) {
		sprite_id = page.character_index;
	}
}

void RPG::SaveSystem::Fixup() {
	const RPG::System& system = Data::system;

	if (graphics_name.empty()) {
		graphics_name = system.system_name;
	}
	if (switches.size() < Data::switches.size()) {
		switches.resize(Data::switches.size());
	}
	if (variables.size() < Data::variables.size()) {
		variables.resize(Data::variables.size());
	}
	if (battle_music.name.empty()) {
		battle_music = system.battle_music;
	}
	if (battle_end_music.name.empty()) {
		battle_end_music = system.battle_end_music;
	}
	if (inn_music.name.empty()) {
		inn_music = system.inn_music;
	}
	if (title_music.name.empty()) {
		title_music = system.title_music;
	}
	if (boat_music.name.empty()) {
		boat_music = system.boat_music;
	}
	if (ship_music.name.empty()) {
		ship_music = system.ship_music;
	}
	if (airship_music.name.empty()) {
		airship_music = system.airship_music;
	}
	if (gameover_music.name.empty()) {
		gameover_music = system.gameover_music;
	}
	if (cursor_se.name.empty()) {
		cursor_se = system.cursor_se;
	}
	if (decision_se.name.empty()) {
		decision_se = system.decision_se;
	}
	if (cancel_se.name.empty()) {
		cancel_se = system.cancel_se;
	}
	if (buzzer_se.name.empty()) {
		buzzer_se = system.buzzer_se;
	}
	if (battle_se.name.empty()) {
		battle_se = system.battle_se;
	}
	if (escape_se.name.empty()) {
		escape_se = system.escape_se;
	}
	if (enemy_attack_se.name.empty()) {
		enemy_attack_se = system.enemy_attack_se;
	}
	if (enemy_damaged_se.name.empty()) {
		enemy_damaged_se = system.enemy_damaged_se;
	}
	if (actor_damaged_se.name.empty()) {
		actor_damaged_se = system.actor_damaged_se;
	}
	if (dodge_se.name.empty()) {
		dodge_se = system.dodge_se;
	}
	if (enemy_death_se.name.empty()) {
		enemy_death_se = system.enemy_death_se;
	}
	if (item_se.name.empty()) {
		item_se = system.item_se;
	}
	if (message_stretch == -1) {
		message_stretch = system.message_stretch;
	}
}

void RPG::SaveMapInfo::Fixup(const RPG::Map& map) {
	if (chipset_id <= 0) {
		chipset_id = map.chipset_id;
	}
}
<|endoftext|>


<commit_before>/*

Copyright (c) 2003, Arvid Norberg, Daniel Wallin
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_ALERT_HPP_INCLUDED
#define TORRENT_ALERT_HPP_INCLUDED

#include <memory>
#include <queue>
#include <string>
#include <typeinfo>

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>

#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "libtorrent/time.hpp"
#include "libtorrent/config.hpp"
#include "libtorrent/assert.hpp"

#ifndef TORRENT_MAX_ALERT_TYPES
#define TORRENT_MAX_ALERT_TYPES 15
#endif

namespace libtorrent {

	class TORRENT_EXPORT alert
	{
	public:

		// only here for backwards compatibility
		enum severity_t { debug, info, warning, critical, fatal, none };

		enum category_t
		{
			error_notification = 0x1,
			peer_notification = 0x2,
			port_mapping_notification = 0x4,
			storage_notification = 0x8,
			tracker_notification = 0x10,
			debug_notification = 0x20,
			status_notification = 0x40,
			progress_notification = 0x80,
			ip_block_notification = 0x100,
			performance_warning = 0x200,
			dht_notification = 0x400,

			all_categories = 0xffffffff
		};

		alert();
		virtual ~alert();

		// a timestamp is automatically created in the constructor
		ptime timestamp() const;

		virtual char const* what() const = 0;
		virtual std::string message() const = 0;
		virtual int category() const = 0;

#ifndef TORRENT_NO_DEPRECATE
		severity_t severity() const TORRENT_DEPRECATED { return warning; }
#endif

		virtual std::auto_ptr<alert> clone() const = 0;

	private:
		ptime m_timestamp;
	};

	class TORRENT_EXPORT alert_manager
	{
	public:
		enum { queue_size_limit_default = 1000 };

		alert_manager();
		~alert_manager();

		void post_alert(const alert& alert_);
		bool pending() const;
		std::auto_ptr<alert> get();

		template <class T>
		bool should_post() const { return (m_alert_mask & T::static_category) != 0; }

		alert const* wait_for_alert(time_duration max_wait);

		void set_alert_mask(int m) { m_alert_mask = m; }

		size_t alert_queue_size_limit() const { return m_queue_size_limit; }
		size_t set_alert_queue_size_limit(size_t queue_size_limit_);

		void set_dispatch_function(boost::function<void(alert const&)> const&);

	private:
		std::queue<alert*> m_alerts;
		mutable boost::mutex m_mutex;
		boost::condition m_condition;
		int m_alert_mask;
		size_t m_queue_size_limit;
		boost::function<void(alert const&)> m_dispatch;
	};

	struct TORRENT_EXPORT unhandled_alert : std::exception
	{
		unhandled_alert() {}
	};

	namespace detail {

		struct void_;

		template<class Handler
			, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, class T)>
		void handle_alert_dispatch(
			const std::auto_ptr<alert>& alert_, const Handler& handler
			, const std::type_info& typeid_
			, BOOST_PP_ENUM_BINARY_PARAMS(TORRENT_MAX_ALERT_TYPES, T, *p))
		{
			if (typeid_ == typeid(T0))
				handler(*static_cast<T0*>(alert_.get()));
			else
				handle_alert_dispatch(alert_, handler, typeid_
					, BOOST_PP_ENUM_SHIFTED_PARAMS(
					TORRENT_MAX_ALERT_TYPES, p), (void_*)0);
		}

		template<class Handler>
		void handle_alert_dispatch(
			const std::auto_ptr<alert>& alert_
			, const Handler& handler
			, const std::type_info& typeid_
			, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, void_* BOOST_PP_INTERCEPT))
		{
			throw unhandled_alert();
		}

	} // namespace detail

	template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
		TORRENT_MAX_ALERT_TYPES, class T, detail::void_)>
	struct TORRENT_EXPORT handle_alert
	{
		template<class Handler>
		handle_alert(const std::auto_ptr<alert>& alert_
			, const Handler& handler)
		{
			#define ALERT_POINTER_TYPE(z, n, text) (BOOST_PP_CAT(T, n)*)0

			detail::handle_alert_dispatch(alert_, handler, typeid(*alert_)
				, BOOST_PP_ENUM(TORRENT_MAX_ALERT_TYPES, ALERT_POINTER_TYPE, _));

			#undef ALERT_POINTER_TYPE
		}
	};

} // namespace libtorrent

#endif // TORRENT_ALERT_HPP_INCLUDED

<commit_msg>added missing include directive<commit_after>/*

Copyright (c) 2003, Arvid Norberg, Daniel Wallin
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_ALERT_HPP_INCLUDED
#define TORRENT_ALERT_HPP_INCLUDED

#include <memory>
#include <queue>
#include <string>
#include <typeinfo>

#ifdef _MSC_VER
#pragma warning(push, 1)
#endif

#include <boost/thread/mutex.hpp>
#include <boost/thread/condition.hpp>
#include <boost/function.hpp>

#include <boost/preprocessor/repetition/enum_params_with_a_default.hpp>
#include <boost/preprocessor/repetition/enum.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_shifted_params.hpp>

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#include "libtorrent/time.hpp"
#include "libtorrent/config.hpp"
#include "libtorrent/assert.hpp"

#ifndef TORRENT_MAX_ALERT_TYPES
#define TORRENT_MAX_ALERT_TYPES 15
#endif

namespace libtorrent {

	class TORRENT_EXPORT alert
	{
	public:

		// only here for backwards compatibility
		enum severity_t { debug, info, warning, critical, fatal, none };

		enum category_t
		{
			error_notification = 0x1,
			peer_notification = 0x2,
			port_mapping_notification = 0x4,
			storage_notification = 0x8,
			tracker_notification = 0x10,
			debug_notification = 0x20,
			status_notification = 0x40,
			progress_notification = 0x80,
			ip_block_notification = 0x100,
			performance_warning = 0x200,
			dht_notification = 0x400,

			all_categories = 0xffffffff
		};

		alert();
		virtual ~alert();

		// a timestamp is automatically created in the constructor
		ptime timestamp() const;

		virtual char const* what() const = 0;
		virtual std::string message() const = 0;
		virtual int category() const = 0;

#ifndef TORRENT_NO_DEPRECATE
		severity_t severity() const TORRENT_DEPRECATED { return warning; }
#endif

		virtual std::auto_ptr<alert> clone() const = 0;

	private:
		ptime m_timestamp;
	};

	class TORRENT_EXPORT alert_manager
	{
	public:
		enum { queue_size_limit_default = 1000 };

		alert_manager();
		~alert_manager();

		void post_alert(const alert& alert_);
		bool pending() const;
		std::auto_ptr<alert> get();

		template <class T>
		bool should_post() const { return (m_alert_mask & T::static_category) != 0; }

		alert const* wait_for_alert(time_duration max_wait);

		void set_alert_mask(int m) { m_alert_mask = m; }

		size_t alert_queue_size_limit() const { return m_queue_size_limit; }
		size_t set_alert_queue_size_limit(size_t queue_size_limit_);

		void set_dispatch_function(boost::function<void(alert const&)> const&);

	private:
		std::queue<alert*> m_alerts;
		mutable boost::mutex m_mutex;
		boost::condition m_condition;
		int m_alert_mask;
		size_t m_queue_size_limit;
		boost::function<void(alert const&)> m_dispatch;
	};

	struct TORRENT_EXPORT unhandled_alert : std::exception
	{
		unhandled_alert() {}
	};

	namespace detail {

		struct void_;

		template<class Handler
			, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, class T)>
		void handle_alert_dispatch(
			const std::auto_ptr<alert>& alert_, const Handler& handler
			, const std::type_info& typeid_
			, BOOST_PP_ENUM_BINARY_PARAMS(TORRENT_MAX_ALERT_TYPES, T, *p))
		{
			if (typeid_ == typeid(T0))
				handler(*static_cast<T0*>(alert_.get()));
			else
				handle_alert_dispatch(alert_, handler, typeid_
					, BOOST_PP_ENUM_SHIFTED_PARAMS(
					TORRENT_MAX_ALERT_TYPES, p), (void_*)0);
		}

		template<class Handler>
		void handle_alert_dispatch(
			const std::auto_ptr<alert>& alert_
			, const Handler& handler
			, const std::type_info& typeid_
			, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, void_* BOOST_PP_INTERCEPT))
		{
			throw unhandled_alert();
		}

	} // namespace detail

	template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
		TORRENT_MAX_ALERT_TYPES, class T, detail::void_)>
	struct TORRENT_EXPORT handle_alert
	{
		template<class Handler>
		handle_alert(const std::auto_ptr<alert>& alert_
			, const Handler& handler)
		{
			#define ALERT_POINTER_TYPE(z, n, text) (BOOST_PP_CAT(T, n)*)0

			detail::handle_alert_dispatch(alert_, handler, typeid(*alert_)
				, BOOST_PP_ENUM(TORRENT_MAX_ALERT_TYPES, ALERT_POINTER_TYPE, _));

			#undef ALERT_POINTER_TYPE
		}
	};

} // namespace libtorrent

#endif // TORRENT_ALERT_HPP_INCLUDED

<|endoftext|>


<commit_before>#pragma once

class memory_manager
{
protected:
	memory_manager(unsigned int memory_size) : memory_size(memory_size) { };
public:
	struct block
	{
		const unsigned int start;
		const unsigned int size;

		block(unsigned int start, unsigned int size) : start(start), size(size) { };
	};

	const unsigned int memory_size;

	virtual block alloc(unsigned int size) = 0;
	virtual void free(block b) = 0;
};<commit_msg>added two comparers for block<commit_after>#pragma once

#include <functional>

class memory_manager
{
protected:
	memory_manager(unsigned int memory_size) : memory_size(memory_size) { };
public:
	struct block
	{
		const unsigned int start;
		const unsigned int size;

		block(unsigned int start, unsigned int size) : start(start), size(size) { };
	};

	const unsigned int memory_size;

	virtual block alloc(unsigned int size) = 0;
	virtual void free(block b) = 0;

	using compare_function = std::function<bool(const block&, const block&)>;

	static bool compare_increasing_size(const block& a, const block& b)
	{
		return a.size < b.size;
	}

	static bool compare_memory_location(const block& a, const block& b)
	{
		return a.start < b.start;
	}
};<|endoftext|>


<commit_before>#include <gtest/gtest.h>
#include <archie/utils/fused/nth.h>

namespace {
using archie::utils::fused::nth;
struct nth_test : ::testing::Test {};

TEST_F(nth_test, canUseNth) {
  char a = 0;
  int b = 1;
  float c = 2.0;

  auto& x = nth<0>(a, b, c);
  auto& y = nth<1>(a, b, c);
  auto& z = nth<2>(a, b, c);
  EXPECT_EQ(&a, &x);
  EXPECT_EQ(&b, &y);
  EXPECT_EQ(&c, &z);

  nth<0>(a, b, c) = 7;
  EXPECT_EQ(7, a);
}

TEST_F(nth_test, canUseConstNth) {
  const char a = 0;
  const int b = 1;
  const float c = 2.0;

  auto const& x = nth<0>(a, b, c);
  EXPECT_EQ(&a, &x);
}
}
<commit_msg>nth wraped in lambda<commit_after>#include <gtest/gtest.h>
#include <archie/utils/fused/nth.h>

namespace {
using archie::utils::fused::nth;
struct nth_test : ::testing::Test {};

TEST_F(nth_test, canUseNth) {
  char a = 0;
  int b = 1;
  float c = 2.0;

  auto& x = nth<0>(a, b, c);
  auto& y = nth<1>(a, b, c);
  auto& z = nth<2>(a, b, c);
  EXPECT_EQ(&a, &x);
  EXPECT_EQ(&b, &y);
  EXPECT_EQ(&c, &z);

  nth<0>(a, b, c) = 7;
  EXPECT_EQ(7, a);
}

TEST_F(nth_test, canUseConstNth) {
  const char a = 0;
  const int b = 1;
  const float c = 2.0;

  auto const& x = nth<0>(a, b, c);
  EXPECT_EQ(&a, &x);
}

TEST_F(nth_test, canWrapNthWithLambda) {
  const char a = 0;
  const int b = 1;
  const float c = 2.0;

  auto f = [](auto&&... args) -> decltype(auto) {
    return nth<0>(std::forward<decltype(args)>(args)...);
  };
  auto const& x = f(a, b, c);
  EXPECT_EQ(&a, &x);
}
}
<|endoftext|>


<commit_before>#ifndef VSMC_CORE_WEIGHT_HPP

#define VSMC_CORE_WEIGHT_HPP

#include <vsmc/internal/common.hpp>

namespace vsmc {

/// \brief Weight set class
/// \ingroup Core
class WeightSetBase
{
    public :

    /// The type of the weight and log weight vectors
    typedef Eigen::VectorXd weight_type;

    template <typename SizeType>
    explicit WeightSetBase (SizeType N) :
        ess_(static_cast<double>(N)), weight_(N), log_weight_(N),
        ess_cached_(false), weight_cached_(false), log_weight_cached_(false),
        zconst_(0), inc_weight_(N)
    {
        set_equal_weight();
    }

    /// Read only access to the weights
    const weight_type &weight () const
    {
        if (!weight_cached_) {
            weight_ = log_weight().array().exp();
            double sum = weight_.sum();
            weight_ *= 1 / sum;
            weight_cached_ = true;
        }

        return weight_;
    }

    /// Read only access to the weights
    template <typename SizeType, typename OutputIter>
    void weight (SizeType N, OutputIter *first) const
    {
        assert(weight_.size() >= N);
        std::copy(weight().data(), weight().data() + N, first);
    }

    /// Read only access to the log weights
    const weight_type &log_weight () const
    {
        if (!log_weight_cached_) {
            double max_weight = log_weight_.maxCoeff();
            log_weight_ = log_weight_.array() - max_weight;
            log_weight_cached_ = true;
        }

        return log_weight_;
    }

    /// Read only access to the log weights
    template <typename SizeType, typename OutputIter>
    void log_weight (SizeType N, OutputIter *first) const
    {
        VSMC_RUNTIME_ASSERT((log_weight_.size() >= N),
                "Size of weight set is too small")

        std::copy(log_weight().data(), log_weight().data() + N, first);
    }

    /// Set equal weights for all particles
    void set_equal_weight ()
    {
        ess_ = static_cast<double>(weight_.size());
        weight_.setConstant(1.0 / weight_.size());
        log_weight_.setConstant(0);

        ess_cached_ = true;
        weight_cached_ = true;
        log_weight_cached_ = true;
    }

    /// \brief Set the log weights with a pointer
    ///
    /// \param nw The position to start the reading, it shall be valid
    /// after increments of size() times.
    /// \param delta A multiplier appiled to the new log weights
    void set_log_weight (const double *nw, double delta = 1)
    {
        Eigen::Map<const weight_type> w(nw, log_weight_.size());
        set_log_weight(w, delta);
    }

    /// \brief Set the log weights with a Eigen object
    ///
    /// \param nw An Eigen::DenseBase object. One dimension Array, Vector,
    /// RowVector are supported. The Scalar type also need to be \c double.
    /// Otherwise it will be a compile-time error
    /// \param delta A multiplier appiled to the new log weights
    template <typename D>
    void set_log_weight (const Eigen::DenseBase<D> &nw, double delta = 1)
    {
        log_weight_ = nw.head(log_weight_.size());
        if (delta != 1)
            log_weight_ *= delta;
        set_weight();
    }

    /// \brief Add to the log weights with a pointer
    ///
    /// \param iw The position to start the reading, it shall be valid
    /// after increments of size() times.
    /// \param delta A multiplier appiled to the new incremental log weights
    /// \param add_zconst Whether this incremental weights shall contribute to
    /// the SMC normalizing constant estimate
    void add_log_weight (const double *iw, double delta = 1,
            bool add_zconst = true)
    {
        Eigen::Map<const weight_type> w(iw, log_weight_.size());
        add_log_weight(w, delta, add_zconst);
    }

    /// \brief Add to the log weights with a weight_object object
    ///
    /// \param iw An Eigen::DenseBase object. One dimension Array, Vector,
    /// RowVector are supported. The Scalar type also need to be \c double.
    /// Otherwise it will be a compile-time error
    /// \param delta A multiplier appiled to the new incremental log weights
    /// \param add_zconst Whether this incremental weights shall contribute to
    /// the SMC normalizing constant estimate
    template <typename D>
    void add_log_weight (const Eigen::DenseBase<D> &iw, double delta = 1,
            bool add_zconst = true)
    {
        using std::log;

        inc_weight_ = iw.head(log_weight_.size());
        if (delta != 1)
            inc_weight_ *= delta;
        log_weight_ += inc_weight_;
        if (add_zconst)
            zconst_ += log(weight().dot(inc_weight_.array().exp().matrix()));
        set_weight();
    }

    /// The current ESS (Effective Sample Size)
    double ess () const
    {
        if (!ess_cached_) {
            ess_ = 1 / weight().squaredNorm();
            ess_cached_ = true;
        }

        return ess_;
    }

    /// Get the value of the logarithm of SMC normalizing constant
    double zconst () const
    {
        return zconst_;
    }

    /// Reset the value of logarithm of SMC normalizing constant to zero
    void reset_zconst ()
    {
        zconst_ = 0;
    }

    private :

    mutable double ess_;
    mutable weight_type weight_;
    mutable weight_type log_weight_;

    mutable bool ess_cached_;
    mutable bool weight_cached_;
    mutable bool log_weight_cached_;

    double zconst_;
    weight_type inc_weight_;

    void set_weight ()
    {
        ess_cached_ = false;
        weight_cached_ = false;
        log_weight_cached_ = false;
    }
}; // class WeightSetBase

} // namespace vsmc

VSMC_DEFINE_TYPE_DISPATCH_TRAIT(WeightSetType, weight_set_type, WeightSetBase);

#endif // VSMC_CORE_WEIGHT_HPP
<commit_msg>cleanup<commit_after>#ifndef VSMC_CORE_WEIGHT_HPP
#define VSMC_CORE_WEIGHT_HPP

#include <vsmc/internal/common.hpp>

namespace vsmc {

/// \brief Weight set class
/// \ingroup Core
class WeightSetBase
{
    public :

    /// The type of the weight and log weight vectors
    typedef Eigen::VectorXd weight_type;

    template <typename SizeType>
    explicit WeightSetBase (SizeType N) :
        ess_(static_cast<double>(N)), weight_(N), log_weight_(N),
        ess_cached_(false), weight_cached_(false), log_weight_cached_(false),
        zconst_(0), inc_weight_(N)
    {
        set_equal_weight();
    }

    /// Read only access to the weights
    const weight_type &weight () const
    {
        if (!weight_cached_) {
            weight_ = log_weight().array().exp();
            double sum = weight_.sum();
            weight_ *= 1 / sum;
            weight_cached_ = true;
        }

        return weight_;
    }

    /// Read only access to the weights
    template <typename SizeType, typename OutputIter>
    void weight (SizeType N, OutputIter *first) const
    {
        assert(weight_.size() >= N);
        std::copy(weight().data(), weight().data() + N, first);
    }

    /// Read only access to the log weights
    const weight_type &log_weight () const
    {
        if (!log_weight_cached_) {
            double max_weight = log_weight_.maxCoeff();
            log_weight_ = log_weight_.array() - max_weight;
            log_weight_cached_ = true;
        }

        return log_weight_;
    }

    /// Read only access to the log weights
    template <typename SizeType, typename OutputIter>
    void log_weight (SizeType N, OutputIter *first) const
    {
        VSMC_RUNTIME_ASSERT((log_weight_.size() >= N),
                "Size of weight set is too small")

        std::copy(log_weight().data(), log_weight().data() + N, first);
    }

    /// Set equal weights for all particles
    void set_equal_weight ()
    {
        ess_ = static_cast<double>(weight_.size());
        weight_.setConstant(1.0 / weight_.size());
        log_weight_.setConstant(0);

        ess_cached_ = true;
        weight_cached_ = true;
        log_weight_cached_ = true;
    }

    /// \brief Set the log weights with a pointer
    ///
    /// \param nw The position to start the reading, it shall be valid
    /// after increments of size() times.
    /// \param delta A multiplier appiled to the new log weights
    void set_log_weight (const double *nw, double delta = 1)
    {
        Eigen::Map<const weight_type> w(nw, log_weight_.size());
        set_log_weight(w, delta);
    }

    /// \brief Set the log weights with a Eigen object
    ///
    /// \param nw An Eigen::DenseBase object. One dimension Array, Vector,
    /// RowVector are supported. The Scalar type also need to be \c double.
    /// Otherwise it will be a compile-time error
    /// \param delta A multiplier appiled to the new log weights
    template <typename D>
    void set_log_weight (const Eigen::DenseBase<D> &nw, double delta = 1)
    {
        log_weight_ = nw.head(log_weight_.size());
        if (delta != 1)
            log_weight_ *= delta;
        set_weight();
    }

    /// \brief Add to the log weights with a pointer
    ///
    /// \param iw The position to start the reading, it shall be valid
    /// after increments of size() times.
    /// \param delta A multiplier appiled to the new incremental log weights
    /// \param add_zconst Whether this incremental weights shall contribute to
    /// the SMC normalizing constant estimate
    void add_log_weight (const double *iw, double delta = 1,
            bool add_zconst = true)
    {
        Eigen::Map<const weight_type> w(iw, log_weight_.size());
        add_log_weight(w, delta, add_zconst);
    }

    /// \brief Add to the log weights with a weight_object object
    ///
    /// \param iw An Eigen::DenseBase object. One dimension Array, Vector,
    /// RowVector are supported. The Scalar type also need to be \c double.
    /// Otherwise it will be a compile-time error
    /// \param delta A multiplier appiled to the new incremental log weights
    /// \param add_zconst Whether this incremental weights shall contribute to
    /// the SMC normalizing constant estimate
    template <typename D>
    void add_log_weight (const Eigen::DenseBase<D> &iw, double delta = 1,
            bool add_zconst = true)
    {
        using std::log;

        inc_weight_ = iw.head(log_weight_.size());
        if (delta != 1)
            inc_weight_ *= delta;
        log_weight_ += inc_weight_;
        if (add_zconst)
            zconst_ += log(weight().dot(inc_weight_.array().exp().matrix()));
        set_weight();
    }

    /// The current ESS (Effective Sample Size)
    double ess () const
    {
        if (!ess_cached_) {
            ess_ = 1 / weight().squaredNorm();
            ess_cached_ = true;
        }

        return ess_;
    }

    /// Get the value of the logarithm of SMC normalizing constant
    double zconst () const
    {
        return zconst_;
    }

    /// Reset the value of logarithm of SMC normalizing constant to zero
    void reset_zconst ()
    {
        zconst_ = 0;
    }

    private :

    mutable double ess_;
    mutable weight_type weight_;
    mutable weight_type log_weight_;

    mutable bool ess_cached_;
    mutable bool weight_cached_;
    mutable bool log_weight_cached_;

    double zconst_;
    weight_type inc_weight_;

    void set_weight ()
    {
        ess_cached_ = false;
        weight_cached_ = false;
        log_weight_cached_ = false;
    }
}; // class WeightSetBase

} // namespace vsmc

VSMC_DEFINE_TYPE_DISPATCH_TRAIT(WeightSetType, weight_set_type, WeightSetBase);

#endif // VSMC_CORE_WEIGHT_HPP
<|endoftext|>


<commit_before>#include <isl/set.h>
#include <isl/union_map.h>
#include <isl/union_set.h>
#include <isl/ast_build.h>
#include <isl/schedule.h>
#include <isl/schedule_node.h>

#include <tiramisu/debug.h>
#include <tiramisu/core.h>

#include <string.h>
#include <Halide.h>
#include "halide_image_io.h"

using namespace tiramisu;

int main(int argc, char **argv)
{
    // Set default tiramisu options.
    global::set_default_tiramisu_options();
    global::set_loop_iterator_default_data_type(p_int32);

    tiramisu::function heat2d_tiramisu("heat2d_tiramisu");

    // Input params.
    float alpha = 0.3;
    float beta = 0.4;

    int SIZE0 = 10000;
    int SIZE1 = 10000;

    // Output buffers.
    int heat2d_extent_1 = SIZE1;
    int heat2d_extent_0 = SIZE0;
    tiramisu::buffer buff_heat2d("buff_heat2d", {tiramisu::expr(heat2d_extent_1), tiramisu::expr(heat2d_extent_0)}, tiramisu::p_float32, tiramisu::a_output, &heat2d_tiramisu);

    // Input buffers.
    int input_extent_1 = SIZE1;
    int input_extent_0 = SIZE0;
    tiramisu::buffer buff_input("buff_input", {tiramisu::expr(input_extent_1), tiramisu::expr(input_extent_0)}, tiramisu::p_float32, tiramisu::a_input, &heat2d_tiramisu);
    tiramisu::computation input("[input_extent_1, input_extent_0]->{input[i1, i0]: (0 <= i1 <= (input_extent_1 + -1)) and (0 <= i0 <= (input_extent_0 + -1))}", expr(), false, tiramisu::p_float32, &heat2d_tiramisu);
    input.set_access("{input[i1, i0]->buff_input[i1, i0]}");

    // Define loop bounds for dimension "heat2d_s0_y".
    tiramisu::constant heat2d_s0_y_loop_min("heat2d_s0_y_loop_min", tiramisu::expr((int32_t)0), tiramisu::p_int32, true, NULL, 0, &heat2d_tiramisu);
    tiramisu::constant heat2d_s0_y_loop_extent("heat2d_s0_y_loop_extent", tiramisu::expr(heat2d_extent_1), tiramisu::p_int32, true, NULL, 0, &heat2d_tiramisu);

    // Define loop bounds for dimension "heat2d_s0_x".
    tiramisu::constant heat2d_s0_x_loop_min("heat2d_s0_x_loop_min", tiramisu::expr((int32_t)0), tiramisu::p_int32, true, NULL, 0, &heat2d_tiramisu);
    tiramisu::constant heat2d_s0_x_loop_extent("heat2d_s0_x_loop_extent", tiramisu::expr(heat2d_extent_0), tiramisu::p_int32, true, NULL, 0, &heat2d_tiramisu);
    tiramisu::computation heat2d_s0("[heat2d_s0_y_loop_min, heat2d_s0_y_loop_extent, heat2d_s0_x_loop_min, heat2d_s0_x_loop_extent]->{heat2d_s0[heat2d_s0_y, heat2d_s0_x]: "
                        "(heat2d_s0_y_loop_min <= heat2d_s0_y <= ((heat2d_s0_y_loop_min + heat2d_s0_y_loop_extent) + -1)) and (heat2d_s0_x_loop_min <= heat2d_s0_x <= ((heat2d_s0_x_loop_min + heat2d_s0_x_loop_extent) + -1))}",
                        tiramisu::expr((float)0), true, tiramisu::p_float32, &heat2d_tiramisu);
    heat2d_s0.set_access("{heat2d_s0[heat2d_s0_y, heat2d_s0_x]->buff_heat2d[heat2d_s0_y, heat2d_s0_x]}");

    // Define loop bounds for dimension "heat2d_s1_r__y".
    tiramisu::constant heat2d_s1_r__y_loop_min("heat2d_s1_r__y_loop_min", tiramisu::expr((int32_t)1), tiramisu::p_int32, true, NULL, 0, &heat2d_tiramisu);
    tiramisu::constant heat2d_s1_r__y_loop_extent("heat2d_s1_r__y_loop_extent", (tiramisu::expr(input_extent_1) + tiramisu::expr((int32_t)-2)), tiramisu::p_int32, true, NULL, 0, &heat2d_tiramisu);

    // Define loop bounds for dimension "heat2d_s1_r__x".
    tiramisu::constant heat2d_s1_r__x_loop_min("heat2d_s1_r__x_loop_min", tiramisu::expr((int32_t)1), tiramisu::p_int32, true, NULL, 0, &heat2d_tiramisu);
    tiramisu::constant heat2d_s1_r__x_loop_extent("heat2d_s1_r__x_loop_extent", (tiramisu::expr(input_extent_0) + tiramisu::expr((int32_t)-2)), tiramisu::p_int32, true, NULL, 0, &heat2d_tiramisu);
    tiramisu::computation heat2d_s1(
        "[heat2d_s1_r__y_loop_min, heat2d_s1_r__y_loop_extent, heat2d_s1_r__x_loop_min, heat2d_s1_r__x_loop_extent]->{heat2d_s1[heat2d_s1_r__y, heat2d_s1_r__x]: "
        "(heat2d_s1_r__y_loop_min <= heat2d_s1_r__y <= ((heat2d_s1_r__y_loop_min + heat2d_s1_r__y_loop_extent) + -1)) and (heat2d_s1_r__x_loop_min <= heat2d_s1_r__x <= ((heat2d_s1_r__x_loop_min + heat2d_s1_r__x_loop_extent) + -1))}",
        tiramisu::expr(), true, tiramisu::p_float32, &heat2d_tiramisu);
    heat2d_s1.set_expression(((tiramisu::expr(alpha) * input(tiramisu::var("heat2d_s1_r__y"), tiramisu::var("heat2d_s1_r__x"))) + (tiramisu::expr(beta) * (((input(tiramisu::var("heat2d_s1_r__y"), (tiramisu::var("heat2d_s1_r__x") + tiramisu::expr((int32_t)1))) + input(tiramisu::var("heat2d_s1_r__y"), (tiramisu::var("heat2d_s1_r__x") - tiramisu::expr((int32_t)1)))) + input((tiramisu::var("heat2d_s1_r__y") + tiramisu::expr((int32_t)1)), tiramisu::var("heat2d_s1_r__x"))) + input((tiramisu::var("heat2d_s1_r__y") - tiramisu::expr((int32_t)1)), tiramisu::var("heat2d_s1_r__x"))))));
    heat2d_s1.set_access("{heat2d_s1[heat2d_s1_r__y, heat2d_s1_r__x]->buff_heat2d[heat2d_s1_r__y, heat2d_s1_r__x]}");

    heat2d_tiramisu.add_context_constraints("[heat2d_s1_r__y_loop_min, heat2d_s1_r__y_loop_extent, heat2d_s1_r__x_loop_min, heat2d_s1_r__x_loop_extent]->{heat2d_s1_r__y_loop_min = 0 and heat2d_s1_r__y_loop_extent%8=0 and heat2d_s1_r__x_loop_min = 0 and heat2d_s1_r__x_loop_extent%8=0 and heat2d_s0_y_loop_min = 0 and heat2d_s0_y_loop_extent%8=0 and heat2d_s0_x_loop_min=0 and heat2d_s0_x_loop_extent%8=0}");

    // Define compute level for "heat2d".
    heat2d_s1.after(heat2d_s0, computation::root);

    // Declare vars.
    tiramisu::var heat2d_s0_x("heat2d_s0_x");
    tiramisu::var heat2d_s0_y("heat2d_s0_y");
    tiramisu::var heat2d_s1_r__x("heat2d_s1_r__x");
    tiramisu::var heat2d_s1_r__y("heat2d_s1_r__y");

    // Add schedules.
    heat2d_s0.tag_parallel_level(heat2d_s0_y);
    heat2d_s0.vectorize(heat2d_s0_x, 8);
    heat2d_s1.tag_parallel_level(heat2d_s1_r__y);
    heat2d_s1.vectorize(heat2d_s1_r__x, 8);

    heat2d_tiramisu.set_arguments({&buff_input, &buff_heat2d});
    heat2d_tiramisu.gen_time_space_domain();
    heat2d_tiramisu.gen_isl_ast();
    heat2d_tiramisu.gen_halide_stmt();
    heat2d_tiramisu.dump_halide_stmt();
    heat2d_tiramisu.gen_halide_obj("build/generated_fct_heat2d.o");

    return 0;
}
<commit_msg>fix benchmark<commit_after>#include <isl/set.h>
#include <isl/union_map.h>
#include <isl/union_set.h>
#include <isl/ast_build.h>
#include <isl/schedule.h>
#include <isl/schedule_node.h>

#include <tiramisu/debug.h>
#include <tiramisu/core.h>

#include <string.h>
#include <Halide.h>
#include "halide_image_io.h"

using namespace tiramisu;

int main(int argc, char **argv)
{
    // Set default tiramisu options.
    global::set_default_tiramisu_options();

    tiramisu::function heat2d_tiramisu("heat2d_tiramisu");

    // Input params.
    float alpha = 0.3;
    float beta = 0.4;

    int SIZE0 = 10000;
    int SIZE1 = 10000;

    // Output buffers.
    int heat2d_extent_1 = SIZE1;
    int heat2d_extent_0 = SIZE0;
    tiramisu::buffer buff_heat2d("buff_heat2d", {tiramisu::expr(heat2d_extent_1), tiramisu::expr(heat2d_extent_0)}, tiramisu::p_float32, tiramisu::a_output, &heat2d_tiramisu);

    // Input buffers.
    int input_extent_1 = SIZE1;
    int input_extent_0 = SIZE0;
    tiramisu::buffer buff_input("buff_input", {tiramisu::expr(input_extent_1), tiramisu::expr(input_extent_0)}, tiramisu::p_float32, tiramisu::a_input, &heat2d_tiramisu);
    tiramisu::computation input("[input_extent_1, input_extent_0]->{input[i1, i0]: (0 <= i1 <= (input_extent_1 + -1)) and (0 <= i0 <= (input_extent_0 + -1))}", expr(), false, tiramisu::p_float32, &heat2d_tiramisu);
    input.set_access("{input[i1, i0]->buff_input[i1, i0]}");

    // Define loop bounds for dimension "heat2d_s0_y".
    tiramisu::constant heat2d_s0_y_loop_min("heat2d_s0_y_loop_min", tiramisu::expr((int32_t)0), tiramisu::p_int32, true, NULL, 0, &heat2d_tiramisu);
    tiramisu::constant heat2d_s0_y_loop_extent("heat2d_s0_y_loop_extent", tiramisu::expr(heat2d_extent_1), tiramisu::p_int32, true, NULL, 0, &heat2d_tiramisu);

    // Define loop bounds for dimension "heat2d_s0_x".
    tiramisu::constant heat2d_s0_x_loop_min("heat2d_s0_x_loop_min", tiramisu::expr((int32_t)0), tiramisu::p_int32, true, NULL, 0, &heat2d_tiramisu);
    tiramisu::constant heat2d_s0_x_loop_extent("heat2d_s0_x_loop_extent", tiramisu::expr(heat2d_extent_0), tiramisu::p_int32, true, NULL, 0, &heat2d_tiramisu);
    tiramisu::computation heat2d_s0("[heat2d_s0_y_loop_min, heat2d_s0_y_loop_extent, heat2d_s0_x_loop_min, heat2d_s0_x_loop_extent]->{heat2d_s0[heat2d_s0_y, heat2d_s0_x]: "
                        "(heat2d_s0_y_loop_min <= heat2d_s0_y <= ((heat2d_s0_y_loop_min + heat2d_s0_y_loop_extent) + -1)) and (heat2d_s0_x_loop_min <= heat2d_s0_x <= ((heat2d_s0_x_loop_min + heat2d_s0_x_loop_extent) + -1))}",
                        tiramisu::expr((float)0), true, tiramisu::p_float32, &heat2d_tiramisu);
    heat2d_s0.set_access("{heat2d_s0[heat2d_s0_y, heat2d_s0_x]->buff_heat2d[heat2d_s0_y, heat2d_s0_x]}");

    // Define loop bounds for dimension "heat2d_s1_r__y".
    tiramisu::constant heat2d_s1_r__y_loop_min("heat2d_s1_r__y_loop_min", tiramisu::expr((int32_t)1), tiramisu::p_int32, true, NULL, 0, &heat2d_tiramisu);
    tiramisu::constant heat2d_s1_r__y_loop_extent("heat2d_s1_r__y_loop_extent", (tiramisu::expr(input_extent_1) + tiramisu::expr((int32_t)-2)), tiramisu::p_int32, true, NULL, 0, &heat2d_tiramisu);

    // Define loop bounds for dimension "heat2d_s1_r__x".
    tiramisu::constant heat2d_s1_r__x_loop_min("heat2d_s1_r__x_loop_min", tiramisu::expr((int32_t)1), tiramisu::p_int32, true, NULL, 0, &heat2d_tiramisu);
    tiramisu::constant heat2d_s1_r__x_loop_extent("heat2d_s1_r__x_loop_extent", (tiramisu::expr(input_extent_0) + tiramisu::expr((int32_t)-2)), tiramisu::p_int32, true, NULL, 0, &heat2d_tiramisu);
    tiramisu::computation heat2d_s1(
        "[heat2d_s1_r__y_loop_min, heat2d_s1_r__y_loop_extent, heat2d_s1_r__x_loop_min, heat2d_s1_r__x_loop_extent]->{heat2d_s1[heat2d_s1_r__y, heat2d_s1_r__x]: "
        "(heat2d_s1_r__y_loop_min <= heat2d_s1_r__y <= ((heat2d_s1_r__y_loop_min + heat2d_s1_r__y_loop_extent) + -1)) and (heat2d_s1_r__x_loop_min <= heat2d_s1_r__x <= ((heat2d_s1_r__x_loop_min + heat2d_s1_r__x_loop_extent) + -1))}",
        tiramisu::expr(), true, tiramisu::p_float32, &heat2d_tiramisu);
    heat2d_s1.set_expression(((tiramisu::expr(alpha) * input(tiramisu::var("heat2d_s1_r__y"), tiramisu::var("heat2d_s1_r__x"))) + (tiramisu::expr(beta) * (((input(tiramisu::var("heat2d_s1_r__y"), (tiramisu::var("heat2d_s1_r__x") + tiramisu::expr((int32_t)1))) + input(tiramisu::var("heat2d_s1_r__y"), (tiramisu::var("heat2d_s1_r__x") - tiramisu::expr((int32_t)1)))) + input((tiramisu::var("heat2d_s1_r__y") + tiramisu::expr((int32_t)1)), tiramisu::var("heat2d_s1_r__x"))) + input((tiramisu::var("heat2d_s1_r__y") - tiramisu::expr((int32_t)1)), tiramisu::var("heat2d_s1_r__x"))))));
    heat2d_s1.set_access("{heat2d_s1[heat2d_s1_r__y, heat2d_s1_r__x]->buff_heat2d[heat2d_s1_r__y, heat2d_s1_r__x]}");

    heat2d_tiramisu.add_context_constraints("[heat2d_s1_r__y_loop_min, heat2d_s1_r__y_loop_extent, heat2d_s1_r__x_loop_min, heat2d_s1_r__x_loop_extent]->{heat2d_s1_r__y_loop_min = 0 and heat2d_s1_r__y_loop_extent%8=0 and heat2d_s1_r__x_loop_min = 0 and heat2d_s1_r__x_loop_extent%8=0 and heat2d_s0_y_loop_min = 0 and heat2d_s0_y_loop_extent%8=0 and heat2d_s0_x_loop_min=0 and heat2d_s0_x_loop_extent%8=0}");

    // Define compute level for "heat2d".
    heat2d_s1.after(heat2d_s0, computation::root);

    // Declare vars.
    tiramisu::var heat2d_s0_x("heat2d_s0_x");
    tiramisu::var heat2d_s0_y("heat2d_s0_y");
    tiramisu::var heat2d_s1_r__x("heat2d_s1_r__x");
    tiramisu::var heat2d_s1_r__y("heat2d_s1_r__y");

    // Add schedules.
    heat2d_s0.tag_parallel_level(heat2d_s0_y);
    heat2d_s0.vectorize(heat2d_s0_x, 8);
    heat2d_s1.tag_parallel_level(heat2d_s1_r__y);
    heat2d_s1.vectorize(heat2d_s1_r__x, 8);

    heat2d_tiramisu.set_arguments({&buff_input, &buff_heat2d});
    heat2d_tiramisu.gen_time_space_domain();
    heat2d_tiramisu.gen_isl_ast();
    heat2d_tiramisu.gen_halide_stmt();
    heat2d_tiramisu.dump_halide_stmt();
    heat2d_tiramisu.gen_halide_obj("build/generated_fct_heat2d.o");

    return 0;
}
<|endoftext|>


<commit_before>/*******************************************************************************
 *
 * MIT License
 *
 * Copyright (c) 2017 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 *******************************************************************************/

#ifndef MIOPEN_RNN_UTIL_H_
#define MIOPEN_RNN_UTIL_H_

#include <cfloat>
#include <cmath>
#include <initializer_list>
#include <set>
#include <vector>
#include <cstdlib>

#define RNN_MM_TRANSPOSE 1

// RNN VANILLA configs
inline std::vector<int> get_rnn_num_layers()
{
    // return {{1, 5, 20}};
    return {{1, 19}};
}

inline std::vector<int> get_rnn_batchSize()
{
    // return {128};
    return {{31, 127}};
}

inline std::vector<int> get_rnn_seq_len()
{
    // return {50};
    return {{3, 51}};
}

inline std::vector<int> get_rnn_vector_len()
{
    // return {32};
    return {{5, 31}};
}

inline std::vector<int> get_rnn_hidden_size()
{
    // return {{16,64,128,256,1760,2048,2560}};
    return {{65, 127}};
}

// LSTM configs
inline std::vector<int> get_lstm_num_layers() { return {{1, 5}}; }

inline std::vector<int> get_lstm_batchSize()
{
    // return {16};
    return {{53}};
}

inline std::vector<int> get_lstm_seq_len()
{
    return {25};
    // return {{2, 50}};
}

inline std::vector<int> get_lstm_vector_len()
{
    return {17};
    // return {{4, 32}};
}

inline std::vector<int> get_lstm_hidden_size()
{
    return {67};
    // return {{16,64,128,256,1760,2048,2560}};
}

// GRU configs
inline std::vector<int> get_gru_num_layers() { return {{1, 5}}; }

inline std::vector<int> get_gru_batchSize()
{
    // return {16};
    return {{53}};
}

inline std::vector<int> get_gru_seq_len()
{
    return {23};
    // return {{2, 50}};
}

inline std::vector<int> get_gru_vector_len()
{
    return {13};
    // return {{4, 32}};
}

inline std::vector<int> get_gru_hidden_size()
{
    return {67};
    // return {{16,64,128,256,1760,2048,2560}};
}

inline std::vector<std::vector<int>> generate_batchSeq(const int batchSize, const int seqLength)
{

    int modval = 3;
    srand(modval);
    int currentval = batchSize;
    std::vector<int> batchSeq;
    for(int i = 0; i < seqLength; i++)
    {
        if(i > 0)
        {
            int nvalue = currentval - rand() % modval;
            currentval = (nvalue < 1) ? 1 : nvalue;
            // printf("current value: %d\n", currentval);
        }
        // printf("adding a value to batch sequence: %d\n", currentval);
        batchSeq.push_back(currentval);
    }
    return {batchSeq};
}

inline int sumvc(std::vector<int>& x)
{
    int sum = 0;
    for(int i = 0; i < x.size(); i++)
    {
        sum += x[i];
    }
    return sum;
}

inline float activfunc(float x, int actvf)
{
    float alpha = 1, beta0 = 0, beta1 = 1;
    if(actvf == 0)
    {
        //        float y = 0;
        //        return std::max(x, y);
        return (x > 0) ? x : x * beta0;
    }
    else if(actvf == 2)
    {
        return 1 / (1 + exp(-x));
    }

    //    return tanh(x);
    return alpha * tanh(beta1 * x);
}

inline float dervactivfunc(float x, int actvf)
{
    if(actvf == 0)
    {
        return (x > 0 ? 1 : 0);
    }
    else if(actvf == 2)
    {
        return exp(-x) / (1 + exp(-x)) / (1 + exp(-x));
    }

    return 1 / cosh(x) / cosh(x);
}

template <typename Dtype>
void RNN_mm_cpu(const Dtype* a_ptr,
                size_t a_cols,
                size_t a_rows,
                size_t a_stride,
                int a_flags,
                const Dtype* b_ptr,
                size_t b_cols,
                size_t b_rows,
                size_t b_stride,
                int b_flags,
                Dtype* c_ptr,
                size_t c_cols,
                size_t c_rows,
                size_t c_stride,
                int /*c_flags*/,
                double d_alpha,
                double d_beta)
{

    Dtype alpha = Dtype(d_alpha);
    Dtype beta  = Dtype(d_beta);
    if((!(a_flags & RNN_MM_TRANSPOSE) && !(b_flags & RNN_MM_TRANSPOSE) &&
        ((a_cols != b_rows) || (a_rows != c_rows) || (b_cols != c_cols))) ||
       ((a_flags & RNN_MM_TRANSPOSE) && (b_flags & RNN_MM_TRANSPOSE) &&
        ((a_rows != b_cols) || (a_cols != c_rows) || (b_rows != c_cols))) ||
       ((a_flags & RNN_MM_TRANSPOSE) && !(b_flags & RNN_MM_TRANSPOSE) &&
        ((a_rows != b_rows) || (a_cols != c_rows) || (b_cols != c_cols))) ||
       (!(a_flags & RNN_MM_TRANSPOSE) && (b_flags & RNN_MM_TRANSPOSE) &&
        ((a_cols != b_cols) || (a_rows != c_rows) || (b_rows != c_cols))))
    {
        printf("MM_CPU ERROR; %zd %zd   %zd %zd   %zd %zd\n",
               a_cols,
               a_rows,
               b_cols,
               b_rows,
               c_rows,
               c_cols);
        return;
    }

    size_t inner_loop = (!(a_flags & RNN_MM_TRANSPOSE)) ? a_cols : a_rows;

    if(!(a_flags & RNN_MM_TRANSPOSE) && !(b_flags & RNN_MM_TRANSPOSE))
    {
        for(size_t n = 0; n < c_rows; ++n)
        {
            for(size_t k = 0; k < c_cols; ++k)
            {
                Dtype mm_e = 0;
                for(size_t m = 0; m < inner_loop; ++m)
                {
                    mm_e += a_ptr[n * a_stride + m] * b_ptr[m * b_stride + k];
                }
                c_ptr[n * c_stride + k] = beta * c_ptr[n * c_stride + k] + alpha * mm_e;
            }
        }
    }
    else if((a_flags & RNN_MM_TRANSPOSE) && !(b_flags & RNN_MM_TRANSPOSE))
    {
        for(size_t n = 0; n < c_rows; ++n)
        {
            for(size_t k = 0; k < c_cols; ++k)
            {

                Dtype mm_e = 0;
                for(size_t m = 0; m < inner_loop; ++m)
                {
                    mm_e += a_ptr[m * a_stride + n] * b_ptr[m * b_stride + k];
#if 0
					if (
						(n == 0 && k == 33
						|| n == 1 && k == 32
						|| n == 3 && k == 1
						|| n == 4 && k == 0

						)
						&& a_ptr[m*a_stride + n] * b_ptr[m*b_stride + k] != 0
						)
					{
						printf("C:mm:%d %d %d   %11.9f %11.9f %11.9f %11.9f\n",
							n, k, m,
							mm_e, a_ptr[m*a_stride + n], b_ptr[m*b_stride + k], a_ptr[m*a_stride + n] * b_ptr[m*b_stride + k]);
					}
#endif
                }
                c_ptr[n * c_stride + k] = beta * c_ptr[n * c_stride + k] + alpha * mm_e;
            }
        }
    }
    else if(!(a_flags & RNN_MM_TRANSPOSE) && (b_flags & RNN_MM_TRANSPOSE))
    {
        for(size_t n = 0; n < c_rows; ++n)
        {
            for(size_t k = 0; k < c_cols; ++k)
            {
                Dtype mm_e = 0;

                for(size_t m = 0; m < inner_loop; ++m)
                {
                    mm_e += a_ptr[n * a_stride + m] * b_ptr[k * b_stride + m];
#if 0
					if (n == 0 && k == 6 && a_ptr[n*a_stride + m] * b_ptr[k*b_stride + m] != 0)
					{
						printf("%4d  %11.9f %11.9f %11.9f\n", m, mm_e, a_ptr[n*a_stride + m], b_ptr[k*b_stride + m]);
					}
#endif
                }
                c_ptr[n * c_stride + k] = beta * c_ptr[n * c_stride + k] + alpha * mm_e;
            }
        }
    }
    else
    {
        for(size_t n = 0; n < c_rows; ++n)
        {
            for(size_t k = 0; k < c_cols; ++k)
            {
                Dtype mm_e = 0;
                for(size_t m = 0; m < inner_loop; ++m)
                {
                    c_ptr[n * c_stride + k] += a_ptr[m * a_stride + n] * b_ptr[k * b_stride + m];
                }
                c_ptr[n * c_stride + k] = beta * c_ptr[n * c_stride + k] + alpha * mm_e;
            }
        }
    }
}

#endif
<commit_msg>Removed curly braces<commit_after>/*******************************************************************************
 *
 * MIT License
 *
 * Copyright (c) 2017 Advanced Micro Devices, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 *******************************************************************************/

#ifndef MIOPEN_RNN_UTIL_H_
#define MIOPEN_RNN_UTIL_H_

#include <cfloat>
#include <cmath>
#include <initializer_list>
#include <set>
#include <vector>
#include <cstdlib>

#define RNN_MM_TRANSPOSE 1

// RNN VANILLA configs
inline std::vector<int> get_rnn_num_layers()
{
    // return {{1, 5, 20}};
    return {{1, 19}};
}

inline std::vector<int> get_rnn_batchSize()
{
    // return {128};
    return {{31, 127}};
}

inline std::vector<int> get_rnn_seq_len()
{
    // return {50};
    return {{3, 51}};
}

inline std::vector<int> get_rnn_vector_len()
{
    // return {32};
    return {{5, 31}};
}

inline std::vector<int> get_rnn_hidden_size()
{
    // return {{16,64,128,256,1760,2048,2560}};
    return {{65, 127}};
}

// LSTM configs
inline std::vector<int> get_lstm_num_layers() { return {{1, 5}}; }

inline std::vector<int> get_lstm_batchSize()
{
    // return {16};
    return {53};
}

inline std::vector<int> get_lstm_seq_len()
{
    return {25};
    // return {{2, 50}};
}

inline std::vector<int> get_lstm_vector_len()
{
    return {17};
    // return {{4, 32}};
}

inline std::vector<int> get_lstm_hidden_size()
{
    return {67};
    // return {{16,64,128,256,1760,2048,2560}};
}

// GRU configs
inline std::vector<int> get_gru_num_layers() { return {{1, 5}}; }

inline std::vector<int> get_gru_batchSize()
{
    // return {16};
    return {53};
}

inline std::vector<int> get_gru_seq_len()
{
    return {23};
    // return {{2, 50}};
}

inline std::vector<int> get_gru_vector_len()
{
    return {13};
    // return {{4, 32}};
}

inline std::vector<int> get_gru_hidden_size()
{
    return {67};
    // return {{16,64,128,256,1760,2048,2560}};
}

inline std::vector<std::vector<int>> generate_batchSeq(const int batchSize, const int seqLength)
{

    int modval = 3;
    srand(modval);
    int currentval = batchSize;
    std::vector<int> batchSeq;
    for(int i = 0; i < seqLength; i++)
    {
        if(i > 0)
        {
            int nvalue = currentval - rand() % modval;
            currentval = (nvalue < 1) ? 1 : nvalue;
            // printf("current value: %d\n", currentval);
        }
        // printf("adding a value to batch sequence: %d\n", currentval);
        batchSeq.push_back(currentval);
    }
    return {batchSeq};
}

inline int sumvc(std::vector<int>& x)
{
    int sum = 0;
    for(int i = 0; i < x.size(); i++)
    {
        sum += x[i];
    }
    return sum;
}

inline float activfunc(float x, int actvf)
{
    float alpha = 1, beta0 = 0, beta1 = 1;
    if(actvf == 0)
    {
        //        float y = 0;
        //        return std::max(x, y);
        return (x > 0) ? x : x * beta0;
    }
    else if(actvf == 2)
    {
        return 1 / (1 + exp(-x));
    }

    //    return tanh(x);
    return alpha * tanh(beta1 * x);
}

inline float dervactivfunc(float x, int actvf)
{
    if(actvf == 0)
    {
        return (x > 0 ? 1 : 0);
    }
    else if(actvf == 2)
    {
        return exp(-x) / (1 + exp(-x)) / (1 + exp(-x));
    }

    return 1 / cosh(x) / cosh(x);
}

template <typename Dtype>
void RNN_mm_cpu(const Dtype* a_ptr,
                size_t a_cols,
                size_t a_rows,
                size_t a_stride,
                int a_flags,
                const Dtype* b_ptr,
                size_t b_cols,
                size_t b_rows,
                size_t b_stride,
                int b_flags,
                Dtype* c_ptr,
                size_t c_cols,
                size_t c_rows,
                size_t c_stride,
                int /*c_flags*/,
                double d_alpha,
                double d_beta)
{

    Dtype alpha = Dtype(d_alpha);
    Dtype beta  = Dtype(d_beta);
    if((!(a_flags & RNN_MM_TRANSPOSE) && !(b_flags & RNN_MM_TRANSPOSE) &&
        ((a_cols != b_rows) || (a_rows != c_rows) || (b_cols != c_cols))) ||
       ((a_flags & RNN_MM_TRANSPOSE) && (b_flags & RNN_MM_TRANSPOSE) &&
        ((a_rows != b_cols) || (a_cols != c_rows) || (b_rows != c_cols))) ||
       ((a_flags & RNN_MM_TRANSPOSE) && !(b_flags & RNN_MM_TRANSPOSE) &&
        ((a_rows != b_rows) || (a_cols != c_rows) || (b_cols != c_cols))) ||
       (!(a_flags & RNN_MM_TRANSPOSE) && (b_flags & RNN_MM_TRANSPOSE) &&
        ((a_cols != b_cols) || (a_rows != c_rows) || (b_rows != c_cols))))
    {
        printf("MM_CPU ERROR; %zd %zd   %zd %zd   %zd %zd\n",
               a_cols,
               a_rows,
               b_cols,
               b_rows,
               c_rows,
               c_cols);
        return;
    }

    size_t inner_loop = (!(a_flags & RNN_MM_TRANSPOSE)) ? a_cols : a_rows;

    if(!(a_flags & RNN_MM_TRANSPOSE) && !(b_flags & RNN_MM_TRANSPOSE))
    {
        for(size_t n = 0; n < c_rows; ++n)
        {
            for(size_t k = 0; k < c_cols; ++k)
            {
                Dtype mm_e = 0;
                for(size_t m = 0; m < inner_loop; ++m)
                {
                    mm_e += a_ptr[n * a_stride + m] * b_ptr[m * b_stride + k];
                }
                c_ptr[n * c_stride + k] = beta * c_ptr[n * c_stride + k] + alpha * mm_e;
            }
        }
    }
    else if((a_flags & RNN_MM_TRANSPOSE) && !(b_flags & RNN_MM_TRANSPOSE))
    {
        for(size_t n = 0; n < c_rows; ++n)
        {
            for(size_t k = 0; k < c_cols; ++k)
            {

                Dtype mm_e = 0;
                for(size_t m = 0; m < inner_loop; ++m)
                {
                    mm_e += a_ptr[m * a_stride + n] * b_ptr[m * b_stride + k];
#if 0
					if (
						(n == 0 && k == 33
						|| n == 1 && k == 32
						|| n == 3 && k == 1
						|| n == 4 && k == 0

						)
						&& a_ptr[m*a_stride + n] * b_ptr[m*b_stride + k] != 0
						)
					{
						printf("C:mm:%d %d %d   %11.9f %11.9f %11.9f %11.9f\n",
							n, k, m,
							mm_e, a_ptr[m*a_stride + n], b_ptr[m*b_stride + k], a_ptr[m*a_stride + n] * b_ptr[m*b_stride + k]);
					}
#endif
                }
                c_ptr[n * c_stride + k] = beta * c_ptr[n * c_stride + k] + alpha * mm_e;
            }
        }
    }
    else if(!(a_flags & RNN_MM_TRANSPOSE) && (b_flags & RNN_MM_TRANSPOSE))
    {
        for(size_t n = 0; n < c_rows; ++n)
        {
            for(size_t k = 0; k < c_cols; ++k)
            {
                Dtype mm_e = 0;

                for(size_t m = 0; m < inner_loop; ++m)
                {
                    mm_e += a_ptr[n * a_stride + m] * b_ptr[k * b_stride + m];
#if 0
					if (n == 0 && k == 6 && a_ptr[n*a_stride + m] * b_ptr[k*b_stride + m] != 0)
					{
						printf("%4d  %11.9f %11.9f %11.9f\n", m, mm_e, a_ptr[n*a_stride + m], b_ptr[k*b_stride + m]);
					}
#endif
                }
                c_ptr[n * c_stride + k] = beta * c_ptr[n * c_stride + k] + alpha * mm_e;
            }
        }
    }
    else
    {
        for(size_t n = 0; n < c_rows; ++n)
        {
            for(size_t k = 0; k < c_cols; ++k)
            {
                Dtype mm_e = 0;
                for(size_t m = 0; m < inner_loop; ++m)
                {
                    c_ptr[n * c_stride + k] += a_ptr[m * a_stride + n] * b_ptr[k * b_stride + m];
                }
                c_ptr[n * c_stride + k] = beta * c_ptr[n * c_stride + k] + alpha * mm_e;
            }
        }
    }
}

#endif
<|endoftext|>


<commit_before>/*
 * High level FastCGI client.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "Request.hxx"
#include "Stock.hxx"
#include "Client.hxx"
#include "http_response.hxx"
#include "lease.hxx"
#include "tcp_stock.hxx"
#include "stock/Stock.hxx"
#include "stock/Item.hxx"
#include "spawn/ChildOptions.hxx"
#include "istream/istream.hxx"
#include "async.hxx"
#include "pool.hxx"
#include "util/Cast.hxx"
#include "util/ConstBuffer.hxx"

#include <daemon/log.h>

#include <sys/socket.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

struct FcgiRequest final : Lease {
    struct pool &pool;

    StockItem *stock_item;

    struct async_operation operation;
    struct async_operation_ref async_ref;

    FcgiRequest(struct pool &_pool, StockItem &_stock_item)
        :pool(_pool), stock_item(&_stock_item) {
        operation.Init2<FcgiRequest>();
    }

    void Abort() {
        if (stock_item != nullptr)
            fcgi_stock_aborted(*stock_item);

        async_ref.Abort();
    }

    /* virtual methods from class Lease */
    void ReleaseLease(bool reuse) override {
        stock_item->Put(!reuse);
        stock_item = nullptr;
    }
};

void
fcgi_request(struct pool *pool, EventLoop &event_loop,
             FcgiStock *fcgi_stock,
             const ChildOptions &options,
             const char *action,
             const char *path,
             ConstBuffer<const char *> args,
             http_method_t method, const char *uri,
             const char *script_name, const char *path_info,
             const char *query_string,
             const char *document_root,
             const char *remote_addr,
             const StringMap &headers, Istream *body,
             ConstBuffer<const char *> params,
             int stderr_fd,
             HttpResponseHandler &handler,
             struct async_operation_ref &async_ref)
{
    if (action == nullptr)
        action = path;

    GError *error = nullptr;
    StockItem *stock_item =
        fcgi_stock_get(fcgi_stock, pool, options,
                       action,
                       args,
                       &error);
    if (stock_item == nullptr) {
        if (body != nullptr)
            body->CloseUnused();

        if (stderr_fd >= 0)
            close(stderr_fd);

        handler.InvokeError(error);
        return;
    }

    auto request = NewFromPool<FcgiRequest>(*pool, *pool, *stock_item);

    async_ref.Set(request->operation);

    const char *script_filename = fcgi_stock_translate_path(*stock_item, path,
                                                            &request->pool);
    document_root = fcgi_stock_translate_path(*stock_item, document_root,
                                              &request->pool);

    fcgi_client_request(&request->pool, event_loop,
                        fcgi_stock_item_get(*stock_item),
                        fcgi_stock_item_get_domain(*stock_item) == AF_LOCAL
                        ? FdType::FD_SOCKET : FdType::FD_TCP,
                        *request,
                        method, uri,
                        script_filename,
                        script_name, path_info,
                        query_string,
                        document_root,
                        remote_addr,
                        headers, body,
                        params,
                        stderr_fd,
                        handler, request->async_ref);
}
<commit_msg>fcgi/request: migrate to class Cancellable<commit_after>/*
 * High level FastCGI client.
 *
 * author: Max Kellermann <mk@cm4all.com>
 */

#include "Request.hxx"
#include "Stock.hxx"
#include "Client.hxx"
#include "http_response.hxx"
#include "lease.hxx"
#include "tcp_stock.hxx"
#include "stock/Stock.hxx"
#include "stock/Item.hxx"
#include "spawn/ChildOptions.hxx"
#include "istream/istream.hxx"
#include "async.hxx"
#include "pool.hxx"
#include "util/Cast.hxx"
#include "util/ConstBuffer.hxx"

#include <daemon/log.h>

#include <sys/socket.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>

struct FcgiRequest final : Lease, Cancellable {
    struct pool &pool;

    StockItem *stock_item;

    struct async_operation_ref async_ref;

    FcgiRequest(struct pool &_pool, StockItem &_stock_item)
        :pool(_pool), stock_item(&_stock_item) {
    }

    /* virtual methods from class Cancellable */
    void Cancel() override {
        if (stock_item != nullptr)
            fcgi_stock_aborted(*stock_item);

        async_ref.Abort();
    }

    /* virtual methods from class Lease */
    void ReleaseLease(bool reuse) override {
        stock_item->Put(!reuse);
        stock_item = nullptr;
    }
};

void
fcgi_request(struct pool *pool, EventLoop &event_loop,
             FcgiStock *fcgi_stock,
             const ChildOptions &options,
             const char *action,
             const char *path,
             ConstBuffer<const char *> args,
             http_method_t method, const char *uri,
             const char *script_name, const char *path_info,
             const char *query_string,
             const char *document_root,
             const char *remote_addr,
             const StringMap &headers, Istream *body,
             ConstBuffer<const char *> params,
             int stderr_fd,
             HttpResponseHandler &handler,
             struct async_operation_ref &async_ref)
{
    if (action == nullptr)
        action = path;

    GError *error = nullptr;
    StockItem *stock_item =
        fcgi_stock_get(fcgi_stock, pool, options,
                       action,
                       args,
                       &error);
    if (stock_item == nullptr) {
        if (body != nullptr)
            body->CloseUnused();

        if (stderr_fd >= 0)
            close(stderr_fd);

        handler.InvokeError(error);
        return;
    }

    auto request = NewFromPool<FcgiRequest>(*pool, *pool, *stock_item);

    async_ref = *request;

    const char *script_filename = fcgi_stock_translate_path(*stock_item, path,
                                                            &request->pool);
    document_root = fcgi_stock_translate_path(*stock_item, document_root,
                                              &request->pool);

    fcgi_client_request(&request->pool, event_loop,
                        fcgi_stock_item_get(*stock_item),
                        fcgi_stock_item_get_domain(*stock_item) == AF_LOCAL
                        ? FdType::FD_SOCKET : FdType::FD_TCP,
                        *request,
                        method, uri,
                        script_filename,
                        script_name, path_info,
                        query_string,
                        document_root,
                        remote_addr,
                        headers, body,
                        params,
                        stderr_fd,
                        handler, request->async_ref);
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2012-2013 Matt Broadstone
 * Contact: http://bitbucket.org/devonit/qjsonrpc
 *
 * This file is part of the QJsonRpc Library.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 */

#include <QDebug>

#if QT_VERSION >= 0x050000
#   include <QJsonDocument>
#else
#   include "json/qjsondocument.h"
#endif

#include "qjsonrpcmessage.h"

class QJsonRpcMessagePrivate : public QSharedData
{
public:
    QJsonRpcMessagePrivate();
    ~QJsonRpcMessagePrivate();

    void initializeWithObject(const QJsonObject &message);
    static QJsonRpcMessage createBasicRequest(const QString &method, const QJsonArray &params);
    QJsonRpcMessage::Type type;
    QJsonObject *object;

    static int uniqueRequestCounter;

};

int QJsonRpcMessagePrivate::uniqueRequestCounter = 0;
QJsonRpcMessagePrivate::QJsonRpcMessagePrivate()
    : type(QJsonRpcMessage::Invalid),
      object(0)
{
}

void QJsonRpcMessagePrivate::initializeWithObject(const QJsonObject &message)
{
    object = new QJsonObject(message);
    if (message.contains(QLatin1String("id"))) {
        if (message.contains(QLatin1String("result")) ||
            message.contains(QLatin1String("error"))) {
            if (message.contains(QLatin1String("error")) &&
                !message.value(QLatin1String("error")).isNull())
                type = QJsonRpcMessage::Error;
            else
                type = QJsonRpcMessage::Response;
        } else if (message.contains(QLatin1String("method"))) {
            type = QJsonRpcMessage::Request;
        }
    } else {
        if (message.contains(QLatin1String("method")))
            type = QJsonRpcMessage::Notification;
    }
}

QJsonRpcMessagePrivate::~QJsonRpcMessagePrivate()
{
    if (object)
        delete object;
}

QJsonRpcMessage::QJsonRpcMessage()
    : d(new QJsonRpcMessagePrivate)
{
    d->object = new QJsonObject;
}

QJsonRpcMessage::QJsonRpcMessage(const QJsonRpcMessage &other)
    : d(other.d)
{
}

QJsonRpcMessage::~QJsonRpcMessage()
{
}

QJsonRpcMessage &QJsonRpcMessage::operator=(const QJsonRpcMessage &other)
{
    d = other.d;
    return *this;
}

bool QJsonRpcMessage::operator==(const QJsonRpcMessage &message) const
{
    if (message.d == d)
        return true;

    if (message.type() == type()) {
        if (message.type() == QJsonRpcMessage::Error) {
            return (message.errorCode() == errorCode() &&
                    message.errorMessage() == errorMessage() &&
                    message.errorData() == errorData());
        } else {
            if (message.type() == QJsonRpcMessage::Notification) {
                return (message.method() == method() &&
                        message.params() == params());
            } else {
                return (message.id() == id() &&
                        message.method() == method() &&
                        message.params() == params());
            }
        }
    }

    return false;
}

QJsonRpcMessage::QJsonRpcMessage(const QByteArray &message)
    : d(new QJsonRpcMessagePrivate)
{
    QJsonParseError error;
    QJsonDocument document = QJsonDocument::fromJson(message, &error);
    if (error.error != QJsonParseError::NoError) {
        qWarning() << Q_FUNC_INFO << error.errorString();
        return;
    }

    if (!document.isObject()) {
        qWarning() << Q_FUNC_INFO << "invalid message: " << message;
        return;
    }

    d->initializeWithObject(document.object());
}

QJsonRpcMessage::QJsonRpcMessage(const QJsonObject &message)
    : d(new QJsonRpcMessagePrivate)
{
    d->initializeWithObject(message);
}

QJsonObject QJsonRpcMessage::toObject() const
{
    if (d->object)
        return QJsonObject(*d->object);
    return QJsonObject();
}

bool QJsonRpcMessage::isValid() const
{
    return d->type != QJsonRpcMessage::Invalid;
}

QJsonRpcMessage::Type QJsonRpcMessage::type() const
{
    return d->type;
}

QJsonRpcMessage QJsonRpcMessagePrivate::createBasicRequest(const QString &method, const QJsonArray &params)
{
    QJsonRpcMessage request;
    request.d->object = new QJsonObject;
    request.d->object->insert(QLatin1String("jsonrpc"), QLatin1String("2.0"));
    request.d->object->insert(QLatin1String("method"), method);
    if (!params.isEmpty())
        request.d->object->insert(QLatin1String("params"), params);
    return request;
}

QJsonRpcMessage QJsonRpcMessage::createRequest(const QString &method, const QJsonArray &params)
{
    QJsonRpcMessage request = QJsonRpcMessagePrivate::createBasicRequest(method, params);
    request.d->type = QJsonRpcMessage::Request;
    QJsonRpcMessagePrivate::uniqueRequestCounter++;
    request.d->object->insert(QLatin1String("id"), QJsonRpcMessagePrivate::uniqueRequestCounter);
    return request;
}

QJsonRpcMessage QJsonRpcMessage::createRequest(const QString &method, const QJsonValue &param)
{
    QJsonArray params;
    params.append(param);
    return createRequest(method, params);
}

QJsonRpcMessage QJsonRpcMessage::createNotification(const QString &method, const QJsonArray &params)
{
    QJsonRpcMessage notification = QJsonRpcMessagePrivate::createBasicRequest(method, params);
    notification.d->type = QJsonRpcMessage::Notification;
    return notification;
}

QJsonRpcMessage QJsonRpcMessage::createNotification(const QString &method, const QJsonValue &param)
{
    QJsonArray params;
    params.append(param);
    return createNotification(method, params);
}

QJsonRpcMessage QJsonRpcMessage::createResponse(const QJsonValue &result) const
{
    QJsonRpcMessage response;
    if (d->object->contains(QLatin1String("id"))) {
        QJsonObject *object = new QJsonObject;
        object->insert(QLatin1String("jsonrpc"), QLatin1String("2.0"));
        object->insert(QLatin1String("id"), d->object->value(QLatin1String("id")));
        object->insert(QLatin1String("result"), result);
        response.d->type = QJsonRpcMessage::Response;
        response.d->object = object;
    }

    return response;
}

QJsonRpcMessage QJsonRpcMessage::createErrorResponse(QJsonRpc::ErrorCode code,
                                                     const QString &message,
                                                     const QJsonValue &data) const
{
    QJsonRpcMessage response;
    QJsonObject error;
    error.insert(QLatin1String("code"), code);
    if (!message.isEmpty())
        error.insert(QLatin1String("message"), message);
    if (!data.isUndefined())
        error.insert(QLatin1String("data"), data);

    response.d->type = QJsonRpcMessage::Error;
    QJsonObject *object = new QJsonObject;
    object->insert(QLatin1String("jsonrpc"), QLatin1String("2.0"));

    if (d->object->contains(QLatin1String("id")))
        object->insert(QLatin1String("id"), d->object->value(QLatin1String("id")));
    else
        object->insert(QLatin1String("id"), 0);
    object->insert(QLatin1String("error"), error);
    response.d->object = object;
    return response;
}

int QJsonRpcMessage::id() const
{
    if (d->type == QJsonRpcMessage::Notification || !d->object)
        return -1;
    return d->object->value(QLatin1String("id")).toInt();
}

QString QJsonRpcMessage::method() const
{
    if (d->type == QJsonRpcMessage::Response || !d->object)
        return QString();

    return d->object->value(QLatin1String("method")).toString();
}

QJsonArray QJsonRpcMessage::params() const
{
    if (d->type == QJsonRpcMessage::Response || d->type == QJsonRpcMessage::Error)
        return QJsonArray();
    if (!d->object)
        return QJsonArray();

    return d->object->value(QLatin1String("params")).toArray();
}

QJsonValue QJsonRpcMessage::result() const
{
    if (d->type != QJsonRpcMessage::Response || !d->object)
        return QJsonValue();

    return d->object->value(QLatin1String("result"));
}

int QJsonRpcMessage::errorCode() const
{
    if (d->type != QJsonRpcMessage::Error || !d->object)
        return 0;

    QJsonObject error =
        d->object->value(QLatin1String("error")).toObject();
    return error.value(QLatin1String("code")).toInt();
}

QString QJsonRpcMessage::errorMessage() const
{
    if (d->type != QJsonRpcMessage::Error || !d->object)
        return QString();

    QJsonObject error =
        d->object->value(QLatin1String("error")).toObject();
    return error.value(QLatin1String("message")).toString();
}

QJsonValue QJsonRpcMessage::errorData() const
{
    if (d->type != QJsonRpcMessage::Error || !d->object)
        return QJsonValue();

    QJsonObject error =
        d->object->value(QLatin1String("error")).toObject();
    return error.value(QLatin1String("data"));
}

static QDebug operator<<(QDebug dbg, QJsonRpcMessage::Type type)
{
    switch (type) {
    case QJsonRpcMessage::Request:
        return dbg << "QJsonRpcMessage::Request";
    case QJsonRpcMessage::Response:
        return dbg << "QJsonRpcMessage::Response";
    case QJsonRpcMessage::Notification:
        return dbg << "QJsonRpcMessage::Notification";
    case QJsonRpcMessage::Error:
        return dbg << "QJsonRpcMessage::Error";
    default:
        return dbg << "QJsonRpcMessage::Invalid";
    }
}

QDebug operator<<(QDebug dbg, const QJsonRpcMessage &msg)
{
    dbg.nospace() << "QJsonRpcMessage(type=" << msg.type();
    if (msg.type() != QJsonRpcMessage::Notification) {
        dbg.nospace() << ", id=" << msg.id();
    }

    if (msg.type() == QJsonRpcMessage::Request ||
        msg.type() == QJsonRpcMessage::Notification) {
        dbg.nospace() << ", method=" << msg.method()
                      << ", params=" << msg.params();
    } else if (msg.type() == QJsonRpcMessage::Response) {
        dbg.nospace() << ", result=" << msg.result();
    } else if (msg.type() == QJsonRpcMessage::Error) {
        dbg.nospace() << ", code=" << msg.errorCode()
                      << ", message=" << msg.errorMessage()
                      << ", data=" << msg.errorData();
    }
    dbg.nospace() << ")";
    return dbg.space();
}
<commit_msg>Fix QJsonObject memory leak<commit_after>/*
 * Copyright (C) 2012-2013 Matt Broadstone
 * Contact: http://bitbucket.org/devonit/qjsonrpc
 *
 * This file is part of the QJsonRpc Library.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 */

#include <QDebug>

#if QT_VERSION >= 0x050000
#   include <QJsonDocument>
#else
#   include "json/qjsondocument.h"
#endif

#include "qjsonrpcmessage.h"

class QJsonRpcMessagePrivate : public QSharedData
{
public:
    QJsonRpcMessagePrivate();
    ~QJsonRpcMessagePrivate();
    QJsonRpcMessagePrivate(const QJsonRpcMessagePrivate &other);

    void initializeWithObject(const QJsonObject &message);
    static QJsonRpcMessage createBasicRequest(const QString &method, const QJsonArray &params);

    QJsonRpcMessage::Type type;
    QScopedPointer<QJsonObject> object;

    static int uniqueRequestCounter;
};

int QJsonRpcMessagePrivate::uniqueRequestCounter = 0;

QJsonRpcMessagePrivate::QJsonRpcMessagePrivate()
    : type(QJsonRpcMessage::Invalid),
      object(0)
{
}

QJsonRpcMessagePrivate::QJsonRpcMessagePrivate(const QJsonRpcMessagePrivate &other)
    : QSharedData(other),
      type(other.type),
      object(other.object ? new QJsonObject(*other.object) : 0)
{
}

void QJsonRpcMessagePrivate::initializeWithObject(const QJsonObject &message)
{
    object.reset(new QJsonObject(message));
    if (message.contains(QLatin1String("id"))) {
        if (message.contains(QLatin1String("result")) ||
            message.contains(QLatin1String("error"))) {
            if (message.contains(QLatin1String("error")) &&
                !message.value(QLatin1String("error")).isNull())
                type = QJsonRpcMessage::Error;
            else
                type = QJsonRpcMessage::Response;
        } else if (message.contains(QLatin1String("method"))) {
            type = QJsonRpcMessage::Request;
        }
    } else {
        if (message.contains(QLatin1String("method")))
            type = QJsonRpcMessage::Notification;
    }
}

QJsonRpcMessagePrivate::~QJsonRpcMessagePrivate()
{
}

QJsonRpcMessage::QJsonRpcMessage()
    : d(new QJsonRpcMessagePrivate)
{
    d->object.reset(new QJsonObject);
}

QJsonRpcMessage::QJsonRpcMessage(const QJsonRpcMessage &other)
    : d(other.d)
{
}

QJsonRpcMessage::~QJsonRpcMessage()
{
}

QJsonRpcMessage &QJsonRpcMessage::operator=(const QJsonRpcMessage &other)
{
    d = other.d;
    return *this;
}

bool QJsonRpcMessage::operator==(const QJsonRpcMessage &message) const
{
    if (message.d == d)
        return true;

    if (message.type() == type()) {
        if (message.type() == QJsonRpcMessage::Error) {
            return (message.errorCode() == errorCode() &&
                    message.errorMessage() == errorMessage() &&
                    message.errorData() == errorData());
        } else {
            if (message.type() == QJsonRpcMessage::Notification) {
                return (message.method() == method() &&
                        message.params() == params());
            } else {
                return (message.id() == id() &&
                        message.method() == method() &&
                        message.params() == params());
            }
        }
    }

    return false;
}

QJsonRpcMessage::QJsonRpcMessage(const QByteArray &message)
    : d(new QJsonRpcMessagePrivate)
{
    QJsonParseError error;
    QJsonDocument document = QJsonDocument::fromJson(message, &error);
    if (error.error != QJsonParseError::NoError) {
        qWarning() << Q_FUNC_INFO << error.errorString();
        return;
    }

    if (!document.isObject()) {
        qWarning() << Q_FUNC_INFO << "invalid message: " << message;
        return;
    }

    d->initializeWithObject(document.object());
}

QJsonRpcMessage::QJsonRpcMessage(const QJsonObject &message)
    : d(new QJsonRpcMessagePrivate)
{
    d->initializeWithObject(message);
}

QJsonObject QJsonRpcMessage::toObject() const
{
    if (d->object)
        return QJsonObject(*d->object);
    return QJsonObject();
}

bool QJsonRpcMessage::isValid() const
{
    return d->type != QJsonRpcMessage::Invalid;
}

QJsonRpcMessage::Type QJsonRpcMessage::type() const
{
    return d->type;
}

QJsonRpcMessage QJsonRpcMessagePrivate::createBasicRequest(const QString &method, const QJsonArray &params)
{
    QJsonRpcMessage request;
    request.d->object->insert(QLatin1String("jsonrpc"), QLatin1String("2.0"));
    request.d->object->insert(QLatin1String("method"), method);
    if (!params.isEmpty())
        request.d->object->insert(QLatin1String("params"), params);
    return request;
}

QJsonRpcMessage QJsonRpcMessage::createRequest(const QString &method, const QJsonArray &params)
{
    QJsonRpcMessage request = QJsonRpcMessagePrivate::createBasicRequest(method, params);
    request.d->type = QJsonRpcMessage::Request;
    QJsonRpcMessagePrivate::uniqueRequestCounter++;
    request.d->object->insert(QLatin1String("id"), QJsonRpcMessagePrivate::uniqueRequestCounter);
    return request;
}

QJsonRpcMessage QJsonRpcMessage::createRequest(const QString &method, const QJsonValue &param)
{
    QJsonArray params;
    params.append(param);
    return createRequest(method, params);
}

QJsonRpcMessage QJsonRpcMessage::createNotification(const QString &method, const QJsonArray &params)
{
    QJsonRpcMessage notification = QJsonRpcMessagePrivate::createBasicRequest(method, params);
    notification.d->type = QJsonRpcMessage::Notification;
    return notification;
}

QJsonRpcMessage QJsonRpcMessage::createNotification(const QString &method, const QJsonValue &param)
{
    QJsonArray params;
    params.append(param);
    return createNotification(method, params);
}

QJsonRpcMessage QJsonRpcMessage::createResponse(const QJsonValue &result) const
{
    QJsonRpcMessage response;
    if (d->object->contains(QLatin1String("id"))) {
        QJsonObject *object = response.d->object.data();
        object->insert(QLatin1String("jsonrpc"), QLatin1String("2.0"));
        object->insert(QLatin1String("id"), d->object->value(QLatin1String("id")));
        object->insert(QLatin1String("result"), result);
        response.d->type = QJsonRpcMessage::Response;
    }

    return response;
}

QJsonRpcMessage QJsonRpcMessage::createErrorResponse(QJsonRpc::ErrorCode code,
                                                     const QString &message,
                                                     const QJsonValue &data) const
{
    QJsonRpcMessage response;
    QJsonObject error;
    error.insert(QLatin1String("code"), code);
    if (!message.isEmpty())
        error.insert(QLatin1String("message"), message);
    if (!data.isUndefined())
        error.insert(QLatin1String("data"), data);

    response.d->type = QJsonRpcMessage::Error;
    QJsonObject *object = response.d->object.data();
    object->insert(QLatin1String("jsonrpc"), QLatin1String("2.0"));
    if (d->object->contains(QLatin1String("id")))
        object->insert(QLatin1String("id"), d->object->value(QLatin1String("id")));
    else
        object->insert(QLatin1String("id"), 0);
    object->insert(QLatin1String("error"), error);
    return response;
}

int QJsonRpcMessage::id() const
{
    if (d->type == QJsonRpcMessage::Notification || !d->object)
        return -1;
    return d->object->value(QLatin1String("id")).toInt();
}

QString QJsonRpcMessage::method() const
{
    if (d->type == QJsonRpcMessage::Response || !d->object)
        return QString();

    return d->object->value(QLatin1String("method")).toString();
}

QJsonArray QJsonRpcMessage::params() const
{
    if (d->type == QJsonRpcMessage::Response || d->type == QJsonRpcMessage::Error)
        return QJsonArray();
    if (!d->object)
        return QJsonArray();

    return d->object->value(QLatin1String("params")).toArray();
}

QJsonValue QJsonRpcMessage::result() const
{
    if (d->type != QJsonRpcMessage::Response || !d->object)
        return QJsonValue();

    return d->object->value(QLatin1String("result"));
}

int QJsonRpcMessage::errorCode() const
{
    if (d->type != QJsonRpcMessage::Error || !d->object)
        return 0;

    QJsonObject error =
        d->object->value(QLatin1String("error")).toObject();
    return error.value(QLatin1String("code")).toInt();
}

QString QJsonRpcMessage::errorMessage() const
{
    if (d->type != QJsonRpcMessage::Error || !d->object)
        return QString();

    QJsonObject error =
        d->object->value(QLatin1String("error")).toObject();
    return error.value(QLatin1String("message")).toString();
}

QJsonValue QJsonRpcMessage::errorData() const
{
    if (d->type != QJsonRpcMessage::Error || !d->object)
        return QJsonValue();

    QJsonObject error =
        d->object->value(QLatin1String("error")).toObject();
    return error.value(QLatin1String("data"));
}

static QDebug operator<<(QDebug dbg, QJsonRpcMessage::Type type)
{
    switch (type) {
    case QJsonRpcMessage::Request:
        return dbg << "QJsonRpcMessage::Request";
    case QJsonRpcMessage::Response:
        return dbg << "QJsonRpcMessage::Response";
    case QJsonRpcMessage::Notification:
        return dbg << "QJsonRpcMessage::Notification";
    case QJsonRpcMessage::Error:
        return dbg << "QJsonRpcMessage::Error";
    default:
        return dbg << "QJsonRpcMessage::Invalid";
    }
}

QDebug operator<<(QDebug dbg, const QJsonRpcMessage &msg)
{
    dbg.nospace() << "QJsonRpcMessage(type=" << msg.type();
    if (msg.type() != QJsonRpcMessage::Notification) {
        dbg.nospace() << ", id=" << msg.id();
    }

    if (msg.type() == QJsonRpcMessage::Request ||
        msg.type() == QJsonRpcMessage::Notification) {
        dbg.nospace() << ", method=" << msg.method()
                      << ", params=" << msg.params();
    } else if (msg.type() == QJsonRpcMessage::Response) {
        dbg.nospace() << ", result=" << msg.result();
    } else if (msg.type() == QJsonRpcMessage::Error) {
        dbg.nospace() << ", code=" << msg.errorCode()
                      << ", message=" << msg.errorMessage()
                      << ", data=" << msg.errorData();
    }
    dbg.nospace() << ")";
    return dbg.space();
}
<|endoftext|>