<commit_before>// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Audio module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Audio/Formats/minimp3Loader.hpp>
#include <Nazara/Audio/Algorithm.hpp>
#include <Nazara/Audio/Audio.hpp>
#include <Nazara/Audio/Config.hpp>
#include <Nazara/Audio/SoundBuffer.hpp>
#include <Nazara/Audio/SoundStream.hpp>
#include <Nazara/Core/CallOnExit.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/File.hpp>
#include <Nazara/Core/MemoryView.hpp>
#include <Nazara/Core/Stream.hpp>
#include <optional>

#define MINIMP3_IMPLEMENTATION
#define MINIMP3_NO_STDIO
#include <minimp3_ex.h>

#include <Nazara/Audio/Debug.hpp>

namespace Nz
{
	namespace
	{
		std::optional<AudioFormat> GuessFormat(UInt32 channelCount)
		{
			switch (channelCount)
			{
				case 1:
					return AudioFormat::I16_Mono;

				case 2:
					return AudioFormat::I16_Stereo;

				case 4:
					return AudioFormat::I16_Quad;

				case 6:
					return AudioFormat::I16_5_1;

				case 7:
					return AudioFormat::I16_6_1;

				case 8:
					return AudioFormat::I16_7_1;

				default:
					return std::nullopt;
			}
		}

		std::string ErrToString(int errCode)
		{
			switch (errCode)
			{
				case 0: return "no error";
				case MP3D_E_PARAM: return "wrong parameters";
				case MP3D_E_MEMORY: return "not enough memory";
				case MP3D_E_IOERROR: return "I/O error";
				case MP3D_E_USER: return "aborted";
				case MP3D_E_DECODE: return "decoding error";
				default: return "unknown error";
			}
		}

		size_t ReadCallback(void* buf, size_t size, void* user_data)
		{
			Stream* stream = static_cast<Stream*>(user_data);
			return static_cast<size_t>(stream->Read(buf, size));
		}

		int SeekCallback(uint64_t position, void* user_data)
		{
			Stream* stream = static_cast<Stream*>(user_data);
			return (stream->SetCursorPos(position)) ? 0 : MP3D_E_IOERROR;
		}

		bool IsSupported(const std::string_view& extension)
		{
			return extension == "mp3";
		}

		Ternary CheckMp3(Stream& stream)
		{
			mp3dec_io_t io;
			io.read = &ReadCallback;
			io.read_data = &stream;
			io.seek = &SeekCallback;
			io.seek_data = &stream;

			std::vector<UInt8> buffer(MINIMP3_BUF_SIZE);
			return (mp3dec_detect_cb(&io, buffer.data(), buffer.size()) == 0) ? Ternary::True : Ternary::False;
		}

		std::shared_ptr<SoundBuffer> LoadSoundBuffer(Stream& stream, const SoundBufferParams& parameters)
		{
			static_assert(std::is_same_v<mp3d_sample_t, Int16>);

			mp3dec_io_t io;
			io.read = &ReadCallback;
			io.read_data = &stream;
			io.seek = &SeekCallback;
			io.seek_data = &stream;

			struct UserData
			{
				std::vector<Int16> samples;
			};

			UserData userdata;

			mp3dec_t dec;
			mp3dec_file_info_t info;
			std::vector<UInt8> buffer(MINIMP3_BUF_SIZE);
			int err = mp3dec_load_cb(&dec, &io, buffer.data(), buffer.size(), &info, nullptr, &userdata);
			if (err != 0)
			{
				NazaraError(ErrToString(err));
				return {};
			}

			CallOnExit freeBuffer([&] { std::free(info.buffer); });

			std::optional<AudioFormat> formatOpt = GuessFormat(info.channels);
			if (!formatOpt)
			{
				NazaraError("unexpected channel count: " + std::to_string(info.channels));
				return {};
			}

			AudioFormat format = *formatOpt;

			UInt32 sampleCount = static_cast<UInt32>(info.samples);

			if (parameters.forceMono && format != AudioFormat::I16_Mono)
			{
				UInt64 frameCount = UInt64(info.samples / info.channels);
				MixToMono(info.buffer, info.buffer, static_cast<UInt32>(info.channels), frameCount);

				format = AudioFormat::I16_Mono;
				sampleCount = frameCount;
			}

			return std::make_shared<SoundBuffer>(format, sampleCount, info.hz, info.buffer);
		}

		class minimp3Stream : public SoundStream
		{
			public:
				minimp3Stream() :
				m_readSampleCount(0)
				{
					std::memset(&m_decoder, 0, sizeof(m_decoder));
				}

				~minimp3Stream()
				{
					mp3dec_ex_close(&m_decoder);
				}

				UInt32 GetDuration() const override
				{
					return m_duration;
				}

				AudioFormat GetFormat() const override
				{
					if (m_mixToMono)
						return AudioFormat::I16_Mono;
					else
						return m_format;
				}

				std::mutex& GetMutex() override
				{
					return m_mutex;
				}

				UInt64 GetSampleCount() const override
				{
					return m_sampleCount;
				}

				UInt32 GetSampleRate() const override
				{
					return m_sampleRate;
				}

				bool Open(const std::filesystem::path& filePath, bool forceMono)
				{
					std::unique_ptr<File> file = std::make_unique<File>();
					if (!file->Open(filePath, OpenMode::ReadOnly))
					{
						NazaraError("failed to open stream from file: " + Error::GetLastError());
						return false;
					}

					m_ownedStream = std::move(file);
					return Open(*m_ownedStream, forceMono);
				}

				bool Open(const void* data, std::size_t size, bool forceMono)
				{
					m_ownedStream = std::make_unique<MemoryView>(data, size);
					return Open(*m_ownedStream, forceMono);
				}

				bool Open(Stream& stream, bool forceMono)
				{
					m_io.read = &ReadCallback;
					m_io.read_data = &stream;
					m_io.seek = &SeekCallback;
					m_io.seek_data = &stream;

					int err = mp3dec_ex_open_cb(&m_decoder, &m_io, MP3D_SEEK_TO_SAMPLE);
					if (err != 0)
					{
						NazaraError(ErrToString(err));
						return {};
					}

					CallOnExit resetOnError([this]
					{
						mp3dec_ex_close(&m_decoder);
						std::memset(&m_decoder, 0, sizeof(m_decoder));
					});

					std::optional<AudioFormat> formatOpt = GuessFormat(m_decoder.info.channels);
					if (!formatOpt)
					{
						NazaraError("unexpected channel count: " + std::to_string(m_decoder.info.channels));
						return false;
					}

					m_format = *formatOpt;

					m_duration = static_cast<UInt32>(1000ULL * m_decoder.samples / (m_decoder.info.hz * m_decoder.info.channels));
					m_sampleCount = m_decoder.samples;
					m_sampleRate = m_decoder.info.hz;

					// Mixing to mono will be done on the fly
					if (forceMono && m_format != AudioFormat::I16_Mono)
					{
						m_mixToMono = true;
						m_sampleCount = static_cast<UInt32>(m_decoder.samples / m_decoder.info.channels);
					}
					else
						m_mixToMono = false;

					resetOnError.Reset();

					return true;
				}

				UInt64 Read(void* buffer, UInt64 sampleCount) override
				{
					// Convert to mono in the fly if necessary
					if (m_mixToMono)
					{
						UInt32 channelCount = GetChannelCount(m_format);

						// Keep a buffer to the side to prevent allocation
						m_mixBuffer.resize(channelCount * sampleCount);
						std::size_t readSample = mp3dec_ex_read(&m_decoder, m_mixBuffer.data(), channelCount * sampleCount);
						m_readSampleCount += readSample;

						MixToMono(m_mixBuffer.data(), static_cast<Int16*>(buffer), channelCount, sampleCount);

						return readSample / channelCount;
					}
					else
					{
						UInt64 readSample = mp3dec_ex_read(&m_decoder, static_cast<Int16*>(buffer), sampleCount);
						m_readSampleCount += readSample;

						return readSample;
					}
				}

				void Seek(UInt64 offset) override
				{
					mp3dec_ex_seek(&m_decoder, offset);
					m_readSampleCount = offset;
				}

				UInt64 Tell() override
				{
					return m_readSampleCount;
				}

			private:
				std::mutex m_mutex;
				std::unique_ptr<Stream> m_ownedStream;
				std::vector<Int16> m_mixBuffer;
				AudioFormat m_format;
				mp3dec_ex_t m_decoder;
				mp3dec_io_t m_io;
				UInt32 m_duration;
				UInt32 m_sampleRate;
				UInt64 m_readSampleCount;
				UInt64 m_sampleCount;
				bool m_mixToMono;
		};

		std::shared_ptr<SoundStream> LoadSoundStreamFile(const std::filesystem::path& filePath, const SoundStreamParams& parameters)
		{
			std::shared_ptr<minimp3Stream> soundStream = std::make_shared<minimp3Stream>();
			if (!soundStream->Open(filePath, parameters.forceMono))
			{
				NazaraError("failed to open sound stream");
				return {};
			}

			return soundStream;
		}

		std::shared_ptr<SoundStream> LoadSoundStreamMemory(const void* data, std::size_t size, const SoundStreamParams& parameters)
		{
			std::shared_ptr<minimp3Stream> soundStream = std::make_shared<minimp3Stream>();
			if (!soundStream->Open(data, size, parameters.forceMono))
			{
				NazaraError("failed to open music stream");
				return {};
			}

			return soundStream;
		}

		std::shared_ptr<SoundStream> LoadSoundStreamStream(Stream& stream, const SoundStreamParams& parameters)
		{
			std::shared_ptr<minimp3Stream> soundStream = std::make_shared<minimp3Stream>();
			if (!soundStream->Open(stream, parameters.forceMono))
			{
				NazaraError("failed to open music stream");
				return {};
			}

			return soundStream;
		}
	}

	namespace Loaders
	{
		SoundBufferLoader::Entry GetSoundBufferLoader_minimp3()
		{
			SoundBufferLoader::Entry loaderEntry;
			loaderEntry.extensionSupport = IsSupported;
			loaderEntry.streamChecker = [](Stream& stream, const SoundBufferParams&) { return CheckMp3(stream); };
			loaderEntry.streamLoader = LoadSoundBuffer;

			return loaderEntry;
		}

		SoundStreamLoader::Entry GetSoundStreamLoader_minimp3()
		{
			SoundStreamLoader::Entry loaderEntry;
			loaderEntry.extensionSupport = IsSupported;
			loaderEntry.streamChecker = [](Stream& stream, const SoundStreamParams&) { return CheckMp3(stream); };
			loaderEntry.fileLoader = LoadSoundStreamFile;
			loaderEntry.memoryLoader = LoadSoundStreamMemory;
			loaderEntry.streamLoader = LoadSoundStreamStream;

			return loaderEntry;
		}
	}
}
<commit_msg>Audio/minimp3Loader: Fix some warnings<commit_after>// Copyright (C) 2020 Jérôme Leclercq
// This file is part of the "Nazara Engine - Audio module"
// For conditions of distribution and use, see copyright notice in Config.hpp

#include <Nazara/Audio/Formats/minimp3Loader.hpp>
#include <Nazara/Audio/Algorithm.hpp>
#include <Nazara/Audio/Audio.hpp>
#include <Nazara/Audio/Config.hpp>
#include <Nazara/Audio/SoundBuffer.hpp>
#include <Nazara/Audio/SoundStream.hpp>
#include <Nazara/Core/CallOnExit.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/File.hpp>
#include <Nazara/Core/MemoryView.hpp>
#include <Nazara/Core/Stream.hpp>
#include <optional>

#define MINIMP3_IMPLEMENTATION
#define MINIMP3_NO_STDIO
#include <minimp3_ex.h>

#include <Nazara/Audio/Debug.hpp>

namespace Nz
{
	namespace
	{
		std::optional<AudioFormat> GuessFormat(UInt32 channelCount)
		{
			switch (channelCount)
			{
				case 1:
					return AudioFormat::I16_Mono;

				case 2:
					return AudioFormat::I16_Stereo;

				case 4:
					return AudioFormat::I16_Quad;

				case 6:
					return AudioFormat::I16_5_1;

				case 7:
					return AudioFormat::I16_6_1;

				case 8:
					return AudioFormat::I16_7_1;

				default:
					return std::nullopt;
			}
		}

		std::string ErrToString(int errCode)
		{
			switch (errCode)
			{
				case 0: return "no error";
				case MP3D_E_PARAM: return "wrong parameters";
				case MP3D_E_MEMORY: return "not enough memory";
				case MP3D_E_IOERROR: return "I/O error";
				case MP3D_E_USER: return "aborted";
				case MP3D_E_DECODE: return "decoding error";
				default: return "unknown error";
			}
		}

		size_t ReadCallback(void* buf, size_t size, void* user_data)
		{
			Stream* stream = static_cast<Stream*>(user_data);
			return static_cast<size_t>(stream->Read(buf, size));
		}

		int SeekCallback(uint64_t position, void* user_data)
		{
			Stream* stream = static_cast<Stream*>(user_data);
			return (stream->SetCursorPos(position)) ? 0 : MP3D_E_IOERROR;
		}

		bool IsSupported(const std::string_view& extension)
		{
			return extension == "mp3";
		}

		Ternary CheckMp3(Stream& stream)
		{
			mp3dec_io_t io;
			io.read = &ReadCallback;
			io.read_data = &stream;
			io.seek = &SeekCallback;
			io.seek_data = &stream;

			std::vector<UInt8> buffer(MINIMP3_BUF_SIZE);
			return (mp3dec_detect_cb(&io, buffer.data(), buffer.size()) == 0) ? Ternary::True : Ternary::False;
		}

		std::shared_ptr<SoundBuffer> LoadSoundBuffer(Stream& stream, const SoundBufferParams& parameters)
		{
			static_assert(std::is_same_v<mp3d_sample_t, Int16>);

			mp3dec_io_t io;
			io.read = &ReadCallback;
			io.read_data = &stream;
			io.seek = &SeekCallback;
			io.seek_data = &stream;

			struct UserData
			{
				std::vector<Int16> samples;
			};

			UserData userdata;

			mp3dec_t dec;
			mp3dec_file_info_t info;
			std::vector<UInt8> buffer(MINIMP3_BUF_SIZE);
			int err = mp3dec_load_cb(&dec, &io, buffer.data(), buffer.size(), &info, nullptr, &userdata);
			if (err != 0)
			{
				NazaraError(ErrToString(err));
				return {};
			}

			CallOnExit freeBuffer([&] { std::free(info.buffer); });

			std::optional<AudioFormat> formatOpt = GuessFormat(info.channels);
			if (!formatOpt)
			{
				NazaraError("unexpected channel count: " + std::to_string(info.channels));
				return {};
			}

			AudioFormat format = *formatOpt;

			UInt64 sampleCount = UInt64(info.samples);

			if (parameters.forceMono && format != AudioFormat::I16_Mono)
			{
				UInt64 frameCount = UInt64(info.samples / info.channels);
				MixToMono(info.buffer, info.buffer, UInt32(info.channels), frameCount);

				format = AudioFormat::I16_Mono;
				sampleCount = frameCount;
			}

			return std::make_shared<SoundBuffer>(format, sampleCount, info.hz, info.buffer);
		}

		class minimp3Stream : public SoundStream
		{
			public:
				minimp3Stream() :
				m_readSampleCount(0)
				{
					std::memset(&m_decoder, 0, sizeof(m_decoder));
				}

				~minimp3Stream()
				{
					mp3dec_ex_close(&m_decoder);
				}

				UInt32 GetDuration() const override
				{
					return m_duration;
				}

				AudioFormat GetFormat() const override
				{
					if (m_mixToMono)
						return AudioFormat::I16_Mono;
					else
						return m_format;
				}

				std::mutex& GetMutex() override
				{
					return m_mutex;
				}

				UInt64 GetSampleCount() const override
				{
					return m_sampleCount;
				}

				UInt32 GetSampleRate() const override
				{
					return m_sampleRate;
				}

				bool Open(const std::filesystem::path& filePath, bool forceMono)
				{
					std::unique_ptr<File> file = std::make_unique<File>();
					if (!file->Open(filePath, OpenMode::ReadOnly))
					{
						NazaraError("failed to open stream from file: " + Error::GetLastError());
						return false;
					}

					m_ownedStream = std::move(file);
					return Open(*m_ownedStream, forceMono);
				}

				bool Open(const void* data, std::size_t size, bool forceMono)
				{
					m_ownedStream = std::make_unique<MemoryView>(data, size);
					return Open(*m_ownedStream, forceMono);
				}

				bool Open(Stream& stream, bool forceMono)
				{
					m_io.read = &ReadCallback;
					m_io.read_data = &stream;
					m_io.seek = &SeekCallback;
					m_io.seek_data = &stream;

					int err = mp3dec_ex_open_cb(&m_decoder, &m_io, MP3D_SEEK_TO_SAMPLE);
					if (err != 0)
					{
						NazaraError(ErrToString(err));
						return {};
					}

					CallOnExit resetOnError([this]
					{
						mp3dec_ex_close(&m_decoder);
						std::memset(&m_decoder, 0, sizeof(m_decoder));
					});

					std::optional<AudioFormat> formatOpt = GuessFormat(m_decoder.info.channels);
					if (!formatOpt)
					{
						NazaraError("unexpected channel count: " + std::to_string(m_decoder.info.channels));
						return false;
					}

					m_format = *formatOpt;

					m_duration = static_cast<UInt32>(1000ULL * m_decoder.samples / (m_decoder.info.hz * m_decoder.info.channels));
					m_sampleCount = m_decoder.samples;
					m_sampleRate = m_decoder.info.hz;

					// Mixing to mono will be done on the fly
					if (forceMono && m_format != AudioFormat::I16_Mono)
					{
						m_mixToMono = true;
						m_sampleCount = static_cast<UInt32>(m_decoder.samples / m_decoder.info.channels);
					}
					else
						m_mixToMono = false;

					resetOnError.Reset();

					return true;
				}

				UInt64 Read(void* buffer, UInt64 sampleCount) override
				{
					// Convert to mono in the fly if necessary
					if (m_mixToMono)
					{
						UInt32 channelCount = GetChannelCount(m_format);

						// Keep a buffer to the side to prevent allocation
						m_mixBuffer.resize(channelCount * sampleCount);
						std::size_t readSample = mp3dec_ex_read(&m_decoder, m_mixBuffer.data(), channelCount * sampleCount);
						m_readSampleCount += readSample;

						MixToMono(m_mixBuffer.data(), static_cast<Int16*>(buffer), channelCount, sampleCount);

						return readSample / channelCount;
					}
					else
					{
						UInt64 readSample = mp3dec_ex_read(&m_decoder, static_cast<Int16*>(buffer), sampleCount);
						m_readSampleCount += readSample;

						return readSample;
					}
				}

				void Seek(UInt64 offset) override
				{
					mp3dec_ex_seek(&m_decoder, offset);
					m_readSampleCount = offset;
				}

				UInt64 Tell() override
				{
					return m_readSampleCount;
				}

			private:
				std::mutex m_mutex;
				std::unique_ptr<Stream> m_ownedStream;
				std::vector<Int16> m_mixBuffer;
				AudioFormat m_format;
				mp3dec_ex_t m_decoder;
				mp3dec_io_t m_io;
				UInt32 m_duration;
				UInt32 m_sampleRate;
				UInt64 m_readSampleCount;
				UInt64 m_sampleCount;
				bool m_mixToMono;
		};

		std::shared_ptr<SoundStream> LoadSoundStreamFile(const std::filesystem::path& filePath, const SoundStreamParams& parameters)
		{
			std::shared_ptr<minimp3Stream> soundStream = std::make_shared<minimp3Stream>();
			if (!soundStream->Open(filePath, parameters.forceMono))
			{
				NazaraError("failed to open sound stream");
				return {};
			}

			return soundStream;
		}

		std::shared_ptr<SoundStream> LoadSoundStreamMemory(const void* data, std::size_t size, const SoundStreamParams& parameters)
		{
			std::shared_ptr<minimp3Stream> soundStream = std::make_shared<minimp3Stream>();
			if (!soundStream->Open(data, size, parameters.forceMono))
			{
				NazaraError("failed to open music stream");
				return {};
			}

			return soundStream;
		}

		std::shared_ptr<SoundStream> LoadSoundStreamStream(Stream& stream, const SoundStreamParams& parameters)
		{
			std::shared_ptr<minimp3Stream> soundStream = std::make_shared<minimp3Stream>();
			if (!soundStream->Open(stream, parameters.forceMono))
			{
				NazaraError("failed to open music stream");
				return {};
			}

			return soundStream;
		}
	}

	namespace Loaders
	{
		SoundBufferLoader::Entry GetSoundBufferLoader_minimp3()
		{
			SoundBufferLoader::Entry loaderEntry;
			loaderEntry.extensionSupport = IsSupported;
			loaderEntry.streamChecker = [](Stream& stream, const SoundBufferParams&) { return CheckMp3(stream); };
			loaderEntry.streamLoader = LoadSoundBuffer;

			return loaderEntry;
		}

		SoundStreamLoader::Entry GetSoundStreamLoader_minimp3()
		{
			SoundStreamLoader::Entry loaderEntry;
			loaderEntry.extensionSupport = IsSupported;
			loaderEntry.streamChecker = [](Stream& stream, const SoundStreamParams&) { return CheckMp3(stream); };
			loaderEntry.fileLoader = LoadSoundStreamFile;
			loaderEntry.memoryLoader = LoadSoundStreamMemory;
			loaderEntry.streamLoader = LoadSoundStreamStream;

			return loaderEntry;
		}
	}
}
<|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 "baryon_wrapper.h"

using namespace tiramisu;

/**
 * Res1 = 0
   For x0 in 0 to 63
     For x1 in 0 to 63
       For x2 in 0 to 63
       {
          Res3 = S(c1,x0,x1,x2,t,a1,x’0)*S(c2,x0,x1,x2, t, a2, x’0)*S(c3, x0, x1, x2,t,a3, x’0)
                +S(c2,x0,x1,x2,t,a1,x’0)*S(c3,x0,x1,x2, t, a2, x’0)*S(c1, x0, x1, x2,t,a3, x’0)
                +S(c3,x0,x1,x2,t,a1,x’0)*S(c1,x0,x1,x2, t, a2, x’0)*S(c2, x0, x1, x2,t,a3, x’0)
                -S(c2,x0,x1,x2,t,a1,x’0)*S(c1,x0,x1,x2, t, a2, x’0)*S(c3, x0, x1, x2, t, a3, x’0)
                -S(c3,x0,x1,x2,t,a1,x’0)*S(c2,x0,x1,x2, t, a2, x’0)*S(c1, x0, x1, x2, t, a3, x’0)
                -S(c1,x0,x1,x2,t,a1,x’0)*S(c3,x0,x1,x2, t, a2, x’0)*S(c2, x0, x1, x2, t, a3, x’0)

         Res2 = 0
         For k = 1 to N(B(b0,b1,b2))
           Res2 += w’(c1,c2,c3, b0,b1,b2, k) * Res3;

         Res1 += exp(i(x0*px+x1*py+x2*pz)) * Res2;
       }

 */

void generate_function(std::string name, int size)
{
    tiramisu::global::set_default_tiramisu_options();

    // -------------------------------------------------------
    // Layer I
    // -------------------------------------------------------

    tiramisu::function function0(name);
    tiramisu::constant N("N", tiramisu::expr((int32_t) size), p_int32, true, NULL, 0, &function0);
    tiramisu::var i("i");
    tiramisu::var j("j");
    tiramisu::computation x("[N]->{x[i]: 0<=i<N}", tiramisu::expr(), false, p_float32, &function0);
    tiramisu::computation y("[N]->{y[i]: 0<=i<N}", tiramisu::expr(), false, p_float32, &function0);
    tiramisu::computation a("{a[0]}", tiramisu::expr(), false, p_float32, &function0);
//    tiramisu::computation result("[N]->{result[i]: 0<=i<N}", a(0) * x(i) + y(i), true, p_float32, &function0);
   tiramisu::computation result("[N]->{result[i]: 0<=i<N}", a(0), true, p_float32, &function0);

    // -------------------------------------------------------
    // Layer II
    // -------------------------------------------------------

    // -------------------------------------------------------
    // Layer III
    // -------------------------------------------------------

    tiramisu::buffer buf_a("buf_a", {1}, tiramisu::p_float32, a_input, &function0);
    tiramisu::buffer buf_x("buf_x", {size}, tiramisu::p_float32, a_input, &function0);
    tiramisu::buffer buf_y("buf_y", {size}, tiramisu::p_float32, a_output, &function0);

    a.set_access("{a[0]->buf_a[0]}");
    x.set_access("[N]->{x[i]->buf_x[i]: 0<=i<N}");
    y.set_access("[N]->{y[i]->buf_y[i]: 0<=i<N}");
    result.set_access("[N]->{result[i]->buf_y[i]: 0<=i<N}");

    // -------------------------------------------------------
    // Code Generation
    // -------------------------------------------------------

    function0.set_arguments({&buf_a, &buf_x, &buf_y});
    function0.gen_time_space_domain();
    function0.gen_isl_ast();
    function0.gen_halide_stmt();
    function0.gen_halide_obj("generated_" + std::string(TEST_NAME_STR) + ".o");
}

int main(int argc, char **argv)
{
    generate_function("tiramisu_generated_code", SIZE);

    return 0;
}
<commit_msg>Create baryong generator<commit_after>#include <tiramisu/debug.h>
#include <tiramisu/core.h>

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

#include "baryon_wrapper.h"
#include "benchmarks.h"

using namespace tiramisu;

/**
 * Res2 = 0
   For x0 in 0 to BARYON_N
     For x1 in 0 to BARYON_N
       For x2 in 0 to BARYON_N
       {
          Res0 = S(c1, x0, x1, x2, t, a1, x’0)*S(c2, x0, x1, x2, t, a2, x’0)*S(c3, x0, x1, x2, t, a3, x’0)
                +S(c2, x0, x1, x2, t, a1, x’0)*S(c3, x0, x1, x2, t, a2, x’0)*S(c1, x0, x1, x2, t, a3, x’0)
                +S(c3, x0, x1, x2, t, a1, x’0)*S(c1, x0, x1, x2, t, a2, x’0)*S(c2, x0, x1, x2, t, a3, x’0)
                -S(c2, x0, x1, x2, t, a1, x’0)*S(c1, x0, x1, x2, t, a2, x’0)*S(c3, x0, x1, x2, t, a3, x’0)
                -S(c3, x0, x1, x2, t, a1, x’0)*S(c2, x0, x1, x2, t, a2, x’0)*S(c1, x0, x1, x2, t, a3, x’0)
                -S(c1, x0, x1, x2, t, a1, x’0)*S(c3, x0, x1, x2, t, a2, x’0)*S(c2, x0, x1, x2, t, a3, x’0)

         Res1 = 0
         For k = 1 to N(B(b0, b1, b2))
           Res1 += w’(c1, c2, c3, b0, b1, b2, k) * Res0;

         Res2 += exp(i(x0*px+x1*py+x2*pz)) * Res1;
       }

 - Questions:
 -------------
 - what is the size of the dimensions of S[] ?
 */

void generate_function(std::string name, int size)
{
    tiramisu::global::set_default_tiramisu_options();

    // -------------------------------------------------------
    // Layer I
    // -------------------------------------------------------

    tiramisu::function function0(name);
    tiramisu::constant N_CONST("N", tiramisu::expr((int32_t) size), p_int32, true, NULL, 0, &function0);
    tiramisu::constant c1("c1", tiramisu::expr((int32_t) 0), p_int32, true, NULL, 0, &function0);
    tiramisu::constant c2("c2", tiramisu::expr((int32_t) 0), p_int32, true, NULL, 0, &function0);
    tiramisu::constant c3("c3", tiramisu::expr((int32_t) 0), p_int32, true, NULL, 0, &function0);
    tiramisu::constant t("t", tiramisu::expr((int32_t) 0), p_int32, true, NULL, 0, &function0);
    tiramisu::constant a1("a1", tiramisu::expr((int32_t) 0), p_int32, true, NULL, 0, &function0);
    tiramisu::constant a2("a2", tiramisu::expr((int32_t) 0), p_int32, true, NULL, 0, &function0);
    tiramisu::constant a3("a3", tiramisu::expr((int32_t) 0), p_int32, true, NULL, 0, &function0);
    tiramisu::constant xp0("xp0", tiramisu::expr((int32_t) 0), p_int32, true, NULL, 0, &function0);
    tiramisu::constant KMAX("KMAX", tiramisu::expr((int32_t) size), p_int32, true, NULL, 0, &function0);
    tiramisu::constant b0("b0", tiramisu::expr((int32_t) 0), p_int32, true, NULL, 0, &function0);
    tiramisu::constant b1("b1", tiramisu::expr((int32_t) 0), p_int32, true, NULL, 0, &function0);
    tiramisu::constant b2("b2", tiramisu::expr((int32_t) 0), p_int32, true, NULL, 0, &function0);

    tiramisu::var x0("x0"), x1("x1"), x2("x2"), k("k");
    tiramisu::computation S("{S[i0, i1, i2, i3, i4, i5, i6]}", tiramisu::expr(), false, p_float32, &function0);
    tiramisu::computation wp("{wp[c1, c2, c3, b1, b2, b3, k]}", tiramisu::expr(), false, p_float32, &function0);

    tiramisu::computation Res0("[N]->{Res0[x0, x1, x2]: 0<=x0<N and 0<=x1<N and 0<=x2<N}", tiramisu::expr(), true, p_float32, &function0);
    Res0.set_expression(
		  S(c1, x0, x1, x2, t, a1, xp0) * S(c2, x0, x1, x2, t, a2, xp0) * S(c3, x0, x1, x2, t, a3, xp0)
                + S(c2, x0, x1, x2, t, a1, xp0) * S(c3, x0, x1, x2, t, a2, xp0) * S(c1, x0, x1, x2, t, a3, xp0)
                + S(c3, x0, x1, x2, t, a1, xp0) * S(c1, x0, x1, x2, t, a2, xp0) * S(c2, x0, x1, x2, t, a3, xp0)
                - S(c2, x0, x1, x2, t, a1, xp0) * S(c1, x0, x1, x2, t, a2, xp0) * S(c3, x0, x1, x2, t, a3, xp0)
                - S(c3, x0, x1, x2, t, a1, xp0) * S(c2, x0, x1, x2, t, a2, xp0) * S(c1, x0, x1, x2, t, a3, xp0)
                - S(c1, x0, x1, x2, t, a1, xp0) * S(c3, x0, x1, x2, t, a2, xp0) * S(c2, x0, x1, x2, t, a3, xp0)
	    );
    tiramisu::computation Res1("[N]->{Res1[x0, x1, x2, k]: 0<=x0<N and 0<=x1<N and 0<=x2<N and k=0}", tiramisu::expr((float) 0), true, p_float32, &function0);
    tiramisu::computation Res1_update_0("[N, KMAX]->{Res1_update_0[x0, x1, x2, k]: 0<=x0<N and 0<=x1<N and 0<=x2<N and 1<=k<KMAX}", tiramisu::expr(), true, p_float32, &function0);
    Res1_update_0.set_expression(Res1(x0, x1, x2, k-1) + wp(c1, c2, c3, b0, b1, b2, k) * Res0(x0, x1, x2));

    tiramisu::computation Res2("[N]->{Res2[0]}", tiramisu::expr((float) 0), true, p_float32, &function0);
    tiramisu::computation Res2_update_0("[N]->{Res2_update_0[x0, x1, x2]: 0<=x0<N and 0<=x1<N and 0<=x2<N}", tiramisu::expr(), true, p_float32, &function0);
    Res2_update_0.set_expression(Res2_update_0(x0, x1, x2) + /* exp(i(x0*px+x1*py+x2*pz)) */ Res1_update_0(x0, x1, x2, KMAX));

    // -------------------------------------------------------
    // Layer II
    // -------------------------------------------------------

    Res0.after(Res2, tiramisu::computation::root);
    Res1.after(Res0, x2);
    Res1_update_0.after(Res1, x2);
    Res2_update_0.after(Res1_update_0, x2);

    // -------------------------------------------------------
    // Layer III
    // -------------------------------------------------------

    tiramisu::buffer buf_res0("buf_res0", {tiramisu::expr((int32_t) 1)}, tiramisu::p_float32, a_temporary, &function0);
    tiramisu::buffer buf_res1("buf_res1", {tiramisu::expr((int32_t) 1)}, tiramisu::p_float32, a_temporary, &function0);
    tiramisu::buffer buf_res2("buf_res2", {tiramisu::expr((int32_t) 1)}, tiramisu::p_float32, a_output, &function0);
    // S(c1, x0, x1, x2, t, a1, x’0)
    tiramisu::buffer buf_S("buf_S", {tiramisu::expr((int32_t) BARYON_P), N_CONST, N_CONST, N_CONST, tiramisu::expr((int32_t) BARYON_P), tiramisu::expr((int32_t) BARYON_P), tiramisu::expr((int32_t) BARYON_P)}, tiramisu::p_float32, a_input, &function0);
    // wp(c1, c2, c3, b0, b1, b2, k)
    tiramisu::buffer buf_wp("buf_wp", {tiramisu::expr((int32_t) BARYON_P), tiramisu::expr((int32_t) BARYON_P), tiramisu::expr((int32_t) BARYON_P), tiramisu::expr((int32_t) BARYON_P), tiramisu::expr((int32_t) BARYON_P), tiramisu::expr((int32_t) BARYON_P), KMAX}, tiramisu::p_float32, a_input, &function0);

    Res0.set_access("{Res0[x0,x1,x2]->buf_res0[0]}");
    Res1.set_access("{Res1[x0,x1,x2,k]->buf_res1[0]}");
    Res1_update_0.set_access("{Res1_update_0[x0,x1,x2,k]->buf_res1[0]}");
    Res2.set_access("{Res2[0]->buf_res2[0]}");
    Res2_update_0.set_access("{Res2_update_0[x0,x1,x2]->buf_res2[0]}");
    S.set_access("{S[c1,x0,x1,x2,t,a1,xp0]->buf_S[c1,x0,x1,x2,t,a1,xp0]}");
    wp.set_access("{wp[c1,c2,c3,b0,b1,b2,k]->buf_wp[c1,c2,c3,b0,b1,b2,k]}");

    // -------------------------------------------------------
    // Code Generation
    // -------------------------------------------------------

    function0.set_arguments({&buf_res2, &buf_S, &buf_wp});
    function0.gen_time_space_domain();
    function0.gen_isl_ast();
    function0.gen_halide_stmt();
    function0.gen_halide_obj("generated_" + std::string(TEST_NAME_STR) + ".o");
}

int main(int argc, char **argv)
{
    generate_function("tiramisu_generated_code", BARYON_N);

    return 0;
}
<|endoftext|>


<commit_before>//----------------------------------------------------------------------------
/// \file common.hpp
//----------------------------------------------------------------------------
/// \namespace dmf Distributed Monitoring Framework.
///
/// This file contains a set of commonly used functions.
//----------------------------------------------------------------------------
// Copyright (c) 2010 Serge Aleynikov <saleyn@gmail.com>
// Created: 2010-09-20
//----------------------------------------------------------------------------

#ifndef _EIXX_COMMON_HPP_
#define _EIXX_COMMON_HPP_

#include <string>
#include <sstream>
#include <stdexcept>
#include <boost/interprocess/detail/atomic.hpp>
#include <boost/version.hpp>
#include <boost/static_assert.hpp>
#include <boost/assert.hpp>
#include <eixx/util/compiler_hints.hpp>

#ifdef HAVE_CONFIG_H
#include <eixx/config.h>
#endif

#define ERL_MONITOR_P       19
#define ERL_DEMONITOR_P     20
#define ERL_MONITOR_P_EXIT  21

namespace EIXX_NAMESPACE {

#if BOOST_VERSION > 104800
namespace bid = boost::interprocess::ipcdetail;
#else
namespace bid = boost::interprocess::detail;
#endif

/// \def THROW_RUNTIME_ERROR(S)
/// Throw an <tt>std::runtime_error</tt> by allowing to use a stream
/// operator to create \a S.
#ifndef THROW_RUNTIME_ERROR
#define THROW_RUNTIME_ERROR(S) \
    do { \
        std::stringstream _s; _s << S; throw std::runtime_error(_s.str().c_str()); \
    } while(0)
#endif

/// \def ON_ERROR_CALLBACK(Client, S)
/// Invokes an error callback from within perc_client's implementation.
///
/// @param Client is of type 'dmf::client'
/// @param S      is the stream of elements to include in the message.
///               The elements can be concatinated with left shift
///               notation.
#define ON_ERROR_CALLBACK(Connection, S) \
    do { \
        std::stringstream __s; __s << S; \
        (Connection)->on_error(__s.str()); \
    } while(0)

/// Calculate <tt>a</tt> raised to the power of <tt>b</tt>.
template <typename T>
T inline power(T a, size_t b) {
    if (a==0) return 0;
    if (b==0) return 1;
    if (b==1) return a;
    return (b & (b-1)) == 0 ? power(a*a, b >> 1) : a*power(a*a, b >> 1);
}

int __inline__ log2(unsigned long n, uint8_t base = 2) {
    BOOST_ASSERT(n > 0);
    return n == 1 ? 0 : 1+log2(n/base, base);
}

static __inline__ unsigned long bit_scan_forward(unsigned long v)
{
    unsigned long r;
    __asm__ __volatile__(
        #if (__SIZEOF_LONG__ == 8)
            "bsfq %1, %0": "=r"(r): "rm"(v) );
        #else
            "bsfl %1, %0": "=r"(r): "rm"(v) );
        #endif
    return r;
}

/// Wrapper for basic atomic operations over an integer.
template <typename T>
struct atomic {
    atomic(T a = 0): m_value(a) {
        // For now we just support 32bit signed and unsigned ints
        BOOST_STATIC_ASSERT(sizeof(T) == 4);
    }
    T operator++ ()                 { return bid::atomic_inc32(&m_value)+1; }
    T operator-- ()                 { return bid::atomic_dec32(&m_value)-1; }
    T operator++ (int)              { return bid::atomic_inc32(&m_value); }
    operator T () const             { return m_value; }
    void operator= (const T& rhs)   { xchg(rhs); }
    void operator+= (const T& a)    { bid::atomic_add32(&m_value, a); }

    void xchg(const T& a)           { bid::atomic_write32(&m_value, a); }

    T cas(const T& a_old, const T& a_new) {
        return bid::atomic_cas32(&m_value, a_new, a_old);
    }
private:
    uint32_t m_value;
};

/// Return the index of a_string in the a_list using a_default index if
/// a_string is not found in the list.
template <int N>
int find_index(const char* (&a_list)[N], const char* a_string, int a_default=-1) {
    for (int i=0; i < N; i++)
        if (strcmp(a_string, a_list[i]) == 0)
            return i;
    return a_default;
}

} // namespace EIXX_NAMESPACE

#endif // _EIXX_COMMON_HPP_

<commit_msg>Reimplement bit_scan_forward using __builtin_ctzl<commit_after>//----------------------------------------------------------------------------
/// \file common.hpp
//----------------------------------------------------------------------------
/// \namespace dmf Distributed Monitoring Framework.
///
/// This file contains a set of commonly used functions.
//----------------------------------------------------------------------------
// Copyright (c) 2010 Serge Aleynikov <saleyn@gmail.com>
// Created: 2010-09-20
//----------------------------------------------------------------------------

#ifndef _EIXX_COMMON_HPP_
#define _EIXX_COMMON_HPP_

#include <string>
#include <sstream>
#include <stdexcept>
#include <boost/interprocess/detail/atomic.hpp>
#include <boost/version.hpp>
#include <boost/static_assert.hpp>
#include <boost/assert.hpp>
#include <eixx/util/compiler_hints.hpp>

#ifdef HAVE_CONFIG_H
#include <eixx/config.h>
#endif

#define ERL_MONITOR_P       19
#define ERL_DEMONITOR_P     20
#define ERL_MONITOR_P_EXIT  21

namespace EIXX_NAMESPACE {

#if BOOST_VERSION > 104800
namespace bid = boost::interprocess::ipcdetail;
#else
namespace bid = boost::interprocess::detail;
#endif

/// \def THROW_RUNTIME_ERROR(S)
/// Throw an <tt>std::runtime_error</tt> by allowing to use a stream
/// operator to create \a S.
#ifndef THROW_RUNTIME_ERROR
#define THROW_RUNTIME_ERROR(S) \
    do { \
        std::stringstream _s; _s << S; throw std::runtime_error(_s.str().c_str()); \
    } while(0)
#endif

/// \def ON_ERROR_CALLBACK(Client, S)
/// Invokes an error callback from within perc_client's implementation.
///
/// @param Client is of type 'dmf::client'
/// @param S      is the stream of elements to include in the message.
///               The elements can be concatinated with left shift
///               notation.
#define ON_ERROR_CALLBACK(Connection, S) \
    do { \
        std::stringstream __s; __s << S; \
        (Connection)->on_error(__s.str()); \
    } while(0)

/// Calculate <tt>a</tt> raised to the power of <tt>b</tt>.
template <typename T>
T inline power(T a, size_t b) {
    if (a==0) return 0;
    if (b==0) return 1;
    if (b==1) return a;
    return (b & (b-1)) == 0 ? power(a*a, b >> 1) : a*power(a*a, b >> 1);
}

int __inline__ log2(unsigned long n, uint8_t base = 2) {
    BOOST_ASSERT(n > 0);
    return n == 1 ? 0 : 1+log2(n/base, base);
}

static __inline__ unsigned long bit_scan_forward(unsigned long v)
{
    return __builtin_ctzl(v);
}

/// Wrapper for basic atomic operations over an integer.
template <typename T>
struct atomic {
    atomic(T a = 0): m_value(a) {
        // For now we just support 32bit signed and unsigned ints
        BOOST_STATIC_ASSERT(sizeof(T) == 4);
    }
    T operator++ ()                 { return bid::atomic_inc32(&m_value)+1; }
    T operator-- ()                 { return bid::atomic_dec32(&m_value)-1; }
    T operator++ (int)              { return bid::atomic_inc32(&m_value); }
    operator T () const             { return m_value; }
    void operator= (const T& rhs)   { xchg(rhs); }
    void operator+= (const T& a)    { bid::atomic_add32(&m_value, a); }

    void xchg(const T& a)           { bid::atomic_write32(&m_value, a); }

    T cas(const T& a_old, const T& a_new) {
        return bid::atomic_cas32(&m_value, a_new, a_old);
    }
private:
    uint32_t m_value;
};

/// Return the index of a_string in the a_list using a_default index if
/// a_string is not found in the list.
template <int N>
int find_index(const char* (&a_list)[N], const char* a_string, int a_default=-1) {
    for (int i=0; i < N; i++)
        if (strcmp(a_string, a_list[i]) == 0)
            return i;
    return a_default;
}

} // namespace EIXX_NAMESPACE

#endif // _EIXX_COMMON_HPP_

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2006-2013  Music Technology Group - Universitat Pompeu Fabra
 *
 * This file is part of Essentia
 *
 * Essentia is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation (FSF), either version 3 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the Affero GNU General Public License
 * version 3 along with this program.  If not, see http://www.gnu.org/licenses/
 */

#include "sinesubtraction.h"
#include "essentiamath.h"
#include <essentia/utils/synth_utils.h>

using namespace essentia;
using namespace standard;

/*
	"""
	Subtract sinusoids from a sound
	x: input sound, N: fft-size, H: hop-size
	sfreq, smag, sphase: sinusoidal frequencies, magnitudes and phases
	returns xr: residual sound
	"""

	hN = N/2                                           # half of fft size
	x = np.append(np.zeros(hN),x)                      # add zeros at beginning to center first window at sample 0
	x = np.append(x,np.zeros(hN))                      # add zeros at the end to analyze last sample
	bh = blackmanharris(N)                             # blackman harris window
	w = bh/ sum(bh)                                    # normalize window
	sw = np.zeros(N)                                   # initialize synthesis window
	sw[hN-H:hN+H] = triang(2*H) / w[hN-H:hN+H]         # synthesis window
	L = sfreq.shape[0]                                 # number of frames, this works if no sines
	xr = np.zeros(x.size)                              # initialize output array
	pin = 0
	# jjaner debug
	outresmag = []
	for l in range(L):
		xw = x[pin:pin+N]*w                              # window the input sound
		X = fft(fftshift(xw))                            # compute FFT
		Yh = UF_C.genSpecSines(N*sfreq[l,:]/fs, smag[l,:], sphase[l,:], N)   # generate spec sines
		Xr = X-Yh
		print Xr.shape                                     # subtract sines from original spectrum
		outresmag = np.append(outresmag, abs(Xr))
		xrw = np.real(fftshift(ifft(Xr)))                # inverse FFT
		xr[pin:pin+N] += xrw*sw                          # overlap-add
		pin += H                                         # advance sound pointer
	xr = np.delete(xr, range(hN))                      # delete half of first window which was added in stftAnal
	xr = np.delete(xr, range(xr.size-hN, xr.size))     # delete half of last window which was added in stftAnal

	print("jj debug: writing output residual magnitude")
	np.savetxt('outresmag.txt',outresmag)
	return xr
	*/

const char* SineSubtraction::name = "SineSubtraction";
const char* SineSubtraction::description = DOC("This algorithm subtracts the sinusoids computed with the sine model analysis from an input audio signal. It ouputs an audio signal.");

void SineSubtraction::configure() {

    _sampleRate = parameter("sampleRate").toReal();
    _fftSize = parameter("fftSize").toInt();
    _hopSize = parameter("hopSize").toInt();

	 	std::string wtype = "blackmanharris92"; // default "hamming"
		_window->configure( "type", wtype.c_str());

	// create synthesis window
	createSynthesisWindow(_synwindow, _hopSize, _fftSize);

}

void SineSubtraction::compute() {

  const std::vector<Real>& inframe = _inframe.get();
  const std::vector<Real>& magnitudes = _magnitudes.get();
  const std::vector<Real>& frequencies = _frequencies.get();
  const std::vector<Real>& phases = _phases.get();

  std::vector<Real>& outframe = _outframe.get();
//
  std::vector<Real> sinesframe;

	// compute input frame FFT
	std::vector<Real> synframe;
	std::vector<Real> wsynframe;
	std::vector<Real> synframeout;

	std::vector<std::complex<Real> > synfft;
	for (int i= (int) ((inframe.size()/2) - _fftSize/2); i <  (int) ((inframe.size()/2) + _fftSize/2); ++i)
	{
		synframe.push_back(inframe[i]);
	}

	_window->input("frame").set(synframe);
	_window->output("frame").set(wsynframe);
	_window->compute();

	_fft->input("frame").set(wsynframe);
	_fft->output("fft").set(synfft);
	_fft->compute();

	// generate sine spectrum
	std::vector<std::complex<Real> > sinefft;
	generateSines(magnitudes, frequencies, phases, sinefft);

  // subtract  sines in FFT domain
	subtractFFT(synfft, sinefft);

  // IFFT of subtracted spectra
	_ifft->input("fft").set(synfft);
	_ifft->output("frame").set(synframeout);
	_ifft->compute();

	applySynthesisWindow(synframeout, _synwindow);

	// overlapp add synthesized audio
	_overlapadd->input("signal").set(synframeout);
	_overlapadd->output("signal").set(outframe);
	_overlapadd->compute();

}

void 	SineSubtraction::subtractFFT(std::vector<std::complex<Real> >&fft1, const std::vector<std::complex<Real> >&fft2)
{
  int minSize = std::min((int)fft1.size(), (int)fft2.size());
  for (int i=0; i < minSize; ++i){
    fft1[i].real( fft1[i].real() -  fft2[i].real());
    fft1[i].imag( fft1[i].imag() -  fft2[i].imag());
  }
}

void SineSubtraction::initializeFFT(std::vector<std::complex<Real> >&fft, int sizeFFT)
{
  fft.resize(sizeFFT);
  for (int i=0; i < sizeFFT; ++i){
    fft[i].real(0);
    fft[i].imag(0);
  }
}

void SineSubtraction::generateSines(const std::vector<Real> magnitudes, const std::vector<Real> frequencies, const std::vector<Real> phases, std::vector<std::complex<Real> >&outfft)
{
	int outSize = (int)floor(_fftSize/2.0) + 1;
  initializeFFT(outfft, outSize);
  int i = 0;

  // convert frequencies to peak locations
  std::vector<Real> locs(frequencies.size());
  for (i=0; i < int(frequencies.size()); ++i){
    locs[i] = _fftSize*frequencies[i]/float(_sampleRate);
  }
  // init synth phase vector
  std::vector<Real> ytphase(frequencies.size());
  std::fill(ytphase.begin(), ytphase.end(), 0.);

  // initialize last phase and frequency vectors
  if (_lastytphase.size() < ytphase.size())
  {
    _lastytphase.resize(ytphase.size());
    std::fill(_lastytphase.begin(), _lastytphase.end(), 0.);
  }
  if (_lastytfreq.size() < frequencies.size())
  {
    _lastytfreq.resize(frequencies.size());
    std::fill(_lastytfreq.begin(), _lastytfreq.end(), 0.);
  }

  // propagate phase if necessary (no input phase vector)
  if (int(phases.size()) > 0){                                 // if no phases generate them
	  	ytphase = phases;
	  }
  else{
		for (i=0; i < int(ytphase.size()); ++i)
		{
			ytphase[i] = _lastytphase[i] + (M_PI * (_lastytfreq[i] + frequencies[i])/float(_sampleRate)) * _hopSize;     // propagate phases
    }
  }

  // generate output fft
  genSpecSines(locs, magnitudes, ytphase, outfft, _fftSize);

  for (i = 0; i < int(ytphase.size()); ++i)
  {
		ytphase[i] = fmod (ytphase[i], float(2*M_PI));                        // make phase inside 2*pi
  }

  // save frequency and phase for phase propagation
  _lastytfreq = frequencies;
  _lastytphase = ytphase;

}

void SineSubtraction::createSynthesisWindow(std::vector<Real> &synwindow, int hopSize, int winSize)
{
	std::vector<Real> ones;
	std::vector<Real> triangle;
	std::vector<Real> win;

	for (int i=0; i < winSize;++i){
		ones.push_back(1.f);
	}

	_window->input("frame").set(ones);
	_window->output("frame").set(win);
	_window->compute();

	// create traingular
	Algorithm* triangular;
	std::string wtype = "triangular"; // default "hamming"
	triangular = AlgorithmFactory::create("Windowing", "type", wtype.c_str());
	ones.resize(2*hopSize); // trim to size 2*hopsize
	triangular->input("frame").set(ones);
	triangular->output("frame").set(triangle);
	triangular->compute();

	// init synthesis window
	synwindow.resize(winSize);
	std::fill(synwindow.begin(), synwindow.end(), 0.);

	int hN = winSize / 2;

	// first half of the windowed signal is the
	// second half of the signal with windowing!
	int i=0;
	for (int j=hN; j<hN + hopSize; j++) {
		synwindow[i++] = triangle[j - hN + hopSize] / win[j];
	}

	// second half of the signal
	i = winSize - hopSize;
	for (int j=hN - hopSize; j<hN; j++) {
		synwindow[i++] = triangle[j - hN + hopSize] / win[j];
	}

	delete triangular;

}

void SineSubtraction::applySynthesisWindow(std::vector<Real> &inframe, const std::vector<Real> synwindow)
{
// it considers zero-phase window shift

printf("TODO: Still testign the synthesis window values!!\n");
	int signalSize = (int)inframe.size();
	for (int i= 0 ; i < signalSize ;++i){

		inframe[i] *= synwindow[i];
	}

//
//    // first half of the windowed signal is the
//    // second half of the signal with windowing!
//    int i=0;
//    for (int j=signalSize/2; j<signalSize; j++) {
//      inframe[i++] *= synwindow[j] ;
//    }
//
//    // second half of the signal
//    for (int j=0; j<signalSize/2; j++) {
//      inframe[i++] *= synwindow[j] ;
//    }

}
<commit_msg>sine subtraction algorithm finished. Comparatuive testing with Python implementation  done.<commit_after>/*
 * Copyright (C) 2006-2013  Music Technology Group - Universitat Pompeu Fabra
 *
 * This file is part of Essentia
 *
 * Essentia is free software: you can redistribute it and/or modify it under
 * the terms of the GNU Affero General Public License as published by the Free
 * Software Foundation (FSF), either version 3 of the License, or (at your
 * option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the Affero GNU General Public License
 * version 3 along with this program.  If not, see http://www.gnu.org/licenses/
 */

#include "sinesubtraction.h"
#include "essentiamath.h"
#include <essentia/utils/synth_utils.h>

using namespace essentia;
using namespace standard;

/*
	"""
	Subtract sinusoids from a sound
	x: input sound, N: fft-size, H: hop-size
	sfreq, smag, sphase: sinusoidal frequencies, magnitudes and phases
	returns xr: residual sound
	"""

	hN = N/2                                           # half of fft size
	x = np.append(np.zeros(hN),x)                      # add zeros at beginning to center first window at sample 0
	x = np.append(x,np.zeros(hN))                      # add zeros at the end to analyze last sample
	bh = blackmanharris(N)                             # blackman harris window
	w = bh/ sum(bh)                                    # normalize window
	sw = np.zeros(N)                                   # initialize synthesis window
	sw[hN-H:hN+H] = triang(2*H) / w[hN-H:hN+H]         # synthesis window
	L = sfreq.shape[0]                                 # number of frames, this works if no sines
	xr = np.zeros(x.size)                              # initialize output array
	pin = 0
	# jjaner debug
	outresmag = []
	for l in range(L):
		xw = x[pin:pin+N]*w                              # window the input sound
		X = fft(fftshift(xw))                            # compute FFT
		Yh = UF_C.genSpecSines(N*sfreq[l,:]/fs, smag[l,:], sphase[l,:], N)   # generate spec sines
		Xr = X-Yh
		print Xr.shape                                     # subtract sines from original spectrum
		outresmag = np.append(outresmag, abs(Xr))
		xrw = np.real(fftshift(ifft(Xr)))                # inverse FFT
		xr[pin:pin+N] += xrw*sw                          # overlap-add
		pin += H                                         # advance sound pointer
	xr = np.delete(xr, range(hN))                      # delete half of first window which was added in stftAnal
	xr = np.delete(xr, range(xr.size-hN, xr.size))     # delete half of last window which was added in stftAnal

	print("jj debug: writing output residual magnitude")
	np.savetxt('outresmag.txt',outresmag)
	return xr
	*/

const char* SineSubtraction::name = "SineSubtraction";
const char* SineSubtraction::description = DOC("This algorithm subtracts the sinusoids computed with the sine model analysis from an input audio signal. It ouputs an audio signal.");

void SineSubtraction::configure() {

    _sampleRate = parameter("sampleRate").toReal();
    _fftSize = parameter("fftSize").toInt();
    _hopSize = parameter("hopSize").toInt();

// configure algorithms
	 	std::string wtype = "blackmanharris92"; // default "hamming"
		_window->configure( "type", wtype.c_str());

	_fft->configure("size", _fftSize);

	_overlapadd->configure( "frameSize", _fftSize, // uses synthesis window
													"hopSize", _hopSize);
	// create synthesis window
	createSynthesisWindow(_synwindow, _hopSize, _fftSize);

// configure algorithms

}

void SineSubtraction::compute() {

  const std::vector<Real>& inframe = _inframe.get();
  const std::vector<Real>& magnitudes = _magnitudes.get();
  const std::vector<Real>& frequencies = _frequencies.get();
  const std::vector<Real>& phases = _phases.get();

  std::vector<Real>& outframe = _outframe.get();
//
  std::vector<Real> sinesframe;

	// compute input frame FFT
	std::vector<Real> synframe;
	std::vector<Real> wsynframe;
	std::vector<Real> synframeout;

	std::vector<std::complex<Real> > synfft;
	for (int i= (int) ((inframe.size()/2) - _fftSize/2); i <  (int) ((inframe.size()/2) + _fftSize/2); ++i)
	{
		synframe.push_back(inframe[i]);
	}

	_window->input("frame").set(synframe);
	_window->output("frame").set(wsynframe);
	_window->compute();

	_fft->input("frame").set(wsynframe);
	_fft->output("fft").set(synfft);
	_fft->compute();

	// generate sine spectrum
	std::vector<std::complex<Real> > sinefft;
	generateSines(magnitudes, frequencies, phases, sinefft);

  // subtract  sines in FFT domain
	subtractFFT(synfft, sinefft);

  // IFFT of subtracted spectra
	_ifft->input("fft").set(synfft);
	_ifft->output("frame").set(synframeout);
	_ifft->compute();

	applySynthesisWindow(synframeout, _synwindow);

	// overlapp add synthesized audio
	_overlapadd->input("signal").set(synframeout);
	_overlapadd->output("signal").set(outframe);
	_overlapadd->compute();

}

void 	SineSubtraction::subtractFFT(std::vector<std::complex<Real> >&fft1, const std::vector<std::complex<Real> >&fft2)
{
  int minSize = std::min((int)fft1.size(), (int)fft2.size());
  for (int i=0; i < minSize; ++i){
    fft1[i].real( fft1[i].real() -  fft2[i].real());
    fft1[i].imag( fft1[i].imag() -  fft2[i].imag());
  }
}

void SineSubtraction::initializeFFT(std::vector<std::complex<Real> >&fft, int sizeFFT)
{
  fft.resize(sizeFFT);
  for (int i=0; i < sizeFFT; ++i){
    fft[i].real(0);
    fft[i].imag(0);
  }
}

void SineSubtraction::generateSines(const std::vector<Real> magnitudes, const std::vector<Real> frequencies, const std::vector<Real> phases, std::vector<std::complex<Real> >&outfft)
{
	int outSize = (int)floor(_fftSize/2.0) + 1;
  initializeFFT(outfft, outSize);
  int i = 0;

  // convert frequencies to peak locations
  std::vector<Real> locs(frequencies.size());
  for (i=0; i < int(frequencies.size()); ++i){
    locs[i] = _fftSize*frequencies[i]/float(_sampleRate);
  }
  // init synth phase vector
  std::vector<Real> ytphase(frequencies.size());
  std::fill(ytphase.begin(), ytphase.end(), 0.);

  // initialize last phase and frequency vectors
  if (_lastytphase.size() < ytphase.size())
  {
    _lastytphase.resize(ytphase.size());
    std::fill(_lastytphase.begin(), _lastytphase.end(), 0.);
  }
  if (_lastytfreq.size() < frequencies.size())
  {
    _lastytfreq.resize(frequencies.size());
    std::fill(_lastytfreq.begin(), _lastytfreq.end(), 0.);
  }

  // propagate phase if necessary (no input phase vector)
  if (int(phases.size()) > 0){                                 // if no phases generate them
	  	ytphase = phases;
	  }
  else{
		for (i=0; i < int(ytphase.size()); ++i)
		{
			ytphase[i] = _lastytphase[i] + (M_PI * (_lastytfreq[i] + frequencies[i])/float(_sampleRate)) * _hopSize;     // propagate phases
    }
  }

  // generate output fft
  genSpecSines(locs, magnitudes, ytphase, outfft, _fftSize);

  for (i = 0; i < int(ytphase.size()); ++i)
  {
		ytphase[i] = fmod (ytphase[i], float(2*M_PI));                        // make phase inside 2*pi
  }

  // save frequency and phase for phase propagation
  _lastytfreq = frequencies;
  _lastytphase = ytphase;

}

void SineSubtraction::createSynthesisWindow(std::vector<Real> &synwindow, int hopSize, int winSize)
{
	std::vector<Real> ones;
	std::vector<Real> triangle;
	std::vector<Real> win;

	for (int i=0; i < winSize;++i){
		ones.push_back(1.f);
	}

	_window->input("frame").set(ones);
	_window->output("frame").set(win);
	_window->compute();

	// create traingular
	Algorithm* triangular;
	std::string wtype = "triangular"; // default "hamming"
	triangular = AlgorithmFactory::create("Windowing", "type", wtype.c_str());
	ones.resize(2*hopSize); // trim to size 2*hopsize
	triangular->input("frame").set(ones);
	triangular->output("frame").set(triangle);
	triangular->compute();

	// init synthesis window
	synwindow.resize(winSize);
	std::fill(synwindow.begin(), synwindow.end(), 0.);

	int hN = winSize / 2;

	// first half of the windowed signal is the
	// second half of the signal with windowing!
	int i=0;
	for (int j=0; j< hopSize; j++) {
		synwindow[i++] = triangle[j] / win[j];
	}

	// second half of the signal
	i = winSize - hopSize;
	for (int j= hopSize; j< 2 * hopSize; j++) {
		synwindow[i] = triangle[j] / win[i];
		i++;
	}

	delete triangular;

}

void SineSubtraction::applySynthesisWindow(std::vector<Real> &inframe, const std::vector<Real> synwindow)
{
// it considers already the zero-phase window shift
	int signalSize = (int)inframe.size();

	for (int i= 0 ; i < signalSize ;++i){
		inframe[i] *= synwindow[i];
	}

}
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <sstream>

#include <boost/program_options.hpp>
#include <boost/program_options/variables_map.hpp>

#include "filelib.h"
#include "weights.h"
#include "line_optimizer.h"
#include "hg.h"
#include "hg_io.h"

using namespace std;
namespace po = boost::program_options;

typedef SparseVector<double> Dir;

typedef RandomNumberGenerator<boost::mt19937> RNG;
RNG rng;

struct oracle_directions {
  string forest_repository;
  unsigned dev_set_size;
  vector<Dir> dirs; //best_to_hope_dirs
  vector<int> fids;
  string forest_file(unsigned i) const {
    ostringstream o;
    o << forest_repository << '/' << i << ".json.gz";
    return o.str();
  }

  oracle_directions(string forest_repository,unsigned dev_set_size,vector<int> const& fids=vector<int>()): forest_repository(forest_repository),dev_set_size(dev_set_size),fids(fids) {
    dirs.resize(dev_set_size);
  }
  Dir const& operator[](unsigned i) {
    Dir &dir=dirs[i];
    if (dir.empty()) {
      ReadFile rf(forest_file(i));
      Hypergraph hg;
      HypergraphIO::ReadFromJSON(rf.stream(), &hg);
      cerr<<"oracle: forest["<<i<<"] loaded: "<<hg.stats()<<endl;
      //TODO: get hope/oracle from vlad.  random for now.
      LineOptimizer::RandomUnitVector(fids,&dir,&rng);
    }
    return dir;
  }

};

void compress_similar(vector<Dir> &dirs,double min_dist,ostream *log=&cerr,bool avg=true) {
  if (min_dist<=0) return;
  double max_s=1.-min_dist;
  unsigned N=dirs.size();
  for (int i=0;i<N;++i) {
    for (int j=i+1;j<N;++j) {
      double s=dirs[i].tanimoto_coef(dirs[j]);
      if (s>max_s) {
        if (log) *log << "Collapsing similar directions (T="<<s<<" > "<<max_s<<").  dirs["<<i<<"]="<<dirs[i]<<" dirs["<<j<<"]";
        if (avg) {
          dirs[i]+=dirs[j];
          dirs[i]/=2.;
          if (log) *log<<" averaged="<<dirs[i];
        }
        if (log) *log<<endl;
        swap(dirs[j],dirs[--N]);
      }
    }
  }
  dirs.resize(N);
}

void InitCommandLine(int argc, char** argv, po::variables_map* conf) {
  po::options_description opts("Configuration options");
  opts.add_options()
        ("dev_set_size,s",po::value<unsigned int>(),"[REQD] Development set size (# of parallel sentences)")
        ("forest_repository,r",po::value<string>(),"[REQD] Path to forest repository")
        ("weights,w",po::value<string>(),"[REQD] Current feature weights file")
        ("optimize_feature,o",po::value<vector<string> >(), "Feature to optimize (if none specified, all weights listed in the weights file will be optimized)")
        ("random_directions,d",po::value<unsigned int>()->default_value(20),"Number of random directions to run the line optimizer in")
    ("no_primary,n","don't use the primary (orthogonal each feature alone) directions")
    ("oracle_directions,O",po::value<unsigned>()->default_value(0),"read the forests and choose this many directions based on heading toward a hope max (bleu+modelscore) translation.")
    ("oracle_batch,b",po::value<unsigned>()->default_value(10),"to produce each oracle direction, sum the 'gradient' over this many sentences")
    ("max_similarity,m",po::value<double>()->default_value(0),"remove directions that are too similar (Tanimoto coeff. less than (1-this)).  0 means don't filter, 1 means only 1 direction allowed?")
        ("help,h", "Help");
  po::options_description dcmdline_options;
  dcmdline_options.add(opts);
  po::store(parse_command_line(argc, argv, dcmdline_options), *conf);
  bool flag = false;
  if (conf->count("dev_set_size") == 0) {
    cerr << "Please specify the size of the development set using -d N\n";
    flag = true;
  }
  if (conf->count("weights") == 0) {
    cerr << "Please specify the starting-point weights using -w <weightfile.txt>\n";
    flag = true;
  }
  if (conf->count("forest_repository") == 0) {
    cerr << "Please specify the forest repository location using -r <DIR>\n";
    flag = true;
  }
  if (flag || conf->count("help")) {
    cerr << dcmdline_options << endl;
    exit(1);
  }
}

int main(int argc, char** argv) {
  po::variables_map conf;
  InitCommandLine(argc, argv, &conf);
  Weights weights;
  vector<string> features;
  weights.InitFromFile(conf["weights"].as<string>(), &features);
  vector<int> fids(features.size());
  for (int i = 0; i < features.size(); ++i)
    fids[i] = FD::Convert(features[i]);

  oracle_directions od(conf["forest_repository"].as<string>()
                       , conf["dev_set_size"].as<unsigned int>()
                       , fids
    );
;
  assert(DirectoryExists(od.forest_repository));
  SparseVector<double> origin;
  weights.InitSparseVector(&origin);
  if (conf.count("optimize_feature") > 0)
    features=conf["optimize_feature"].as<vector<string> >();
  vector<SparseVector<double> > axes;
  LineOptimizer::CreateOptimizationDirections(
     fids,
     conf["random_directions"].as<unsigned int>(),
     &rng,
     &axes,
     !conf.count("no_primary")
    );
  compress_similar(axes,conf["max_similarity"].as<double>());
  for (int i = 0; i < od.dev_set_size; ++i)
    for (int j = 0; j < axes.size(); ++j)
      cout << od.forest_file(i) <<" " << i << ' ' << origin << ' ' << axes[j] << endl;
  return 0;
}
<commit_msg>vest oracle directions<commit_after>#include <iostream>
#include <vector>
#include <sstream>

#include <boost/program_options.hpp>
#include <boost/program_options/variables_map.hpp>

#include "sampler.h"
#include "filelib.h"
#include "weights.h"
#include "line_optimizer.h"
#include "hg.h"
#include "hg_io.h"

using namespace std;
namespace po = boost::program_options;

typedef SparseVector<double> Dir;

MT19937 rng;

struct oracle_directions {
  string forest_repository;
  unsigned dev_set_size;
  vector<Dir> dirs; //best_to_hope_dirs
  vector<int> fids;
  string forest_file(unsigned i) const {
    ostringstream o;
    o << forest_repository << '/' << i << ".json.gz";
    return o.str();
  }

  oracle_directions(string forest_repository,unsigned dev_set_size,vector<int> const& fids=vector<int>()): forest_repository(forest_repository),dev_set_size(dev_set_size),fids(fids) {
    dirs.resize(dev_set_size);
  }
  Dir const& operator[](unsigned i) {
    Dir &dir=dirs[i];
    if (dir.empty()) {
      ReadFile rf(forest_file(i));
      Hypergraph hg;
      HypergraphIO::ReadFromJSON(rf.stream(), &hg);
      cerr<<"oracle: forest["<<i<<"] loaded: "<<hg.stats()<<endl;
      //TODO: get hope/oracle from vlad.  random for now.
      LineOptimizer::RandomUnitVector(fids,&dir,&rng);
    }
    return dir;
  }
  // if start_random is true, immediately sample w/ replacement from src sentences; otherwise, consume them sequentially until exhausted, then random.  oracle vectors are summed
  void add_directions(vector<Dir> &dirs,unsigned n,unsigned batchsz=20,bool start_random=false) {
    MT19937::IntRNG rsg=rng.inclusive(0,dev_set_size-1);
    unsigned b=0;
    for(unsigned i=0;i<n;++i) {
      dirs.push_back(Dir());
      Dir &d=dirs.back();
      for (unsigned j=0;j<batchsz;++j,++b)
        d+=(*this)[(start_random || b>=dev_set_size)?rsg():b];
      d/=(double)batchsz;
    }
  }

};

void compress_similar(vector<Dir> &dirs,double min_dist,ostream *log=&cerr,bool avg=true) {
  if (min_dist<=0) return;
  double max_s=1.-min_dist;
  unsigned N=dirs.size();
  for (int i=0;i<N;++i) {
    for (int j=i+1;j<N;++j) {
      double s=dirs[i].tanimoto_coef(dirs[j]);
      if (s>max_s) {
        if (log) *log << "Collapsing similar directions (T="<<s<<" > "<<max_s<<").  dirs["<<i<<"]="<<dirs[i]<<" dirs["<<j<<"]";
        if (avg) {
          dirs[i]+=dirs[j];
          dirs[i]/=2.;
          if (log) *log<<" averaged="<<dirs[i];
        }
        if (log) *log<<endl;
        swap(dirs[j],dirs[--N]);
      }
    }
  }
  dirs.resize(N);
}

void InitCommandLine(int argc, char** argv, po::variables_map* conf) {
  po::options_description opts("Configuration options");
  opts.add_options()
        ("dev_set_size,s",po::value<unsigned int>(),"[REQD] Development set size (# of parallel sentences)")
        ("forest_repository,r",po::value<string>(),"[REQD] Path to forest repository")
        ("weights,w",po::value<string>(),"[REQD] Current feature weights file")
        ("optimize_feature,o",po::value<vector<string> >(), "Feature to optimize (if none specified, all weights listed in the weights file will be optimized)")
        ("random_directions,d",po::value<unsigned int>()->default_value(20),"Number of random directions to run the line optimizer in")
    ("no_primary,n","don't use the primary (orthogonal each feature alone) directions")
    ("oracle_directions,O",po::value<unsigned>()->default_value(0),"read the forests and choose this many directions based on heading toward a hope max (bleu+modelscore) translation.")
    ("oracle_batch,b",po::value<unsigned>()->default_value(10),"to produce each oracle direction, sum the 'gradient' over this many sentences")
    ("max_similarity,m",po::value<double>()->default_value(0),"remove directions that are too similar (Tanimoto coeff. less than (1-this)).  0 means don't filter, 1 means only 1 direction allowed?")
        ("help,h", "Help");
  po::options_description dcmdline_options;
  dcmdline_options.add(opts);
  po::store(parse_command_line(argc, argv, dcmdline_options), *conf);
  bool flag = false;
  if (conf->count("dev_set_size") == 0) {
    cerr << "Please specify the size of the development set using -d N\n";
    flag = true;
  }
  if (conf->count("weights") == 0) {
    cerr << "Please specify the starting-point weights using -w <weightfile.txt>\n";
    flag = true;
  }
  if (conf->count("forest_repository") == 0) {
    cerr << "Please specify the forest repository location using -r <DIR>\n";
    flag = true;
  }
  if (flag || conf->count("help")) {
    cerr << dcmdline_options << endl;
    exit(1);
  }
}

int main(int argc, char** argv) {
  po::variables_map conf;
  InitCommandLine(argc, argv, &conf);
  Weights weights;
  vector<string> features;
  weights.InitFromFile(conf["weights"].as<string>(), &features);
  vector<int> fids(features.size());
  for (int i = 0; i < features.size(); ++i)
    fids[i] = FD::Convert(features[i]);

  oracle_directions od(conf["forest_repository"].as<string>()
                       , conf["dev_set_size"].as<unsigned int>()
                       , fids
    );
;
  assert(DirectoryExists(od.forest_repository));
  SparseVector<double> origin;
  weights.InitSparseVector(&origin);
  if (conf.count("optimize_feature") > 0)
    features=conf["optimize_feature"].as<vector<string> >();
  vector<SparseVector<double> > axes;
  LineOptimizer::CreateOptimizationDirections(
     fids,
     conf["random_directions"].as<unsigned int>(),
     &rng,
     &axes,
     !conf.count("no_primary")
    );
  od.add_directions(axes,conf["oracle_directions"].as<unsigned>(),conf["oracle_batch"].as<unsigned>());
  compress_similar(axes,conf["max_similarity"].as<double>());
  for (int i = 0; i < od.dev_set_size; ++i)
    for (int j = 0; j < axes.size(); ++j)
      cout << od.forest_file(i) <<" " << i << ' ' << origin << ' ' << axes[j] << endl;
  return 0;
}
<|endoftext|>


<commit_before><commit_msg>Add inversion edge creation to construct<commit_after><|endoftext|>


<commit_before>#include "Halide.h"
#include <tiramisu/utils.h>
#include <cstdlib>
#include <iostream>
#include "benchmarks.h"

#include "baryon_wrapper.h"
#include "baryon_ref.cpp"

int main(int, char **)
{
    std::vector<std::chrono::duration<double,std::milli>> duration_vector_1;
    std::vector<std::chrono::duration<double,std::milli>> duration_vector_2;

    std::complex<double> Blocal[Nsrc][Nc][Ns][Nc][Ns][Nc][Ns][Vsnk][Lt];
    std::complex<double> Bsingle[Nsrc][Nc][Ns][Nc][Ns][Nc][Ns][Vsnk][Vsnk][Lt];
    std::complex<double> prop[Nq][Nc][Ns][Nc][Ns][Vsnk][Lt][Vsrc];
    int color_weights[Nw][Nq];
    int spin_weights[Nw][Nq];
    double weights[Nw];
    std::complex<double> psi[Nsrc][Vsrc];

    // Blocal
    // Blocal_r: tiramisu real part of Blocal.
    // Blocal_i: tiramisu imaginary part of Blocal.
    Halide::Buffer<double> Blocal_r(Lt, Vsnk, Ns, Nc, Ns, Nc, Ns, Nc, Nsrc, "Blocal_r");
    Halide::Buffer<double> Blocal_i(Lt, Vsnk, Ns, Nc, Ns, Nc, Ns, Nc, Nsrc, "Blocal_i");

    // prop
    Halide::Buffer<double> prop_r(Vsrc, Lt, Vsnk, Ns, Nc, Ns, Nc, Nq, "prop_r");
    Halide::Buffer<double> prop_i(Vsrc, Lt, Vsnk, Ns, Nc, Ns, Nc, Nq, "prop_i");

    // psi
    Halide::Buffer<double> psi_r(Vsrc, Nsrc, "psi_r");
    Halide::Buffer<double> psi_i(Vsrc, Nsrc, "psi_i");

    Halide::Buffer<int> color_weights_t(Nq, Nw, "color_weights_t");
    Halide::Buffer<int> spin_weights_t(Nq, Nw, "spin_weights_t");
    Halide::Buffer<double> weights_t(Nw, "weights_t");

    Halide::Buffer<double> Bsingle_r(Lt, Vsrc, Vsnk, Ns, Nc, Ns, Nc, Ns, Nc, Nsrc, "Bsingle_r");
    Halide::Buffer<double> Bsingle_i(Lt, Vsnk, Vsnk, Ns, Nc, Ns, Nc, Ns, Nc, Nsrc, "Bsingle_i");

    // Initialization
   for (int wnum=0; wnum<Nw; wnum++)
   {
       double v = rand()%10;
       weights[wnum] = v;
       weights_t(wnum) = v;
   }

   for (int n=0; n<Nsrc; n++)
     for (int y=0; y<Vsrc; y++)
     {
	double v1 = rand()%10;
	psi[n][y] = v1 + 2i ;
	psi_r(y, n) = v1;
	psi_i(y, n) = 2;
     }

   for (int tri=0; tri<Nq; tri++)
       for (int iCprime=0; iCprime<Nc; iCprime++)
	  for (int iSprime=0; iSprime<Ns; iSprime++)
	     for (int jCprime=0; jCprime<Nc; jCprime++)
		for (int jSprime=0; jSprime<Ns; jSprime++)
                   for (int x=0; x<Vsnk; x++)
                      for (int t=0; t<Lt; t++)
		        for (int y=0; y<Vsrc; y++)
			{
			    double v = rand();
			    prop[tri][iCprime][iSprime][jCprime][jSprime][x][t][y] = v;
			    prop_r(y, t, x, jSprime, jCprime, iSprime, iCprime, tri) = v;
 		        }

   for (int wnum=0; wnum<Nw; wnum++)
	for (int tri=0; tri<Nq; tri++)
	{
		color_weights[wnum][tri] = 0; // tri
		color_weights_t(tri, wnum) = 0; //tri
		spin_weights[wnum][tri] = 0; //tri
		spin_weights_t(tri, wnum) = 0; //tri
	}

    for (int i = 0; i < NB_TESTS; i++)
    {
	    auto start2 = std::chrono::high_resolution_clock::now();

	    make_local_block(Blocal, prop, color_weights, spin_weights, weights, psi);
	    make_single_block(Bsingle, prop, color_weights, spin_weights, weights, psi);

	    auto end2 = std::chrono::high_resolution_clock::now();
	    std::chrono::duration<double,std::milli> duration2 = end2 - start2;
	    duration_vector_2.push_back(duration2);
    }

    for (int i = 0; i < NB_TESTS; i++)
    {
	    auto start1 = std::chrono::high_resolution_clock::now();

	    tiramisu_generated_code(Blocal_r.raw_buffer(),
				    Blocal_i.raw_buffer(),
				    prop_r.raw_buffer(),
				    prop_i.raw_buffer(),
				    weights_t.raw_buffer(),
				    psi_r.raw_buffer(),
				    psi_i.raw_buffer(),
				    color_weights_t.raw_buffer(),
				    spin_weights_t.raw_buffer(),
				    Bsingle_r.raw_buffer(),
				    Bsingle_i.raw_buffer());

	    auto end1 = std::chrono::high_resolution_clock::now();
	    std::chrono::duration<double,std::milli> duration1 = end1 - start1;
	    duration_vector_1.push_back(duration1);
    }

    print_time("performance_CPU.csv", "dibaryon", {"Ref", "Tiramisu"}, {median(duration_vector_2), median(duration_vector_1)});
    std::cout << "\nSpeedup = " << median(duration_vector_2)/median(duration_vector_1) << std::endl;

    // Compare outputs.
    for (int n=0; n<Nsrc; n++)
      for (int iCprime=0; iCprime<Nc; iCprime++)
        for (int iSprime=0; iSprime<Ns; iSprime++)
           for (int jCprime=0; jCprime<Nc; jCprime++)
              for (int jSprime=0; jSprime<Ns; jSprime++)
                 for (int kCprime=0; kCprime<Nc; kCprime++)
                    for (int kSprime=0; kSprime<Ns; kSprime++)
                       for (int x=0; x<Vsnk; x++)
                          for (int t=0; t<Lt; t++)
                              if (std::abs(Blocal[n][iCprime][iSprime][jCprime][jSprime][kCprime][kSprime][x][t].real() -
				  Blocal_r(t, x, kSprime, kCprime, jSprime, jCprime, iSprime, iCprime, n)) >= 0.01)
			      {
				  std::cout << "Error: different computed values for Blocal! Ref = " << Blocal[n][iCprime][iSprime][jCprime][jSprime][kCprime][kSprime][x][t].real() << " - Tiramisu = " << Blocal_r(t, x, kSprime, kCprime, jSprime, jCprime, iSprime, iCprime, n) << std::endl;
				  exit(1);
			      }

    for (int n=0; n<Nsrc; n++)
      for (int iCprime=0; iCprime<Nc; iCprime++)
        for (int iSprime=0; iSprime<Ns; iSprime++)
           for (int jCprime=0; jCprime<Nc; jCprime++)
              for (int jSprime=0; jSprime<Ns; jSprime++)
                 for (int kCprime=0; kCprime<Nc; kCprime++)
                    for (int kSprime=0; kSprime<Ns; kSprime++)
                       for (int x=0; x<Vsnk; x++)
		         for (int x2=0; x2<Vsnk; x2++)
			     for (int t=0; t<Lt; t++)
                             if (std::abs(Bsingle[n][iCprime][iSprime][jCprime][jSprime][kCprime][kSprime][x][x2][t].real() -
					 Bsingle_r(t, x2, x, kSprime, kCprime, jSprime, jCprime, iSprime, iCprime, n)) >= 0.01)
			      {
				  std::cout << "Error: different computed values for Bsingle! Ref = " << Bsingle[n][iCprime][iSprime][jCprime][jSprime][kCprime][kSprime][x][x2][t].real() << " - Tiramisu = " << Bsingle_r(t, x2, x, kSprime, kCprime, jSprime, jCprime, iSprime, iCprime, n) << std::endl;
				std::cout << "Position: (" << n << ", " << iCprime << ", " << iSprime << ", " << jCprime << ", " << jSprime << ", " << kCprime << ", " << kSprime << ", " << x << ", " << x2 << ", " << t << ")" << std::endl;
				  exit(1);
			      }

    std::cout << "\n\n\033[1;32mSuccess: computed values are equal!\033[0m\n\n" << std::endl;

    return 0;
}
<commit_msg>dibaryon: add debugging to dibaryon wrapper<commit_after>#include "Halide.h"
#include <tiramisu/utils.h>
#include <cstdlib>
#include <iostream>
#include "benchmarks.h"

#include "baryon_wrapper.h"
#include "baryon_ref.cpp"

int main(int, char **)
{
    std::vector<std::chrono::duration<double,std::milli>> duration_vector_1;
    std::vector<std::chrono::duration<double,std::milli>> duration_vector_2;

    std::complex<double> Blocal[Nsrc][Nc][Ns][Nc][Ns][Nc][Ns][Vsnk][Lt];
    std::complex<double> Bsingle[Nsrc][Nc][Ns][Nc][Ns][Nc][Ns][Vsnk][Vsnk][Lt];
    std::complex<double> prop[Nq][Nc][Ns][Nc][Ns][Vsnk][Lt][Vsrc];
    int color_weights[Nw][Nq];
    int spin_weights[Nw][Nq];
    double weights[Nw];
    std::complex<double> psi[Nsrc][Vsrc];

    // Blocal
    // Blocal_r: tiramisu real part of Blocal.
    // Blocal_i: tiramisu imaginary part of Blocal.
    Halide::Buffer<double> Blocal_r(Lt, Vsnk, Ns, Nc, Ns, Nc, Ns, Nc, Nsrc, "Blocal_r");
    Halide::Buffer<double> Blocal_i(Lt, Vsnk, Ns, Nc, Ns, Nc, Ns, Nc, Nsrc, "Blocal_i");

    // prop
    Halide::Buffer<double> prop_r(Vsrc, Lt, Vsnk, Ns, Nc, Ns, Nc, Nq, "prop_r");
    Halide::Buffer<double> prop_i(Vsrc, Lt, Vsnk, Ns, Nc, Ns, Nc, Nq, "prop_i");

    // psi
    Halide::Buffer<double> psi_r(Vsrc, Nsrc, "psi_r");
    Halide::Buffer<double> psi_i(Vsrc, Nsrc, "psi_i");

    Halide::Buffer<int> color_weights_t(Nq, Nw, "color_weights_t");
    Halide::Buffer<int> spin_weights_t(Nq, Nw, "spin_weights_t");
    Halide::Buffer<double> weights_t(Nw, "weights_t");

    Halide::Buffer<double> Bsingle_r(Lt, Vsrc, Vsnk, Ns, Nc, Ns, Nc, Ns, Nc, Nsrc, "Bsingle_r");
    Halide::Buffer<double> Bsingle_i(Lt, Vsnk, Vsnk, Ns, Nc, Ns, Nc, Ns, Nc, Nsrc, "Bsingle_i");

    // Initialization
   for (int wnum=0; wnum<Nw; wnum++)
   {
       double v = rand()%10;
       weights[wnum] = v;
       weights_t(wnum) = v;
   }

   for (int n=0; n<Nsrc; n++)
     for (int y=0; y<Vsrc; y++)
     {
	double v = rand()%10;
	psi[n][y] = v + 2i ;
	psi_r(y, n) = v;
	psi_i(y, n) = 2;
     }

   for (int tri=0; tri<Nq; tri++)
       for (int iCprime=0; iCprime<Nc; iCprime++)
	  for (int iSprime=0; iSprime<Ns; iSprime++)
	     for (int jCprime=0; jCprime<Nc; jCprime++)
		for (int jSprime=0; jSprime<Ns; jSprime++)
                   for (int x=0; x<Vsnk; x++)
                      for (int t=0; t<Lt; t++)
		        for (int y=0; y<Vsrc; y++)
			{
			    double v = rand()%10;
			    prop[tri][iCprime][iSprime][jCprime][jSprime][x][t][y] = v + 5i;
			    prop_r(y, t, x, jSprime, jCprime, iSprime, iCprime, tri) = v;
			    prop_i(y, t, x, jSprime, jCprime, iSprime, iCprime, tri) = 5;
 		        }

   for (int wnum=0; wnum<Nw; wnum++)
	for (int tri=0; tri<Nq; tri++)
	{
		color_weights[wnum][tri] = 0; // tri
		color_weights_t(tri, wnum) = 0; //tri
		spin_weights[wnum][tri] = 0; //tri
		spin_weights_t(tri, wnum) = 0; //tri
	}

    for (int i = 0; i < NB_TESTS; i++)
    {
	    auto start2 = std::chrono::high_resolution_clock::now();

	    make_local_block(Blocal, prop, color_weights, spin_weights, weights, psi);
	    make_single_block(Bsingle, prop, color_weights, spin_weights, weights, psi);

	    auto end2 = std::chrono::high_resolution_clock::now();
	    std::chrono::duration<double,std::milli> duration2 = end2 - start2;
	    duration_vector_2.push_back(duration2);
    }

    for (int i = 0; i < NB_TESTS; i++)
    {
	    auto start1 = std::chrono::high_resolution_clock::now();

	    tiramisu_generated_code(Blocal_r.raw_buffer(),
				    Blocal_i.raw_buffer(),
				    prop_r.raw_buffer(),
				    prop_i.raw_buffer(),
				    weights_t.raw_buffer(),
				    psi_r.raw_buffer(),
				    psi_i.raw_buffer(),
				    color_weights_t.raw_buffer(),
				    spin_weights_t.raw_buffer(),
				    Bsingle_r.raw_buffer(),
				    Bsingle_i.raw_buffer());

	    auto end1 = std::chrono::high_resolution_clock::now();
	    std::chrono::duration<double,std::milli> duration1 = end1 - start1;
	    duration_vector_1.push_back(duration1);
    }

    print_time("performance_CPU.csv", "dibaryon", {"Ref", "Tiramisu"}, {median(duration_vector_2), median(duration_vector_1)});
    std::cout << "\nSpeedup = " << median(duration_vector_2)/median(duration_vector_1) << std::endl;

    for (int n=0; n<Nsrc; n++)
      for (int iCprime=0; iCprime<Nc; iCprime++)
        for (int iSprime=0; iSprime<Ns; iSprime++)
           for (int jCprime=0; jCprime<Nc; jCprime++)
              for (int jSprime=0; jSprime<Ns; jSprime++)
                 for (int kCprime=0; kCprime<Nc; kCprime++)
                    for (int kSprime=0; kSprime<Ns; kSprime++)
                       for (int x=0; x<Vsnk; x++)
                          for (int t=0; t<Lt; t++)
			     std::cout << Blocal[n][iCprime][iSprime][jCprime][jSprime][kCprime][kSprime][x][t].real() << "  ///  " << Blocal_r(t, x, kSprime, kCprime, jSprime, jCprime, iSprime, iCprime, n) << std::endl;

    // Compare outputs.
    for (int n=0; n<Nsrc; n++)
      for (int iCprime=0; iCprime<Nc; iCprime++)
        for (int iSprime=0; iSprime<Ns; iSprime++)
           for (int jCprime=0; jCprime<Nc; jCprime++)
              for (int jSprime=0; jSprime<Ns; jSprime++)
                 for (int kCprime=0; kCprime<Nc; kCprime++)
                    for (int kSprime=0; kSprime<Ns; kSprime++)
                       for (int x=0; x<Vsnk; x++)
                          for (int t=0; t<Lt; t++)
                              if (std::abs(Blocal[n][iCprime][iSprime][jCprime][jSprime][kCprime][kSprime][x][t].real() -
						Blocal_r(t, x, kSprime, kCprime, jSprime, jCprime, iSprime, iCprime, n)) >= 0.01)
			      {
				  std::cout << "Error: different computed values for Blocal! Ref = " << Blocal[n][iCprime][iSprime][jCprime][jSprime][kCprime][kSprime][x][t].real() << " - Tiramisu = " << Blocal_r(t, x, kSprime, kCprime, jSprime, jCprime, iSprime, iCprime, n) << std::endl;
				  exit(1);
			      }

    for (int n=0; n<Nsrc; n++)
      for (int iCprime=0; iCprime<Nc; iCprime++)
        for (int iSprime=0; iSprime<Ns; iSprime++)
           for (int jCprime=0; jCprime<Nc; jCprime++)
              for (int jSprime=0; jSprime<Ns; jSprime++)
                 for (int kCprime=0; kCprime<Nc; kCprime++)
                    for (int kSprime=0; kSprime<Ns; kSprime++)
                       for (int x=0; x<Vsnk; x++)
		         for (int x2=0; x2<Vsnk; x2++)
			     for (int t=0; t<Lt; t++)
                             if (std::abs(Bsingle[n][iCprime][iSprime][jCprime][jSprime][kCprime][kSprime][x][x2][t].real() -
					 Bsingle_r(t, x2, x, kSprime, kCprime, jSprime, jCprime, iSprime, iCprime, n)) >= 0.01)
			      {
				  std::cout << "Error: different computed values for Bsingle! Ref = " << Bsingle[n][iCprime][iSprime][jCprime][jSprime][kCprime][kSprime][x][x2][t].real() << " - Tiramisu = " << Bsingle_r(t, x2, x, kSprime, kCprime, jSprime, jCprime, iSprime, iCprime, n) << std::endl;
				std::cout << "Position: (" << n << ", " << iCprime << ", " << iSprime << ", " << jCprime << ", " << jSprime << ", " << kCprime << ", " << kSprime << ", " << x << ", " << x2 << ", " << t << ")" << std::endl;
				  exit(1);
			      }

    std::cout << "\n\n\033[1;32mSuccess: computed values are equal!\033[0m\n\n" << std::endl;

    return 0;
}
<|endoftext|>


<commit_before>/*
 * eos - A 3D Morphable Model fitting library written in modern C++11/14.
 *
 * File: include/eos/render/utils.hpp
 *
 * Copyright 2014, 2015 Patrik Huber
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#pragma once

#ifndef RENDER_UTILS_HPP_
#define RENDER_UTILS_HPP_

#include "glm/vec2.hpp"

namespace eos {
namespace render {

/**
 * Transforms a point from clip space ([-1, 1] x [-1, 1]) to
 * image (screen) coordinates, i.e. the window transform.
 * Note that the y-coordinate is flipped because the image origin
 * is top-left while in clip space top is +1 and bottom is -1.
 * No z-division is performed.
 * Note: It should rather be called from NDC to screen space?
 *
 * Exactly conforming to the OpenGL viewport transform, except that
 * we flip y at the end.
 * Qt: Origin top-left. OpenGL: bottom-left. OCV: top-left.
 *
 * @param[in] clip_coordinates A point in clip coordinates.
 * @param[in] screen_width Width of the screen or window.
 * @param[in] screen_height Height of the screen or window.
 * @return A vector with x and y coordinates transformed to screen space.
 */
inline glm::vec2 clip_to_screen_space(const glm::vec2& clip_coordinates, int screen_width, int screen_height)
{
    // Window transform:
    const float x_ss = (clip_coordinates[0] + 1.0f) * (screen_width / 2.0f);
    const float y_ss =
        screen_height - (clip_coordinates[1] + 1.0f) *
                            (screen_height / 2.0f); // also flip y; Qt: Origin top-left. OpenGL: bottom-left.
    return glm::vec2(x_ss, y_ss);
    /* Note: What we do here is equivalent to
       x_w = (x *  vW/2) + vW/2;
       However, Shirley says we should do:
       x_w = (x *  vW/2) + (vW-1)/2;
       (analogous for y)
       Todo: Check the consequences.
    */
};

/**
 * Transforms a point from image (screen) coordinates to
 * clip space ([-1, 1] x [-1, 1]).
 * Note that the y-coordinate is flipped because the image origin
 * is top-left while in clip space top is +1 and bottom is -1.
 *
 * @param[in] screen_coordinates A point in screen coordinates.
 * @param[in] screen_width Width of the screen or window.
 * @param[in] screen_height Height of the screen or window.
 * @return A vector with x and y coordinates transformed to clip space.
 */
/*inline cv::Vec2f screen_to_clip_space(const cv::Vec2f& screen_coordinates, int screen_width, int screen_height)
{
    const float x_cs = screen_coordinates[0] / (screen_width / 2.0f) - 1.0f;
    float y_cs = screen_coordinates[1] / (screen_height / 2.0f) - 1.0f;
    y_cs *= -1.0f;
    return cv::Vec2f(x_cs, y_cs);
};*/

template <typename T, glm::precision P = glm::defaultp>
glm::tvec2<T, P> clip_to_screen_space(const T clip_coord_x, const T clip_coord_y, int screen_width,
                                      int screen_height)
{
    // Todo: See/copy notes from utils.hpp/clip_to_screen_space.
    const T x_ss = (clip_coord_x + T(1)) * (screen_width / 2.0);
    const T y_ss =
        screen_height - (clip_coord_y + T(1)) *
                            (screen_height / 2.0); // also flip y; Qt: Origin top-left. OpenGL: bottom-left.
    return glm::tvec2<T, P>(x_ss, y_ss);
};

} /* namespace render */
} /* namespace eos */

#endif /* RENDER_UTILS_HPP_ */
<commit_msg>Prefixed header guard of render/utils.hpp with EOS_<commit_after>/*
 * eos - A 3D Morphable Model fitting library written in modern C++11/14.
 *
 * File: include/eos/render/utils.hpp
 *
 * Copyright 2014, 2015 Patrik Huber
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#pragma once

#ifndef EOS_RENDER_UTILS_HPP
#define EOS_RENDER_UTILS_HPP

#include "glm/vec2.hpp"

namespace eos {
namespace render {

/**
 * Transforms a point from clip space ([-1, 1] x [-1, 1]) to
 * image (screen) coordinates, i.e. the window transform.
 * Note that the y-coordinate is flipped because the image origin
 * is top-left while in clip space top is +1 and bottom is -1.
 * No z-division is performed.
 * Note: It should rather be called from NDC to screen space?
 *
 * Exactly conforming to the OpenGL viewport transform, except that
 * we flip y at the end.
 * Qt: Origin top-left. OpenGL: bottom-left. OCV: top-left.
 *
 * @param[in] clip_coordinates A point in clip coordinates.
 * @param[in] screen_width Width of the screen or window.
 * @param[in] screen_height Height of the screen or window.
 * @return A vector with x and y coordinates transformed to screen space.
 */
inline glm::vec2 clip_to_screen_space(const glm::vec2& clip_coordinates, int screen_width, int screen_height)
{
    // Window transform:
    const float x_ss = (clip_coordinates[0] + 1.0f) * (screen_width / 2.0f);
    const float y_ss =
        screen_height - (clip_coordinates[1] + 1.0f) *
                            (screen_height / 2.0f); // also flip y; Qt: Origin top-left. OpenGL: bottom-left.
    return glm::vec2(x_ss, y_ss);
    /* Note: What we do here is equivalent to
       x_w = (x *  vW/2) + vW/2;
       However, Shirley says we should do:
       x_w = (x *  vW/2) + (vW-1)/2;
       (analogous for y)
       Todo: Check the consequences.
    */
};

/**
 * Transforms a point from image (screen) coordinates to
 * clip space ([-1, 1] x [-1, 1]).
 * Note that the y-coordinate is flipped because the image origin
 * is top-left while in clip space top is +1 and bottom is -1.
 *
 * @param[in] screen_coordinates A point in screen coordinates.
 * @param[in] screen_width Width of the screen or window.
 * @param[in] screen_height Height of the screen or window.
 * @return A vector with x and y coordinates transformed to clip space.
 */
/*inline cv::Vec2f screen_to_clip_space(const cv::Vec2f& screen_coordinates, int screen_width, int screen_height)
{
    const float x_cs = screen_coordinates[0] / (screen_width / 2.0f) - 1.0f;
    float y_cs = screen_coordinates[1] / (screen_height / 2.0f) - 1.0f;
    y_cs *= -1.0f;
    return cv::Vec2f(x_cs, y_cs);
};*/

template <typename T, glm::precision P = glm::defaultp>
glm::tvec2<T, P> clip_to_screen_space(const T clip_coord_x, const T clip_coord_y, int screen_width,
                                      int screen_height)
{
    // Todo: See/copy notes from utils.hpp/clip_to_screen_space.
    const T x_ss = (clip_coord_x + T(1)) * (screen_width / 2.0);
    const T y_ss =
        screen_height - (clip_coord_y + T(1)) *
                            (screen_height / 2.0); // also flip y; Qt: Origin top-left. OpenGL: bottom-left.
    return glm::tvec2<T, P>(x_ss, y_ss);
};

} /* namespace render */
} /* namespace eos */

#endif /* EOS_RENDER_UTILS_HPP */
<|endoftext|>


<commit_before>/*
 This file is part of SWGANH. For more information, visit http://swganh.com

 Copyright (c) 2006 - 2011 The SWG:ANH Team

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#include "anh/network/soe/outgoing_start_filter.h"
#include "anh/network/soe/session.h"
#include "anh/network/soe/outgoing_packet.h"

using namespace anh::network::soe;
using namespace std;
using namespace tbb;

OutgoingStartFilter::OutgoingStartFilter(list<shared_ptr<OutgoingPacket>>& message_queue)
	: message_queue_(message_queue) {}

shared_ptr<OutgoingPacket> OutgoingStartFilter::operator()(flow_control& fc) const {
	// Cut the pipeline loop if we run out of messages.
	if(message_queue_.empty())
		return nullptr;

	auto packet = message_queue_.front();
	message_queue_.pop_front();

	// If we are no longer connected, skip.
	if(packet->session()->connected() == false)
	{
		return nullptr;
	}

	return packet;
}
<commit_msg>Cleaned up for use with the typed pipeline<commit_after>/*
 This file is part of SWGANH. For more information, visit http://swganh.com

 Copyright (c) 2006 - 2011 The SWG:ANH Team

 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#include "anh/network/soe/outgoing_start_filter.h"
#include "anh/network/soe/session.h"
#include "anh/network/soe/outgoing_packet.h"

using namespace anh::network::soe;
using namespace std;
using namespace tbb;

OutgoingStartFilter::OutgoingStartFilter(list<shared_ptr<OutgoingPacket>>& message_queue)
	: message_queue_(message_queue) {}

shared_ptr<OutgoingPacket> OutgoingStartFilter::operator()(flow_control& fc) const {
    shared_ptr<OutgoingPacket> packet;

    do {
        // No more packets to process.
        if(message_queue_.empty()) {
            fc.stop();
            return nullptr;
        }

        packet = message_queue_.front();
        message_queue_.pop_front();

        // Loop until we have a packet with a valid connection.
    } while(packet->session()->connected() == false);

	return packet;
}
<|endoftext|>


<commit_before>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * helloBPWriterXML_nompi.cpp: sequential non-mpi version of helloBPWriterXML
 *
 *  Created on: Feb 16, 2017
 *      Author: William F Godoy godoywf@ornl.gov
 */

#include <ios>      //std::ios_base::failure
#include <iostream> //std::cout
#include <mpi.h>
#include <stdexcept> //std::invalid_argument std::exception
#include <vector>

#include <adios2.h>

int main(int argc, char *argv[])
{
    /** Application variable */
    std::vector<float> myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    const std::size_t Nx = myFloats.size();

    try
    {
        /** ADIOS class factory of IO class objects, DebugON is recommended */
        adios2::ADIOS adios("helloBPWriter.xml", adios2::DebugON);

        /*** IO class object: settings and factory of Settings: Variables,
         * Parameters, Transports, and Execution: Engines */
        adios2::IO &bpIO = adios.DeclareIO("BPFile_N2N");

        /** global array : name, { shape (total) }, { start (local) }, { count
         * (local) }, all are constant dimensions */
        adios2::Variable<float> &bpFloats = bpIO.DefineVariable<float>(
            "bpFloats", {}, {}, {Nx}, adios2::ConstantDims);

        /** Engine derived class, spawned to start IO operations */
        auto bpWriter = bpIO.Open("myVector.bp", adios2::OpenMode::Write);

        if (!bpWriter)
        {
            throw std::ios_base::failure(
                "ERROR: bpWriter not created at Open\n");
        }

        /** Write variable for buffering */
        bpWriter->Write<float>(bpFloats, myFloats.data());

        /** Create bp file, engine becomes unreachable after this*/
        bpWriter->Close();
    }
    catch (std::invalid_argument &e)
    {
        std::cout << "Invalid argument exception, STOPPING PROGRAM\n";
        std::cout << e.what() << "\n";
    }
    catch (std::ios_base::failure &e)
    {
        std::cout << "IO System base failure exception, STOPPING PROGRAM\n";
        std::cout << e.what() << "\n";
    }
    catch (std::exception &e)
    {
        std::cout << "Exception, STOPPING PROGRAM from rank\n";
        std::cout << e.what() << "\n";
    }

    return 0;
}
<commit_msg>Remove leftover unused mpi include.<commit_after>/*
 * Distributed under the OSI-approved Apache License, Version 2.0.  See
 * accompanying file Copyright.txt for details.
 *
 * helloBPWriterXML_nompi.cpp: sequential non-mpi version of helloBPWriterXML
 *
 *  Created on: Feb 16, 2017
 *      Author: William F Godoy godoywf@ornl.gov
 */

#include <ios>      //std::ios_base::failure
#include <iostream> //std::cout
#include <stdexcept> //std::invalid_argument std::exception
#include <vector>

#include <adios2.h>

int main(int argc, char *argv[])
{
    /** Application variable */
    std::vector<float> myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    const std::size_t Nx = myFloats.size();

    try
    {
        /** ADIOS class factory of IO class objects, DebugON is recommended */
        adios2::ADIOS adios("helloBPWriter.xml", adios2::DebugON);

        /*** IO class object: settings and factory of Settings: Variables,
         * Parameters, Transports, and Execution: Engines */
        adios2::IO &bpIO = adios.DeclareIO("BPFile_N2N");

        /** global array : name, { shape (total) }, { start (local) }, { count
         * (local) }, all are constant dimensions */
        adios2::Variable<float> &bpFloats = bpIO.DefineVariable<float>(
            "bpFloats", {}, {}, {Nx}, adios2::ConstantDims);

        /** Engine derived class, spawned to start IO operations */
        auto bpWriter = bpIO.Open("myVector.bp", adios2::OpenMode::Write);

        if (!bpWriter)
        {
            throw std::ios_base::failure(
                "ERROR: bpWriter not created at Open\n");
        }

        /** Write variable for buffering */
        bpWriter->Write<float>(bpFloats, myFloats.data());

        /** Create bp file, engine becomes unreachable after this*/
        bpWriter->Close();
    }
    catch (std::invalid_argument &e)
    {
        std::cout << "Invalid argument exception, STOPPING PROGRAM\n";
        std::cout << e.what() << "\n";
    }
    catch (std::ios_base::failure &e)
    {
        std::cout << "IO System base failure exception, STOPPING PROGRAM\n";
        std::cout << e.what() << "\n";
    }
    catch (std::exception &e)
    {
        std::cout << "Exception, STOPPING PROGRAM from rank\n";
        std::cout << e.what() << "\n";
    }

    return 0;
}
<|endoftext|>


<commit_before><commit_msg>flipped around ifdef for readability<commit_after><|endoftext|>


<commit_before>// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "dap/network.h"
#include "dap/io.h"

#include "chan.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include <chrono>
#include <thread>

namespace {

bool write(const std::shared_ptr<dap::Writer>& w, const std::string& s) {
  return w->write(s.data(), s.size()) && w->write("\0", 1);
}

std::string read(const std::shared_ptr<dap::Reader>& r) {
  char c;
  std::string s;
  while (r->read(&c, sizeof(c)) > 0) {
    if (c == '\0') {
      return s;
    }
    s += c;
  }
  return r->isOpen() ? "<read failed>" : "<stream closed>";
}

}  // anonymous namespace

TEST(Network, ClientServer) {
  const int port = 19021;
  dap::Chan<bool> done;
  auto server = dap::net::Server::create();
  if (!server->start(port,
                     [&](const std::shared_ptr<dap::ReaderWriter>& rw) {
                       ASSERT_EQ(read(rw), "client to server");
                       ASSERT_TRUE(write(rw, "server to client"));
                       done.put(true);
                     },
                     [&](const char* err) {
                       FAIL() << "Server error: " << err;
                     })) {
    FAIL() << "Couldn't start server";
    return;
  }

  for (int i = 0; i < 10; i++) {
    if (auto client = dap::net::connect("localhost", port)) {
      ASSERT_TRUE(write(client, "client to server"));
      ASSERT_EQ(read(client), "server to client");
      break;
    }
    std::this_thread::sleep_for(std::chrono::seconds(1));
  }

  done.take();
  server.reset();
}
<commit_msg>Format all source files<commit_after>// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "dap/network.h"
#include "dap/io.h"

#include "chan.h"

#include "gmock/gmock.h"
#include "gtest/gtest.h"

#include <chrono>
#include <thread>

namespace {

bool write(const std::shared_ptr<dap::Writer>& w, const std::string& s) {
  return w->write(s.data(), s.size()) && w->write("\0", 1);
}

std::string read(const std::shared_ptr<dap::Reader>& r) {
  char c;
  std::string s;
  while (r->read(&c, sizeof(c)) > 0) {
    if (c == '\0') {
      return s;
    }
    s += c;
  }
  return r->isOpen() ? "<read failed>" : "<stream closed>";
}

}  // anonymous namespace

TEST(Network, ClientServer) {
  const int port = 19021;
  dap::Chan<bool> done;
  auto server = dap::net::Server::create();
  if (!server->start(
          port,
          [&](const std::shared_ptr<dap::ReaderWriter>& rw) {
            ASSERT_EQ(read(rw), "client to server");
            ASSERT_TRUE(write(rw, "server to client"));
            done.put(true);
          },
          [&](const char* err) { FAIL() << "Server error: " << err; })) {
    FAIL() << "Couldn't start server";
    return;
  }

  for (int i = 0; i < 10; i++) {
    if (auto client = dap::net::connect("localhost", port)) {
      ASSERT_TRUE(write(client, "client to server"));
      ASSERT_EQ(read(client), "server to client");
      break;
    }
    std::this_thread::sleep_for(std::chrono::seconds(1));
  }

  done.take();
  server.reset();
}
<|endoftext|>