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

#include "compiler.hpp"
#include <shaderc/shaderc.hpp>
#include <path.hpp>
#include "util.hpp"
#include "filesystem.hpp"

#include "spirv-tools/libspirv.hpp"

using namespace std;

namespace Granite
{

Stage GLSLCompiler::stage_from_path(const std::string &path)
{
	auto ext = Path::ext(path);
	if (ext == "vert")
		return Stage::Vertex;
	else if (ext == "tesc")
		return Stage::TessControl;
	else if (ext == "tese")
		return Stage::TessEvaluation;
	else if (ext == "geom")
		return Stage::Geometry;
	else if (ext == "frag")
		return Stage::Fragment;
	else if (ext == "comp")
		return Stage::Compute;
	else
		return Stage::Unknown;
}

bool GLSLCompiler::set_source_from_file(const string &path)
{
	if (!Global::filesystem()->read_file_to_string(path, source))
	{
		LOGE("Failed to load shader: %s\n", path.c_str());
		return false;
	}

	source_path = path;
	stage = stage_from_path(path);
	return stage != Stage::Unknown;
}

void GLSLCompiler::set_include_directories(const std::vector<std::string> *include_directories_)
{
	include_directories = include_directories_;
}

bool GLSLCompiler::find_include_path(const string &source_path_, const string &include_path,
                                     string &included_path, string &included_source)
{
	auto relpath = Path::relpath(source_path_, include_path);
	if (Global::filesystem()->read_file_to_string(relpath, included_source))
	{
		included_path = relpath;
		return true;
	}

	if (include_directories)
	{
		for (auto &include_dir : *include_directories)
		{
			auto path = Path::join(include_dir, include_path);
			if (Global::filesystem()->read_file_to_string(path, included_source))
			{
				included_path = path;
				return true;
			}
		}
	}

	return false;
}

bool GLSLCompiler::parse_variants(const string &source_, const string &path)
{
	auto lines = Util::split(source_, "\n");

	unsigned line_index = 0;
	for (auto &line : lines)
	{
		if (line.find("#include \"") == 0)
		{
			auto include_path = line.substr(10);
			if (!include_path.empty() && include_path.back() == '"')
				include_path.pop_back();

			string included_source;
			if (!find_include_path(path, include_path, include_path, included_source))
			{
				LOGE("Failed to include GLSL file: %s\n", include_path.c_str());
				return false;
			}

			preprocessed_source += Util::join("#line ", 1, " \"", include_path, "\"\n");
			if (!parse_variants(included_source, include_path))
				return false;
			preprocessed_source += Util::join("#line ", line_index + 2, " \"", path, "\"\n");

			dependencies.insert(include_path);
		}
		else if (line.find("#pragma optimize off") == 0)
		{
			optimization = Optimization::ForceOff;
			preprocessed_source += "// #pragma optimize off";
			preprocessed_source += '\n';
		}
		else if (line.find("#pragma optimize on") == 0)
		{
			optimization = Optimization::ForceOn;
			preprocessed_source += "// #pragma optimize on";
			preprocessed_source += '\n';
		}
		else
		{
			preprocessed_source += line;
			preprocessed_source += '\n';

			auto first_non_space = line.find_first_not_of(' ');
			if (first_non_space != string::npos && line[first_non_space] == '#')
			{
				auto keywords = Util::split(line.substr(first_non_space + 1), " ");
				if (keywords.size() == 1)
				{
					auto &word = keywords.front();
					if (word == "endif")
						preprocessed_source += Util::join("#line ", line_index + 2, " \"", path, "\"\n");
				}
			}
		}

		line_index++;
	}
	return true;
}

bool GLSLCompiler::preprocess()
{
	preprocessed_source.clear();
	return parse_variants(source, source_path);
}

vector<uint32_t> GLSLCompiler::compile(const vector<pair<string, int>> *defines)
{
	shaderc::Compiler compiler;
	shaderc::CompileOptions options;
	if (preprocessed_source.empty())
	{
		LOGE("Need to preprocess source first.\n");
		return {};
	}

	if (defines)
		for (auto &define : *defines)
			options.AddMacroDefinition(define.first, to_string(define.second));

#if GRANITE_COMPILER_OPTIMIZE
	if (optimization != Optimization::ForceOff)
		options.SetOptimizationLevel(shaderc_optimization_level_performance);
	else
	{
		options.SetOptimizationLevel(shaderc_optimization_level_zero);
		options.SetGenerateDebugInfo();
	}
#else
	options.SetOptimizationLevel(shaderc_optimization_level_zero);
	options.SetGenerateDebugInfo();
#endif

	options.SetTargetEnvironment(shaderc_target_env_vulkan,
	                             target == Target::Vulkan11 ?
	                             shaderc_env_version_vulkan_1_1 :
	                             shaderc_env_version_vulkan_1_0);

	options.SetSourceLanguage(shaderc_source_language_glsl);

	shaderc_shader_kind kind;
	switch (stage)
	{
	case Stage::Vertex:
		kind = shaderc_glsl_vertex_shader;
		break;

	case Stage::TessControl:
		kind = shaderc_glsl_tess_control_shader;
		break;

	case Stage::TessEvaluation:
		kind = shaderc_glsl_tess_evaluation_shader;
		break;

	case Stage::Geometry:
		kind = shaderc_glsl_geometry_shader;
		break;

	case Stage::Fragment:
		kind = shaderc_glsl_fragment_shader;
		break;

	case Stage::Compute:
		kind = shaderc_glsl_compute_shader;
		break;

	default:
		return {};
	}
	shaderc::SpvCompilationResult result = compiler.CompileGlslToSpv(preprocessed_source, kind, source_path.c_str(), options);

	error_message.clear();
	if (result.GetCompilationStatus() != shaderc_compilation_status_success)
	{
		error_message = result.GetErrorMessage();
		return {};
	}

	vector<uint32_t> compiled_spirv(result.cbegin(), result.cend());

	spvtools::SpirvTools core(target == Target::Vulkan11 ? SPV_ENV_VULKAN_1_1 : SPV_ENV_VULKAN_1_0);

	core.SetMessageConsumer([this](spv_message_level_t, const char *, const spv_position_t&, const char *message) {
		error_message = message;
	});

	spvtools::ValidatorOptions opts;
	opts.SetScalarBlockLayout(true);
	if (!core.Validate(compiled_spirv.data(), compiled_spirv.size(), opts))
	{
		LOGE("Failed to validate SPIR-V.\n");
		return {};
	}

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

#include "compiler.hpp"
#include <shaderc/shaderc.hpp>
#include <path.hpp>
#include "util.hpp"
#include "filesystem.hpp"

#include "spirv-tools/libspirv.hpp"

using namespace std;

namespace Granite
{

Stage GLSLCompiler::stage_from_path(const std::string &path)
{
	auto ext = Path::ext(path);
	if (ext == "vert")
		return Stage::Vertex;
	else if (ext == "tesc")
		return Stage::TessControl;
	else if (ext == "tese")
		return Stage::TessEvaluation;
	else if (ext == "geom")
		return Stage::Geometry;
	else if (ext == "frag")
		return Stage::Fragment;
	else if (ext == "comp")
		return Stage::Compute;
	else
		return Stage::Unknown;
}

bool GLSLCompiler::set_source_from_file(const string &path)
{
	if (!Global::filesystem()->read_file_to_string(path, source))
	{
		LOGE("Failed to load shader: %s\n", path.c_str());
		return false;
	}

	source_path = path;
	stage = stage_from_path(path);
	return stage != Stage::Unknown;
}

void GLSLCompiler::set_include_directories(const std::vector<std::string> *include_directories_)
{
	include_directories = include_directories_;
}

bool GLSLCompiler::find_include_path(const string &source_path_, const string &include_path,
                                     string &included_path, string &included_source)
{
	auto relpath = Path::relpath(source_path_, include_path);
	if (Global::filesystem()->read_file_to_string(relpath, included_source))
	{
		included_path = relpath;
		return true;
	}

	if (include_directories)
	{
		for (auto &include_dir : *include_directories)
		{
			auto path = Path::join(include_dir, include_path);
			if (Global::filesystem()->read_file_to_string(path, included_source))
			{
				included_path = path;
				return true;
			}
		}
	}

	return false;
}

bool GLSLCompiler::parse_variants(const string &source_, const string &path)
{
	auto lines = Util::split(source_, "\n");

	unsigned line_index = 0;
	for (auto &line : lines)
	{
		if (line.find("#include \"") == 0)
		{
			auto include_path = line.substr(10);
			if (!include_path.empty() && include_path.back() == '"')
				include_path.pop_back();

			string included_source;
			if (!find_include_path(path, include_path, include_path, included_source))
			{
				LOGE("Failed to include GLSL file: %s\n", include_path.c_str());
				return false;
			}

			preprocessed_source += Util::join("#line ", 1, " \"", include_path, "\"\n");
			if (!parse_variants(included_source, include_path))
				return false;
			preprocessed_source += Util::join("#line ", line_index + 2, " \"", path, "\"\n");

			dependencies.insert(include_path);
		}
		else if (line.find("#pragma optimize off") == 0)
		{
			optimization = Optimization::ForceOff;
			preprocessed_source += "// #pragma optimize off";
			preprocessed_source += '\n';
		}
		else if (line.find("#pragma optimize on") == 0)
		{
			optimization = Optimization::ForceOn;
			preprocessed_source += "// #pragma optimize on";
			preprocessed_source += '\n';
		}
		else
		{
			preprocessed_source += line;
			preprocessed_source += '\n';

			auto first_non_space = line.find_first_not_of(' ');
			if (first_non_space != string::npos && line[first_non_space] == '#')
			{
				auto keywords = Util::split(line.substr(first_non_space + 1), " ");
				if (keywords.size() == 1)
				{
					auto &word = keywords.front();
					if (word == "endif")
						preprocessed_source += Util::join("#line ", line_index + 2, " \"", path, "\"\n");
				}
			}
		}

		line_index++;
	}
	return true;
}

bool GLSLCompiler::preprocess()
{
	preprocessed_source.clear();
	return parse_variants(source, source_path);
}

vector<uint32_t> GLSLCompiler::compile(const vector<pair<string, int>> *defines)
{
	shaderc::Compiler compiler;
	shaderc::CompileOptions options;
	if (preprocessed_source.empty())
	{
		LOGE("Need to preprocess source first.\n");
		return {};
	}

	if (defines)
		for (auto &define : *defines)
			options.AddMacroDefinition(define.first, to_string(define.second));

#if GRANITE_COMPILER_OPTIMIZE
	if (optimization != Optimization::ForceOff)
		options.SetOptimizationLevel(shaderc_optimization_level_performance);
	else
		options.SetOptimizationLevel(shaderc_optimization_level_zero);
#else
	options.SetOptimizationLevel(shaderc_optimization_level_zero);
#endif
	// Need this for some reflection purposes with immutable samplers.
	options.SetGenerateDebugInfo();

	options.SetTargetEnvironment(shaderc_target_env_vulkan,
	                             target == Target::Vulkan11 ?
	                             shaderc_env_version_vulkan_1_1 :
	                             shaderc_env_version_vulkan_1_0);

	options.SetSourceLanguage(shaderc_source_language_glsl);

	shaderc_shader_kind kind;
	switch (stage)
	{
	case Stage::Vertex:
		kind = shaderc_glsl_vertex_shader;
		break;

	case Stage::TessControl:
		kind = shaderc_glsl_tess_control_shader;
		break;

	case Stage::TessEvaluation:
		kind = shaderc_glsl_tess_evaluation_shader;
		break;

	case Stage::Geometry:
		kind = shaderc_glsl_geometry_shader;
		break;

	case Stage::Fragment:
		kind = shaderc_glsl_fragment_shader;
		break;

	case Stage::Compute:
		kind = shaderc_glsl_compute_shader;
		break;

	default:
		return {};
	}
	shaderc::SpvCompilationResult result = compiler.CompileGlslToSpv(preprocessed_source, kind, source_path.c_str(), options);

	error_message.clear();
	if (result.GetCompilationStatus() != shaderc_compilation_status_success)
	{
		error_message = result.GetErrorMessage();
		return {};
	}

	vector<uint32_t> compiled_spirv(result.cbegin(), result.cend());

	spvtools::SpirvTools core(target == Target::Vulkan11 ? SPV_ENV_VULKAN_1_1 : SPV_ENV_VULKAN_1_0);

	core.SetMessageConsumer([this](spv_message_level_t, const char *, const spv_position_t&, const char *message) {
		error_message = message;
	});

	spvtools::ValidatorOptions opts;
	opts.SetScalarBlockLayout(true);
	if (!core.Validate(compiled_spirv.data(), compiled_spirv.size(), opts))
	{
		LOGE("Failed to validate SPIR-V.\n");
		return {};
	}

	return compiled_spirv;
}
}
<|endoftext|>


<commit_before>#include "itkImageFileReader.h"

int main(int ac, char** av)
{
  if(ac < 2)
    {
    std::cerr << "Usage: " << av[0] << " Image\n";
    return EXIT_FAILURE;
    }

  typedef itk::Image<unsigned char, 2> myImage;
  itk::ImageFileReader<myImage>::Pointer reader
                                  = itk::ImageFileReader<myImage>::New();

  reader->DebugOn();
  reader->SetFileName(av[1]);

  try
    {
    reader->Update();
    }
  catch (itk::ImageFileReaderException& e)
    {
    std::cerr << "exception in file reader \n"  << e.GetDescription();
    return EXIT_FAILURE;
    }

  myImage::Pointer image = reader->GetOutput();

  image->Print(std::cout );

  myImage::RegionType region = image->GetLargestPossibleRegion();
  std::cout << "region " << region;

  unsigned char* data = image->GetPixelContainer()->GetBufferPointer();

  unsigned long numberOfPixels = region.GetNumberOfPixels();
  for(unsigned int i=0; i < numberOfPixels; i++ )
    {
      std::cout << i << " : " << *data++ << std::endl;
    }

  return EXIT_SUCCESS;
}
<commit_msg>ENH: Test is done with a 3D image<commit_after>#include "itkImageFileReader.h"

int main(int ac, char** av)
{
  if(ac < 2)
    {
    std::cerr << "Usage: " << av[0] << " Image\n";
    return EXIT_FAILURE;
    }

  typedef itk::Image<unsigned char, 3> myImage;
  itk::ImageFileReader<myImage>::Pointer reader
                                  = itk::ImageFileReader<myImage>::New();

  reader->DebugOn();
  reader->SetFileName(av[1]);

  try
    {
    reader->Update();
    }
  catch (itk::ImageFileReaderException& e)
    {
    std::cerr << "exception in file reader \n"  << e.GetDescription();
    return EXIT_FAILURE;
    }

  myImage::Pointer image = reader->GetOutput();

  image->Print(std::cout );

  myImage::RegionType region = image->GetLargestPossibleRegion();
  std::cout << "region " << region;

  unsigned char* data = image->GetPixelContainer()->GetBufferPointer();

  unsigned long numberOfPixels = region.GetNumberOfPixels();
  for(unsigned int i=0; i < numberOfPixels; i++ )
    {
      std::cout << i << " : " << *data++ << std::endl;
    }

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// CORE TODO
// [ ] `net_plugin`: block broadcast decoupled from controller
// [ ] `producer_plugin`: control block broadcast
// [ ] `producer_plugin`: send committed blocks to BlockVault.
// [ ] `producer_plugin`: send accepted blocks to BlockVault.
// [ ] `producer_plugin`: store snapshots in BlockVault driven by RPC.
//
// [X] BlockVault "propose_constructed_block" interface.
// [ ] BlockVault "propose_constructed_block" implementation.
// [ ] BlockVault "propose_constructed_block" unit tests with mocked connection.
//
// [X] BlockVault "append_external_block" interface.
// [ ] BlockVault "append_external_block" implementation.
// [ ] BlockVault "append_external_block" unit tests with mocked connection.
//
// [X] BlockVault "propose_snapshot" interface.
// [ ] BlockVault "propose_snapshot" implementation.
// [ ] BlockVault "propose_snapshot" unit tests with mocked connection.
//
// [ ] `net_plugin`: disable `net_plugin` syncing when BlockVault is configured.
// [ ] `chain_plugin`: `chain_plugin` integration.
// [ ] BlockVault "sync_for_construction" interface.
// [ ] BlockVault "sync_for_construction" implementation.
// [ ] BlockVault "sync_for_construction" unit tests with mocked connection and consumer.
// [ ] BlockVault "sync_for_construction" sync controller with BlockVault when configured implementation.
// [ ] BlockVault "sync_for_construction" unit tests with mocked provider.

// LONG-TERM TOOD
// Rid all `using namespace` for verbosity-sake (or perhaps not).
// After interface is implemented double-check documentation comments.
// Make sure to delete all trailing whitespace in all touched files.
// Merge blockvault changes into my branch.
// Merge develop into blockvault.
// Submit PR to blockvault branch.

// SHORT-TERM TODO
// Finish plugin init test.
// Finish rest of impl.

#pragma once

#include <optional> // std::optional
#include <utility> // std::pair
#include <appbase/application.hpp> // appbase::plugin
#include "blockvault.hpp"

namespace eosio {

using namespace appbase;
using namespace eosio;
using namespace eosio::chain;

using block_num = uint32_t;

class blockvault_client_plugin_impl;

/// Documentation for blockvault_client_plugin.
///
/// blockvault_client_plugin is a proposed clustered component in an EOSIO
/// network architecture which provides a replicated durable storage with strong
/// consistency guarantees for all the input required by a redundant cluster of
/// nodeos nodes to achieve the guarantees:
///
/// Guarantee against double-production of blocks
/// Guarantee against finality violation
/// Guarantee of liveness (ability to make progress as a blockchain)
class blockvault_client_plugin : public appbase::plugin<blockvault_client_plugin> {
public:
   blockvault_client_plugin();
   virtual ~blockvault_client_plugin();

   APPBASE_PLUGIN_REQUIRES()
   virtual void set_program_options(options_description&, options_description& cfg) final;

   void plugin_initialize(const variables_map& options);
   void plugin_startup();
   void plugin_shutdown();

   eosio::blockvault::block_vault_interface* get();

 private:
   std::unique_ptr<class blockvault_client_plugin_impl> my;
};

}
<commit_msg>made get member function static<commit_after>// CORE TODO
// [ ] `net_plugin`: block broadcast decoupled from controller
// [ ] `producer_plugin`: control block broadcast
// [ ] `producer_plugin`: send committed blocks to BlockVault.
// [ ] `producer_plugin`: send accepted blocks to BlockVault.
// [ ] `producer_plugin`: store snapshots in BlockVault driven by RPC.
//
// [X] BlockVault "propose_constructed_block" interface.
// [ ] BlockVault "propose_constructed_block" implementation.
// [ ] BlockVault "propose_constructed_block" unit tests with mocked connection.
//
// [X] BlockVault "append_external_block" interface.
// [ ] BlockVault "append_external_block" implementation.
// [ ] BlockVault "append_external_block" unit tests with mocked connection.
//
// [X] BlockVault "propose_snapshot" interface.
// [ ] BlockVault "propose_snapshot" implementation.
// [ ] BlockVault "propose_snapshot" unit tests with mocked connection.
//
// [ ] `net_plugin`: disable `net_plugin` syncing when BlockVault is configured.
// [ ] `chain_plugin`: `chain_plugin` integration.
// [ ] BlockVault "sync_for_construction" interface.
// [ ] BlockVault "sync_for_construction" implementation.
// [ ] BlockVault "sync_for_construction" unit tests with mocked connection and consumer.
// [ ] BlockVault "sync_for_construction" sync controller with BlockVault when configured implementation.
// [ ] BlockVault "sync_for_construction" unit tests with mocked provider.

// LONG-TERM TOOD
// Rid all `using namespace` for verbosity-sake (or perhaps not).
// After interface is implemented double-check documentation comments.
// Make sure to delete all trailing whitespace in all touched files.
// Merge blockvault changes into my branch.
// Merge develop into blockvault.
// Submit PR to blockvault branch.

// SHORT-TERM TODO
// Finish plugin init test.
// Finish rest of impl.

#pragma once

#include <optional> // std::optional
#include <utility> // std::pair
#include <appbase/application.hpp> // appbase::plugin
#include "blockvault.hpp"

namespace eosio {

using namespace appbase;
using namespace eosio;
using namespace eosio::chain;

using block_num = uint32_t;

class blockvault_client_plugin_impl;

/// Documentation for blockvault_client_plugin.
///
/// blockvault_client_plugin is a proposed clustered component in an EOSIO
/// network architecture which provides a replicated durable storage with strong
/// consistency guarantees for all the input required by a redundant cluster of
/// nodeos nodes to achieve the guarantees:
///
/// Guarantee against double-production of blocks
/// Guarantee against finality violation
/// Guarantee of liveness (ability to make progress as a blockchain)
class blockvault_client_plugin : public appbase::plugin<blockvault_client_plugin> {
public:
   blockvault_client_plugin();
   virtual ~blockvault_client_plugin();

   APPBASE_PLUGIN_REQUIRES()
   virtual void set_program_options(options_description&, options_description& cfg) final;

   void plugin_initialize(const variables_map& options);
   void plugin_startup();
   void plugin_shutdown();

   static eosio::blockvault::block_vault_interface* get() {return nullptr;} // TODO: implement me

 private:
   std::unique_ptr<class blockvault_client_plugin_impl> my;
};

}
<|endoftext|>


<commit_before>/*********************************************************************************
- Contact:    Brigitte Cheynis     b.cheynis@ipnl.in2p3.fr
- Link:       http
- Raw data test file :
- Reference run number :
- Run Type:   CHANNEL_DELAY_TUNING
- DA Type:    LDC
- Number of events needed: 500
- Input Files:  argument list
- Output Files: local file  V0_ChannelDelayTuning.dat
                FXS file    V0_ChannelDelayTuning.dat
- Trigger types used: PHYSICS_EVENT
**********************************************************************************/

/**********************************************************************************
*                                                                                *
* VZERO Detector Algorithm used for tuning FEE parameters                         *
*                                                                                *
* This program reads data on the LDC                                              *
* It cumulates fBB and fBG flags, populates local "./V0_ChannelDelayTuning.dat"   *
* file, exports it to the FES, and stores it to DAQ DB                            *
* We have 128 channels instead of 64 as expected for V0 due to the two sets of    *
* charge integrators which are used by the FEE ...                                *
* The program reports about its processing progress.                              *
*                                                                                *
***********************************************************************************/

// DATE
#include "event.h"
#include "monitor.h"
#include "daqDA.h"

//AliRoot
#include <AliVZERORawStream.h>
#include <AliRawReaderDate.h>
#include <AliRawReader.h>
#include <AliDAQ.h>

// standard
#include <stdio.h>
#include <stdlib.h>

//ROOT
#include "TROOT.h"
#include "TPluginManager.h"
#include <TFile.h>
#include <TH1F.h>
#include <TMath.h>

/* Main routine --- Arguments: list of DATE raw data files */

int main(int argc, char **argv) {

/* magic line from Cvetan */
  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
                    "*",
                    "TStreamerInfo",
                    "RIO",
                    "TStreamerInfo()");
  int status;
  status = daqDA_DB_getFile("V00da_results","./V0_Ped_Width_Gain.dat");
  if (status) {
      printf("Failed to get Pedestal file (V0_Ped_Width_Gain.dat) from DAQ DB, status=%d\n", status);
      return -1;
  }

  Float_t MeanPed[128], SigPed[128], fdump;

  /* open the pedestal file and retrieve pedestal mean and sigma */
  FILE *fpPed = fopen("V0_Ped_Width_Gain.dat","r");
  for(int i=0;i<128;i++){
      fscanf(fpPed,"%f %f %f %f \n",&MeanPed[i],&SigPed[i],&fdump,&fdump);
//      printf("%.3f %.3f \n",MeanPed[i],SigPed[i]);
  }
  fclose(fpPed);

//______________________________________________________________________________
// Get running parameters from V00_ChannelDelayTuning_DA.config file

  Int_t    kNbEventSkipped;   // = 100;   number of events skipped - to be tuned
  Float_t  kSigmaCut;         // = 3.0;   number of sigmas for threshold cut - to be tuned

  status = daqDA_DB_getFile("V00_ChannelDelayTuning_DA.config","./V00_ChannelDelayTuning_DA.config");
  if (status) {
      printf("Failed to get config file (V00_ChannelDelayTuning_DA.config) from DAQ DB, status=%d\n", status);
      return -1;
  }
  /* open the config file and retrieve running parameters */
  FILE *fpConfig = fopen("V00_ChannelDelayTuning_DA.config","r");
  fscanf(fpConfig,"%f %d",&kSigmaCut,&kNbEventSkipped);
  fclose(fpConfig);

  printf("Number of events skipped = %d ; Number of sigmas for threshold cut = %f\n",kNbEventSkipped,kSigmaCut);
//______________________________________________________________________________

  Int_t BBFlag[64];
  Int_t BGFlag[64];
  Int_t ChargeEoI = 0;
  Bool_t Integrator = 0;
  Int_t NHit[64];
  for(Int_t i=0; i<64; i++) {
      BBFlag[i] = 0;
      BGFlag[i] = 0;
      NHit[i] = 0;
  }

  /* log start of process */
  printf("VZERO DA program started - Channel Delay Tuning \n");

  /* check that we got some arguments  */
  if (argc<2)   {
      printf("Wrong number of arguments\n");
      return -1;}

  /* open result file to be exported to FES */
  FILE *fp=NULL;
  fp=fopen("./V0_ChannelDelayTuning.dat","a");
  if (fp==NULL) {
      printf("Failed to open result file\n");
      return -1;}

  /* open log file to inform user */
  FILE *flog=NULL;
  flog=fopen("./V00log.txt","w");
  if (flog==NULL) {
      printf("Failed to open log file\n");
      return -1;  }

  /* report progress */
  daqDA_progressReport(10);

  /* init counters on events */
  int nevents_physics=0;
  int nevents_total=0;
  int iteration;
  sscanf(argv[1],"%d",&iteration);

  /* read the n data files */
  for (int n=2; n<argc; n++) {

  /* read the data  */
    status=monitorSetDataSource( argv[n] );
    if (status!=0) {
        printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
        return -1; }

  /* report progress */
    daqDA_progressReport(10+50*n/argc);

  /* read the data file */
    for(;;) {
        struct eventHeaderStruct *event;
        eventTypeType eventT;

        /* get next event */
        status=monitorGetEventDynamic((void **)&event);
        if (status==MON_ERR_EOF) break; /* end of monitoring file has been reached */
        if (status!=0) {
            printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
            return -1; }

        /* retry if got no event */
        if (event==NULL) break;

        /* decode event */
        eventT=event->eventType;

        switch (event->eventType){

        case START_OF_RUN:
	     printf("START Of Run detected\n");
             break;

        case END_OF_RUN:
	     printf("END Of Run detected\n");
             break;

        case PHYSICS_EVENT:
             nevents_physics++;

	     AliRawReader *rawReader = new AliRawReaderDate((void*)event);

	     AliVZERORawStream* rawStream  = new AliVZERORawStream(rawReader);
	     rawStream->Next();
	     if(nevents_physics > kNbEventSkipped){
		for(Int_t i=0; i<64; i++) {
	            ChargeEoI = rawStream->GetADC(i);
		    Integrator = rawStream->GetIntegratorFlag(i,10);
		    Float_t Threshold = MeanPed[i + 64 * Integrator] + kSigmaCut * SigPed[i + 64 * Integrator];

		    if((float)ChargeEoI>Threshold) {
			NHit[i]+=1;
	        	if(rawStream->GetBBFlag(i,10)) BBFlag[i]+=1;
			if(rawStream->GetBGFlag(i,10)) BGFlag[i]+=1;
		    }
          	}
	     }
             delete rawStream;
             rawStream = 0x0;
             delete rawReader;
             rawReader = 0x0;
        } // end of switch on event type

        nevents_total++;
        /* free resources */
        free(event);

    }    // end of loop over events
  }      // end of loop over data files

//________________________________________________________________________
//  Computes mean values, dumps them into the output text file
  Float_t fBB, fBG;
  for(Int_t i=0; i<64; i++) {
      if(NHit[i] > 0) {
         fBB = (float)BBFlag[i]/(float)NHit[i];
         fBG = (float)BGFlag[i]/(float)NHit[i];
       }else{
      	 fBB = fBG = 0.;
       }
       fprintf(fp," %d %d %f %f\n",iteration,i,fBB,fBG);
       fprintf(flog," it %d ch %d BB %f BG %f BBFlag %d BGFlag %d Hit %d\n",iteration,i,fBB,fBG,BBFlag[i],BGFlag[i],NHit[i]);
  }

//________________________________________________________________________

  /* write report */
  fprintf(flog,"Run #%s, received %d physics events out of %d\n",getenv("DATE_RUN_NUMBER"),nevents_physics,nevents_total);
  printf("Run #%s, received %d physics events out of %d\n",getenv("DATE_RUN_NUMBER"),nevents_physics,nevents_total);

  /* close result and log files */
  fclose(fp);
  fclose(flog);

  /* report progress */
  daqDA_progressReport(90);

  /* export result file to FES */
  status=daqDA_FES_storeFile("./V0_ChannelDelayTuning.dat","V00da_ChannelDelayTuning");
  if (status)    {
      printf("Failed to export file : %d\n",status);
      return -1; }

  /* store result file on Online DB */
//   status=daqDA_DB_storeFile("./V0_ChannelDelayTuning.dat","V00da_ChannelDelayTuning");
//   if (status)    {
//       printf("Failed to store file into Online DB: %d\n",status);
//       return -1; }

  /* report progress */
  daqDA_progressReport(100);

  return status;
}
<commit_msg>ADC taken as maximum value in the train of LHC clocks<commit_after>/*********************************************************************************
- Contact:    Brigitte Cheynis     b.cheynis@ipnl.in2p3.fr
- Link:       http
- Raw data test file :
- Reference run number :
- Run Type:   CHANNEL_DELAY_TUNING
- DA Type:    LDC
- Number of events needed: 500
- Input Files:  argument list
- Output Files: local file  V0_ChannelDelayTuning.dat
                FXS file    V0_ChannelDelayTuning.dat
- Trigger types used: PHYSICS_EVENT
**********************************************************************************/

/**********************************************************************************
*                                                                                *
* VZERO Detector Algorithm used for tuning FEE parameters                         *
*                                                                                *
* This program reads data on the LDC                                              *
* It cumulates fBB and fBG flags, populates local "./V0_ChannelDelayTuning.dat"   *
* file, exports it to the FES, and stores it to DAQ DB                            *
* We have 128 channels instead of 64 as expected for V0 due to the two sets of    *
* charge integrators which are used by the FEE ...                                *
* The program reports about its processing progress.                              *
*                                                                                *
***********************************************************************************/

// DATE
#include "event.h"
#include "monitor.h"
#include "daqDA.h"

//AliRoot
#include <AliVZERORawStream.h>
#include <AliRawReaderDate.h>
#include <AliRawReader.h>
#include <AliDAQ.h>

// standard
#include <stdio.h>
#include <stdlib.h>

//ROOT
#include "TROOT.h"
#include "TPluginManager.h"
#include <TFile.h>
#include <TH1F.h>
#include <TMath.h>

/* Main routine --- Arguments: list of DATE raw data files */

int main(int argc, char **argv) {

/* magic line from Cvetan */
  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
                    "*",
                    "TStreamerInfo",
                    "RIO",
                    "TStreamerInfo()");
  int status;
  status = daqDA_DB_getFile("V00da_results","./V0_Pedestals.dat");
  if (status) {
      printf("Failed to get Pedestal file (V0_Pedestals.dat) from DAQ DB, status=%d\n", status);
      return -1;
  }

  Float_t MeanPed[128], SigPed[128], fdump;

  /* open the pedestal file and retrieve pedestal mean and sigma */
  FILE *fpPed = fopen("V0_Pedestals.dat","r");
  for(int i=0;i<128;i++){
      fscanf(fpPed,"%f %f %f %f \n",&MeanPed[i],&SigPed[i],&fdump,&fdump);
//      printf("%.3f %.3f \n",MeanPed[i],SigPed[i]);
  }
  fclose(fpPed);

//______________________________________________________________________________
// Get running parameters from V00_ChannelDelayTuning_DA.config file

  Int_t    kNbEventSkipped;   // = 100;   number of events skipped - to be tuned
  Float_t  kSigmaCut;         // = 3.0;   number of sigmas for threshold cut - to be tuned

  status = daqDA_DB_getFile("V00_ChannelDelayTuning_DA.config","./V00_ChannelDelayTuning_DA.config");
  if (status) {
      printf("Failed to get config file (V00_ChannelDelayTuning_DA.config) from DAQ DB, status=%d\n", status);
      return -1;
  }
  /* open the config file and retrieve running parameters */
  FILE *fpConfig = fopen("V00_ChannelDelayTuning_DA.config","r");
  fscanf(fpConfig,"%f %d",&kSigmaCut,&kNbEventSkipped);
  fclose(fpConfig);

  printf("Number of events skipped = %d ; Number of sigmas for threshold cut = %f\n",kNbEventSkipped,kSigmaCut);
//______________________________________________________________________________

  Int_t  BBFlag[64];
  Int_t  BGFlag[64];
  Int_t  ChargeEoI  = 0;
  Bool_t Integrator = 0;
  Int_t NHit[64];
  for(Int_t i=0; i<64; i++) {
      BBFlag[i] = 0;
      BGFlag[i] = 0;
      NHit[i]   = 0;
  }

  /* log start of process */
  printf("VZERO DA program started - Channel Delay Tuning \n");

  /* check that we got some arguments  */
  if (argc<2)   {
      printf("Wrong number of arguments\n");
      return -1;}

  /* open result file to be exported to FES */
  FILE *fp=NULL;
  fp=fopen("./V0_ChannelDelayTuning.dat","a");
  if (fp==NULL) {
      printf("Failed to open result file\n");
      return -1;}

  /* open log file to inform user */
  FILE *flog=NULL;
  flog=fopen("./V00log.txt","w");
  if (flog==NULL) {
      printf("Failed to open log file\n");
      return -1;  }

  /* report progress */
  daqDA_progressReport(10);

  /* init counters on events */
  int nevents_physics=0;
  int nevents_total=0;
  int iteration;
  sscanf(argv[1],"%d",&iteration);

  /* read the n data files */
  for (int n=2; n<argc; n++) {

  /* read the data  */
    status=monitorSetDataSource( argv[n] );
    if (status!=0) {
        printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
        return -1; }

  /* report progress */
    daqDA_progressReport(10+50*n/argc);

  /* read the data file */
    for(;;) {
        struct eventHeaderStruct *event;
        eventTypeType eventT;

        /* get next event */
        status=monitorGetEventDynamic((void **)&event);
        if (status==MON_ERR_EOF) break; /* end of monitoring file has been reached */
        if (status!=0) {
            printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
            return -1; }

        /* retry if got no event */
        if (event==NULL) break;

        /* decode event */
        eventT=event->eventType;

        switch (event->eventType){

        case START_OF_RUN:
	     printf("START Of Run detected\n");
             break;

        case END_OF_RUN:
	     printf("END Of Run detected\n");
             break;

        case PHYSICS_EVENT:
             nevents_physics++;

	     AliRawReader *rawReader = new AliRawReaderDate((void*)event);

	     AliVZERORawStream* rawStream  = new AliVZERORawStream(rawReader);
	     rawStream->Next();
	     if(nevents_physics > kNbEventSkipped){
		for(Int_t i=0; i<64; i++) {
	            //ChargeEoI= rawStream->GetADC(i); takes EoI as central clock
		    // Look for the maximum in the LHC clock train instead of central clock 10
                    ChargeEoI    = 0;
                    Int_t iClock = 0;
                    for(size_t iEvent=0; iEvent<21; iEvent++){
                         if(rawStream->GetPedestal(i,iEvent)>ChargeEoI)
	                    {ChargeEoI= rawStream->GetPedestal(i,iEvent);
	                    iClock    = iEvent;}
                    }
		    Integrator = rawStream->GetIntegratorFlag(i,iClock);
		    Float_t Threshold = MeanPed[i + 64 * Integrator] + kSigmaCut * SigPed[i + 64 * Integrator];

		    if((float)ChargeEoI>Threshold) {
			NHit[i]+=1;
	        	if(rawStream->GetBBFlag(i,iClock)) BBFlag[i]+=1;
			if(rawStream->GetBGFlag(i,iClock)) BGFlag[i]+=1;
		    }
          	}
	     }
             delete rawStream;
             rawStream = 0x0;
             delete rawReader;
             rawReader = 0x0;
        } // end of switch on event type

        nevents_total++;
        /* free resources */
        free(event);

    }    // end of loop over events
  }      // end of loop over data files

//________________________________________________________________________
//  Computes mean values, dumps them into the output text file
  Float_t fBB, fBG;
  for(Int_t i=0; i<64; i++) {
      if(NHit[i] > 0) {
         fBB = (float)BBFlag[i]/(float)NHit[i];
         fBG = (float)BGFlag[i]/(float)NHit[i];
       }else{
      	 fBB = fBG = 0.;
       }
       fprintf(fp," %d %d %f %f\n",iteration,i,fBB,fBG);
       fprintf(flog," it %d ch %d BB %f BG %f BBFlag %d BGFlag %d Hit %d\n",iteration,i,fBB,fBG,BBFlag[i],BGFlag[i],NHit[i]);
  }

//________________________________________________________________________

  /* write report */
  fprintf(flog,"Run #%s, received %d physics events out of %d\n",getenv("DATE_RUN_NUMBER"),nevents_physics,nevents_total);
  printf("Run #%s, received %d physics events out of %d\n",getenv("DATE_RUN_NUMBER"),nevents_physics,nevents_total);

  /* close result and log files */
  fclose(fp);
  fclose(flog);

  /* report progress */
  daqDA_progressReport(90);

  /* export result file to FES */
  status=daqDA_FES_storeFile("./V0_ChannelDelayTuning.dat","V00da_ChannelDelayTuning");
  if (status)    {
      printf("Failed to export file : %d\n",status);
      return -1; }

  /* store result file on Online DB */
//   status=daqDA_DB_storeFile("./V0_ChannelDelayTuning.dat","V00da_ChannelDelayTuning");
//   if (status)    {
//       printf("Failed to store file into Online DB: %d\n",status);
//       return -1; }

  /* report progress */
  daqDA_progressReport(100);

  return status;
}
<|endoftext|>


<commit_before>#define DEBUG 1
/**
 * File    : B2.cpp
 * Author  : Kazune Takahashi
 * Created : 7/15/2019, 2:30:15 AM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define maxs(x, y) (x = max(x, y))
#define mins(x, y) (x = min(x, y))
using ll = long long;
class mint
{
public:
  static ll MOD;
  ll x;
  mint() : x(0) {}
  mint(ll x) : x(x % MOD) {}
  mint operator-() const { return x ? MOD - x : 0; }
  mint &operator+=(const mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  mint &operator-=(const mint &a) { return *this += -a; }
  mint &operator*=(const mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint &operator/=(const mint &a) { return (*this *= power(MOD - 2)); }
  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }
  mint operator/(const mint &a) const { return mint(*this) /= a; }
  bool operator<(const mint &a) const { return x < a.x; }
  bool operator==(const mint &a) const { return x == a.x; }
  const mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      mint half = power(N / 2);
      return half * half;
    }
  }
};
ll mint::MOD = 1e9 + 7;
istream &operator>>(istream &stream, mint &a) { return stream >> a.x; }
ostream &operator<<(ostream &stream, const mint &a) { return stream << a.x; }
class combination
{
public:
  vector<mint> inv, fact, factinv;
  static int MAX_SIZE;
  combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[mint::MOD % i]) * (mint::MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1; i < MAX_SIZE; i++)
    {
      fact[i] = mint(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  mint operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
};
int combination::MAX_SIZE = 1e6 + 10;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// const double epsilon = 1e-10;
// const ll infty = 1000000000000000LL;
// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

class UnionFind
{
  vector<long long> par;

public:
  UnionFind() {}
  UnionFind(int n) : par(n, -1) {}

  bool is_same(int x, int y)
  {
    return root(x) == root(y);
  }

  bool merge(int x, int y)
  {
    x = root(x);
    y = root(y);
    if (x == y)
    {
      return false;
    }
    if (par[x] > par[y])
    {
      swap(x, y);
    }
    par[x] += par[y];
    par[y] = x;
    return true;
  }

  long long size(int x)
  {
    return -par[root(x)];
  }

private:
  int root(int x)
  {
    if (par[x] < 0)
    {
      return x;
    }
    return par[x] = root(par[x]);
  }
};

using edge = tuple<int, int>;

int N, M;
vector<edge> E;
vector<edge> ans;
int cnt[100010];
vector<int> V[100010];

void Yes()
{
  for (auto x : ans)
  {
    cout << get<0>(x) << " " << get<1>(x) << endl;
  }
  exit(0);
}

void No()
{
  cout << "-1" << endl;
  exit(0);
}

void make_V()
{
  UnionFind uf{N};
  for (auto e : E)
  {
    int a, b;
    tie(a, b) = e;
    if (!uf.is_same(a, b))
    {
      uf.merge(a, b);
      V[a].push_back(b);
      V[b].push_back(a);
    }
    else
    {
      ans.push_back(e);
      cnt[a]++;
    }
  }
}

void dfs(int v, int p = -1)
{
  for (auto w : V[v])
  {
    if (p != w)
    {
      dfs(w, v);
    }
  }
  if (p == -1)
  {
    return;
  }
  if (cnt[v] % 2 == 1)
  {
    ans.push_back(edge(v, p));
  }
  else
  {
    ans.push_back(edge(p, v));
  }
}

void solve()
{
  make_V();
  dfs(0);
}

int main()
{
  cin >> N >> M;
  for (auto i = 0; i < M; i++)
  {
    int a, b;
    cin >> a >> b;
    --a;
    --b;
    E.push_back(edge(a, b));
  }
  if (M % 2 == 0)
  {
    No();
  }
  solve();
  Yes();
}<commit_msg>tried B2.cpp to 'B'<commit_after>#define DEBUG 1
/**
 * File    : B2.cpp
 * Author  : Kazune Takahashi
 * Created : 7/15/2019, 2:30:15 AM
 * Powered by Visual Studio Code
 */
#include <iostream>
#include <iomanip>
#include <algorithm>
#include <vector>
#include <string>
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <functional>
#include <random>
#include <chrono>
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;
#define maxs(x, y) (x = max(x, y))
#define mins(x, y) (x = min(x, y))
using ll = long long;
class mint
{
public:
  static ll MOD;
  ll x;
  mint() : x(0) {}
  mint(ll x) : x(x % MOD) {}
  mint operator-() const { return x ? MOD - x : 0; }
  mint &operator+=(const mint &a)
  {
    if ((x += a.x) >= MOD)
    {
      x -= MOD;
    }
    return *this;
  }
  mint &operator-=(const mint &a) { return *this += -a; }
  mint &operator*=(const mint &a)
  {
    (x *= a.x) %= MOD;
    return *this;
  }
  mint &operator/=(const mint &a) { return (*this *= power(MOD - 2)); }
  mint operator+(const mint &a) const { return mint(*this) += a; }
  mint operator-(const mint &a) const { return mint(*this) -= a; }
  mint operator*(const mint &a) const { return mint(*this) *= a; }
  mint operator/(const mint &a) const { return mint(*this) /= a; }
  bool operator<(const mint &a) const { return x < a.x; }
  bool operator==(const mint &a) const { return x == a.x; }
  const mint power(ll N)
  {
    if (N == 0)
    {
      return 1;
    }
    else if (N % 2 == 1)
    {
      return *this * power(N - 1);
    }
    else
    {
      mint half = power(N / 2);
      return half * half;
    }
  }
};
ll mint::MOD = 1e9 + 7;
istream &operator>>(istream &stream, mint &a) { return stream >> a.x; }
ostream &operator<<(ostream &stream, const mint &a) { return stream << a.x; }
class combination
{
public:
  vector<mint> inv, fact, factinv;
  static int MAX_SIZE;
  combination() : inv(MAX_SIZE), fact(MAX_SIZE), factinv(MAX_SIZE)
  {
    inv[1] = 1;
    for (auto i = 2; i < MAX_SIZE; i++)
    {
      inv[i] = (-inv[mint::MOD % i]) * (mint::MOD / i);
    }
    fact[0] = factinv[0] = 1;
    for (auto i = 1; i < MAX_SIZE; i++)
    {
      fact[i] = mint(i) * fact[i - 1];
      factinv[i] = inv[i] * factinv[i - 1];
    }
  }
  mint operator()(int n, int k)
  {
    if (n >= 0 && k >= 0 && n - k >= 0)
    {
      return fact[n] * factinv[k] * factinv[n - k];
    }
    return 0;
  }
};
int combination::MAX_SIZE = 1e6 + 10;
ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; }
// const double epsilon = 1e-10;
// const ll infty = 1000000000000000LL;
// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

class UnionFind
{
  vector<long long> par;

public:
  UnionFind() {}
  UnionFind(int n) : par(n, -1) {}

  bool is_same(int x, int y)
  {
    return root(x) == root(y);
  }

  bool merge(int x, int y)
  {
    x = root(x);
    y = root(y);
    if (x == y)
    {
      return false;
    }
    if (par[x] > par[y])
    {
      swap(x, y);
    }
    par[x] += par[y];
    par[y] = x;
    return true;
  }

  long long size(int x)
  {
    return -par[root(x)];
  }

private:
  int root(int x)
  {
    if (par[x] < 0)
    {
      return x;
    }
    return par[x] = root(par[x]);
  }
};

using edge = tuple<int, int>;

int N, M;
vector<edge> E;
vector<edge> ans;
int cnt[100010];
vector<int> V[100010];

void Yes()
{
  for (auto x : ans)
  {
    cout << get<0>(x) + 1 << " " << get<1>(x) + 1 << endl;
  }
  exit(0);
}

void No()
{
  cout << "-1" << endl;
  exit(0);
}

void make_V()
{
  UnionFind uf{N};
  for (auto e : E)
  {
    int a, b;
    tie(a, b) = e;
    if (!uf.is_same(a, b))
    {
      uf.merge(a, b);
      V[a].push_back(b);
      V[b].push_back(a);
    }
    else
    {
      ans.push_back(e);
      cnt[a]++;
    }
  }
}

void dfs(int v, int p = -1)
{
  for (auto w : V[v])
  {
    if (p != w)
    {
      dfs(w, v);
    }
  }
  if (p == -1)
  {
    return;
  }
  if (cnt[v] % 2 == 1)
  {
    ans.push_back(edge(v, p));
  }
  else
  {
    ans.push_back(edge(p, v));
  }
}

void solve()
{
  make_V();
  dfs(0);
}

int main()
{
  cin >> N >> M;
  for (auto i = 0; i < M; i++)
  {
    int a, b;
    cin >> a >> b;
    --a;
    --b;
    E.push_back(edge(a, b));
  }
  if (M % 2 == 1)
  {
    No();
  }
  solve();
  Yes();
}<|endoftext|>


<commit_before>#include "perf_precomp.hpp"

PERF_TEST_P(DevInfo_Size_MatType, transpose, testing::Combine(testing::ValuesIn(devices()),
                                                              testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                              testing::Values(CV_8UC1, CV_32SC1, CV_64FC1)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());

    setDevice(devInfo.deviceID());

    Mat src_host(size, type);

    declare.in(src_host, WARMUP_RNG);

    GpuMat src(src_host);
    GpuMat dst(size.width, size.height, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        transpose(src, dst);
    }

    Mat dst_host = dst;

    SANITY_CHECK(dst_host);
}

PERF_TEST_P(DevInfo_Size_MatType_FlipCode, flip, testing::Combine(testing::ValuesIn(devices()),
                                                                  testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                                  testing::Values(CV_8UC1, CV_8UC4),
                                                                  testing::Values((int)HORIZONTAL_AXIS, (int)VERTICAL_AXIS, (int)BOTH_AXIS)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());
    int flipCode = std::tr1::get<3>(GetParam());

    setDevice(devInfo.deviceID());

    Mat src_host(size, type);

    declare.in(src_host, WARMUP_RNG);

    GpuMat src(src_host);
    GpuMat dst(size, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        flip(src, dst, flipCode);
    }

    Mat dst_host = dst;

    SANITY_CHECK(dst_host);
}

PERF_TEST_P(DevInfo_Size_MatType, LUT, testing::Combine(testing::ValuesIn(devices()),
                                                        testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                        testing::Values(CV_8UC1, CV_8UC3)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());

    setDevice(devInfo.deviceID());

    Mat src_host(size, type);
    Mat lut(1, 256, CV_8UC1);

    declare.in(src_host, lut, WARMUP_RNG);

    GpuMat src(src_host);
    GpuMat dst(size, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        LUT(src, lut, dst);
    }

    Mat dst_host = dst;

    SANITY_CHECK(dst_host);
}

PERF_TEST_P(DevInfo_Size, cartToPolar, testing::Combine(testing::ValuesIn(devices()),
                                                        testing::Values(GPU_TYPICAL_MAT_SIZES)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());

    setDevice(devInfo.deviceID());

    Mat x_host(size, CV_32FC1);
    Mat y_host(size, CV_32FC1);

    declare.in(x_host, y_host, WARMUP_RNG);

    GpuMat x(x_host);
    GpuMat y(y_host);
    GpuMat magnitude(size, CV_32FC1);
    GpuMat angle(size, CV_32FC1);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        cartToPolar(x, y, magnitude, angle);
    }

    Mat magnitude_host = magnitude;
    Mat angle_host = angle;

    SANITY_CHECK(magnitude_host);
    SANITY_CHECK(angle_host);
}

PERF_TEST_P(DevInfo_Size, polarToCart, testing::Combine(testing::ValuesIn(devices()),
                                                        testing::Values(GPU_TYPICAL_MAT_SIZES)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());

    setDevice(devInfo.deviceID());

    Mat magnitude_host(size, CV_32FC1);
    Mat angle_host(size, CV_32FC1);

    declare.in(magnitude_host, angle_host, WARMUP_RNG);

    GpuMat magnitude(magnitude_host);
    GpuMat angle(angle_host);
    GpuMat x(size, CV_32FC1);
    GpuMat y(size, CV_32FC1);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        polarToCart(magnitude, angle, x, y);
    }

    Mat x_host = x;
    Mat y_host = angle;

    SANITY_CHECK(x_host);
    SANITY_CHECK(y_host);
}

PERF_TEST_P(DevInfo_Size_MatType, addMat, testing::Combine(testing::ValuesIn(devices()),
                                                           testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                           testing::Values(CV_8UC1, CV_8UC4, CV_32FC1)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());

    setDevice(devInfo.deviceID());

    Mat a_host(size, type);
    Mat b_host(size, type);

    declare.in(a_host, b_host, WARMUP_RNG);

    GpuMat a(a_host);
    GpuMat b(b_host);
    GpuMat c(size, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        add(a, b, c);
    }

    Mat c_host = c;

    SANITY_CHECK(c_host);
}

PERF_TEST_P(DevInfo_Size_MatType, addScalar, testing::Combine(testing::ValuesIn(devices()),
                                                              testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                              testing::Values(CV_32FC1, CV_32FC2)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());

    setDevice(devInfo.deviceID());

    Mat a_host(size, type);

    declare.in(a_host, WARMUP_RNG);

    GpuMat a(a_host);
    Scalar b(1,2,3,4);
    GpuMat c(size, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        add(a, b, c);
    }

    Mat c_host = c;

    SANITY_CHECK(c_host);
}

PERF_TEST_P(DevInfo_Size, exp, testing::Combine(testing::ValuesIn(devices()),
                                                testing::Values(GPU_TYPICAL_MAT_SIZES)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());

    setDevice(devInfo.deviceID());

    Mat a_host(size, CV_32FC1);

    declare.in(a_host, WARMUP_RNG);

    GpuMat a(a_host);
    GpuMat b(size, CV_32FC1);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        exp(a, b);
    }

    Mat b_host = b;

    SANITY_CHECK(b_host);
}

PERF_TEST_P(DevInfo_Size_MatType, pow, testing::Combine(testing::ValuesIn(devices()),
                                                        testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                        testing::Values(CV_8UC1, CV_8UC4, CV_16UC1, CV_32FC1)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());

    setDevice(devInfo.deviceID());

    Mat src_host(size, type);

    declare.in(src_host, WARMUP_RNG);

    GpuMat src(src_host);
    GpuMat dst(size, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        pow(src, 2.0, dst);
    }

    Mat dst_host = dst;

    SANITY_CHECK(dst_host);
}

PERF_TEST_P(DevInfo_Size_MatType_CmpOp, compare, testing::Combine(testing::ValuesIn(devices()),
                                                                  testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                                  testing::Values(CV_8UC4, CV_32FC1),
                                                                  testing::Values(CMP_NE, CMP_EQ)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());
    int cmpop = std::tr1::get<3>(GetParam());

    setDevice(devInfo.deviceID());

    Mat src1_host(size, type);
    Mat src2_host(size, type);

    declare.in(src1_host, src2_host, WARMUP_RNG);

    GpuMat src1(src1_host);
    GpuMat src2(src2_host);
    GpuMat dst(size, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        compare(src1, src2, dst, cmpop);
    }

    Mat dst_host = dst;

    SANITY_CHECK(dst_host);
}

PERF_TEST_P(DevInfo_Size_MatType, bitwise_not, testing::Combine(testing::ValuesIn(devices()),
                                                                testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                                testing::Values(CV_8UC1, CV_16UC1, CV_32SC1)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());

    setDevice(devInfo.deviceID());

    Mat src_host(size, type);

    declare.in(src_host, WARMUP_RNG);

    GpuMat src(src_host);
    GpuMat dst(size, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        bitwise_not(src, dst);
    }

    Mat dst_host = dst;

    SANITY_CHECK(dst_host);
}

PERF_TEST_P(DevInfo_Size_MatType, bitwise_and, testing::Combine(testing::ValuesIn(devices()),
                                                                testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                                testing::Values(CV_8UC1, CV_16UC1, CV_32SC1)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());

    setDevice(devInfo.deviceID());

    Mat src1_host(size, type);
    Mat src2_host(size, type);

    declare.in(src1_host, src2_host, WARMUP_RNG);

    GpuMat src1(src1_host);
    GpuMat src2(src2_host);
    GpuMat dst(size, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        bitwise_and(src1, src2, dst);
    }

    Mat dst_host = dst;

    SANITY_CHECK(dst_host);
}

PERF_TEST_P(DevInfo_Size_MatType, min, testing::Combine(testing::ValuesIn(devices()),
                                                        testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                        testing::Values(CV_8UC1, CV_16UC1, CV_32SC1)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());

    setDevice(devInfo.deviceID());

    Mat src1_host(size, type);
    Mat src2_host(size, type);

    declare.in(src1_host, src2_host, WARMUP_RNG);

    GpuMat src1(src1_host);
    GpuMat src2(src2_host);
    GpuMat dst(size, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        min(src1, src2, dst);
    }

    Mat dst_host = dst;

    SANITY_CHECK(dst_host);
}
<commit_msg>fixed bug in gpu perf. test<commit_after>#include "perf_precomp.hpp"

PERF_TEST_P(DevInfo_Size_MatType, transpose, testing::Combine(testing::ValuesIn(devices()),
                                                              testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                              testing::Values(CV_8UC1, CV_32SC1, CV_64FC1)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());

    setDevice(devInfo.deviceID());

    Mat src_host(size, type);

    declare.in(src_host, WARMUP_RNG);

    GpuMat src(src_host);
    GpuMat dst(size.width, size.height, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        transpose(src, dst);
    }

    Mat dst_host = dst;

    SANITY_CHECK(dst_host);
}

PERF_TEST_P(DevInfo_Size_MatType_FlipCode, flip, testing::Combine(testing::ValuesIn(devices()),
                                                                  testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                                  testing::Values(CV_8UC1, CV_8UC4),
                                                                  testing::Values((int)HORIZONTAL_AXIS, (int)VERTICAL_AXIS, (int)BOTH_AXIS)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());
    int flipCode = std::tr1::get<3>(GetParam());

    setDevice(devInfo.deviceID());

    Mat src_host(size, type);

    declare.in(src_host, WARMUP_RNG);

    GpuMat src(src_host);
    GpuMat dst(size, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        flip(src, dst, flipCode);
    }

    Mat dst_host = dst;

    SANITY_CHECK(dst_host);
}

PERF_TEST_P(DevInfo_Size_MatType, LUT, testing::Combine(testing::ValuesIn(devices()),
                                                        testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                        testing::Values(CV_8UC1, CV_8UC3)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());

    setDevice(devInfo.deviceID());

    Mat src_host(size, type);
    Mat lut(1, 256, CV_8UC1);

    declare.in(src_host, lut, WARMUP_RNG);

    GpuMat src(src_host);
    GpuMat dst(size, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        LUT(src, lut, dst);
    }

    Mat dst_host = dst;

    SANITY_CHECK(dst_host);
}

PERF_TEST_P(DevInfo_Size, cartToPolar, testing::Combine(testing::ValuesIn(devices()),
                                                        testing::Values(GPU_TYPICAL_MAT_SIZES)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());

    setDevice(devInfo.deviceID());

    Mat x_host(size, CV_32FC1);
    Mat y_host(size, CV_32FC1);

    declare.in(x_host, y_host, WARMUP_RNG);

    GpuMat x(x_host);
    GpuMat y(y_host);
    GpuMat magnitude(size, CV_32FC1);
    GpuMat angle(size, CV_32FC1);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        cartToPolar(x, y, magnitude, angle);
    }

    Mat magnitude_host = magnitude;
    Mat angle_host = angle;

    SANITY_CHECK(magnitude_host);
    SANITY_CHECK(angle_host);
}

PERF_TEST_P(DevInfo_Size, polarToCart, testing::Combine(testing::ValuesIn(devices()),
                                                        testing::Values(GPU_TYPICAL_MAT_SIZES)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());

    setDevice(devInfo.deviceID());

    Mat magnitude_host(size, CV_32FC1);
    Mat angle_host(size, CV_32FC1);

    declare.in(magnitude_host, angle_host, WARMUP_RNG);

    GpuMat magnitude(magnitude_host);
    GpuMat angle(angle_host);
    GpuMat x(size, CV_32FC1);
    GpuMat y(size, CV_32FC1);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        polarToCart(magnitude, angle, x, y);
    }

    Mat x_host = x;
    Mat y_host = angle;

    SANITY_CHECK(x_host);
    SANITY_CHECK(y_host);
}

PERF_TEST_P(DevInfo_Size_MatType, addMat, testing::Combine(testing::ValuesIn(devices()),
                                                           testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                           testing::Values(CV_8UC1, CV_8UC4, CV_32FC1)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());

    setDevice(devInfo.deviceID());

    Mat a_host(size, type);
    Mat b_host(size, type);

    declare.in(a_host, b_host, WARMUP_RNG);

    GpuMat a(a_host);
    GpuMat b(b_host);
    GpuMat c(size, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        add(a, b, c);
    }

    Mat c_host = c;

    SANITY_CHECK(c_host);
}

PERF_TEST_P(DevInfo_Size_MatType, addScalar, testing::Combine(testing::ValuesIn(devices()),
                                                              testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                              testing::Values(CV_32FC1, CV_32FC2)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());

    setDevice(devInfo.deviceID());

    Mat a_host(size, type);

    declare.in(a_host, WARMUP_RNG);

    GpuMat a(a_host);
    Scalar b(1,2,3,4);
    GpuMat c(size, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        add(a, b, c);
    }

    Mat c_host = c;

    SANITY_CHECK(c_host);
}

PERF_TEST_P(DevInfo_Size, exp, testing::Combine(testing::ValuesIn(devices()),
                                                testing::Values(GPU_TYPICAL_MAT_SIZES)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());

    setDevice(devInfo.deviceID());

    Mat a_host(size, CV_32FC1);

    declare.in(a_host, WARMUP_RNG);

    GpuMat a(a_host);
    GpuMat b(size, CV_32FC1);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        exp(a, b);
    }

    Mat b_host = b;

    SANITY_CHECK(b_host);
}

PERF_TEST_P(DevInfo_Size_MatType, pow, testing::Combine(testing::ValuesIn(devices()),
                                                        testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                        testing::Values(CV_8UC1, CV_8UC4, CV_16UC1, CV_32FC1)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());

    setDevice(devInfo.deviceID());

    Mat src_host(size, type);

    declare.in(src_host, WARMUP_RNG);

    GpuMat src(src_host);
    GpuMat dst(size, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        pow(src, 2.0, dst);
    }

    Mat dst_host = dst;

    SANITY_CHECK(dst_host);
}

PERF_TEST_P(DevInfo_Size_MatType_CmpOp, compare, testing::Combine(testing::ValuesIn(devices()),
                                                                  testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                                  testing::Values(CV_8UC4, CV_32FC1),
                                                                  testing::Values((int)CMP_NE, (int)CMP_EQ)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());
    int cmpop = std::tr1::get<3>(GetParam());

    setDevice(devInfo.deviceID());

    Mat src1_host(size, type);
    Mat src2_host(size, type);

    declare.in(src1_host, src2_host, WARMUP_RNG);

    GpuMat src1(src1_host);
    GpuMat src2(src2_host);
    GpuMat dst(size, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        compare(src1, src2, dst, cmpop);
    }

    Mat dst_host = dst;

    SANITY_CHECK(dst_host);
}

PERF_TEST_P(DevInfo_Size_MatType, bitwise_not, testing::Combine(testing::ValuesIn(devices()),
                                                                testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                                testing::Values(CV_8UC1, CV_16UC1, CV_32SC1)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());

    setDevice(devInfo.deviceID());

    Mat src_host(size, type);

    declare.in(src_host, WARMUP_RNG);

    GpuMat src(src_host);
    GpuMat dst(size, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        bitwise_not(src, dst);
    }

    Mat dst_host = dst;

    SANITY_CHECK(dst_host);
}

PERF_TEST_P(DevInfo_Size_MatType, bitwise_and, testing::Combine(testing::ValuesIn(devices()),
                                                                testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                                testing::Values(CV_8UC1, CV_16UC1, CV_32SC1)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());

    setDevice(devInfo.deviceID());

    Mat src1_host(size, type);
    Mat src2_host(size, type);

    declare.in(src1_host, src2_host, WARMUP_RNG);

    GpuMat src1(src1_host);
    GpuMat src2(src2_host);
    GpuMat dst(size, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        bitwise_and(src1, src2, dst);
    }

    Mat dst_host = dst;

    SANITY_CHECK(dst_host);
}

PERF_TEST_P(DevInfo_Size_MatType, min, testing::Combine(testing::ValuesIn(devices()),
                                                        testing::Values(GPU_TYPICAL_MAT_SIZES),
                                                        testing::Values(CV_8UC1, CV_16UC1, CV_32SC1)))
{
    DeviceInfo devInfo = std::tr1::get<0>(GetParam());
    Size size = std::tr1::get<1>(GetParam());
    int type = std::tr1::get<2>(GetParam());

    setDevice(devInfo.deviceID());

    Mat src1_host(size, type);
    Mat src2_host(size, type);

    declare.in(src1_host, src2_host, WARMUP_RNG);

    GpuMat src1(src1_host);
    GpuMat src2(src2_host);
    GpuMat dst(size, type);

    declare.time(0.5).iterations(100);

    SIMPLE_TEST_CYCLE()
    {
        min(src1, src2, dst);
    }

    Mat dst_host = dst;

    SANITY_CHECK(dst_host);
}
<|endoftext|>


<commit_before>/*
 Flexisip, a flexible SIP proxy server with media capabilities.
 Copyright (C) 2012  Belledonne Communications SARL.

 This program 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, 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 Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <sys/types.h>
#include <dirent.h>

#include "pushnotificationservice.hh"
#include "pushnotificationclient.hh"
#include "common.hh"

#include <boost/bind.hpp>
#include <sstream>

const char *APN_DEV_ADDRESS = "gateway.sandbox.push.apple.com";
const char *APN_PROD_ADDRESS = "gateway.push.apple.com";
const char *APN_PORT = "2195";

const char *GPN_ADDRESS = "gcm.googleapis.com";
const char *GPN_PORT = "5235";

const char *WPPN_PORT = "80";

int MAX_QUEUE_SIZE = 10;

using namespace ::std;
namespace ssl = boost::asio::ssl;

int PushNotificationService::sendRequest(const std::shared_ptr<PushNotificationRequest> &pn) {
	std::shared_ptr<PushNotificationClient> client=mClients[pn->getAppIdentifier()];
	if (client==0){
		if (pn->getType().compare(string("wp"))==0) {
			string wpClient = pn->getAppIdentifier();
			std::shared_ptr<ssl::context> ctx(new ssl::context(mIOService, ssl::context::sslv23_client));
			boost::system::error_code err;
			ctx->set_options(ssl::context::default_workarounds, err);
			ctx->set_verify_mode(ssl::context::verify_none);
			mClients[wpClient] = std::make_shared<PushNotificationClient>(wpClient, this, ctx, pn->getAppIdentifier(), WPPN_PORT, MAX_QUEUE_SIZE, false);
			LOGD("Creating PNclient for client %s",pn->getAppIdentifier().c_str());
			client = mClients[wpClient];
		} else {
			LOGE("No push notification certificate for client %s",pn->getAppIdentifier().c_str());
			return -1;
		}
	}
	//this method is called from flexisip main thread, while service is running in its own thread.
	//To avoid using dedicated mutex, use the server post() method to delegate the processing of the push notification to the service thread.
	mIOService.post(std::bind(&PushNotificationClient::sendRequest,client,pn));
	return 0;
}

void PushNotificationService::start() {
	if (mThread == NULL || !mThread->joinable()) {
		delete mThread;
		mThread = NULL;
	}
	if (mThread == NULL) {
		LOGD("Start PushNotificationService");
		mHaveToStop = false;
		mThread = new thread(&PushNotificationService::run, this);
	}
}

void PushNotificationService::stop() {
	if (mThread != NULL) {
		LOGD("Stopping PushNotificationService");
		mHaveToStop = true;
		mIOService.stop();
		if (mThread->joinable()) {
			mThread->join();
		}
		delete mThread;
		mThread = NULL;
	}
}

void PushNotificationService::waitEnd() {
	if (mThread != NULL) {
		LOGD("Waiting for PushNotificationService to end");
		bool finished = false;
		while (!finished) {
			finished = true;
			map<string, std::shared_ptr<PushNotificationClient> >::const_iterator it;
			for (it = mClients.begin(); it != mClients.end(); ++it) {
				if (!it->second->isIdle()) {
					finished = false;
					break;
				}
			}
		}
	}
}

void PushNotificationService::setupClients(const string &certdir, const string &ca, int maxQueueSize) {
	struct dirent *dirent;
	DIR *dirp;
	MAX_QUEUE_SIZE = maxQueueSize;

	// Android Client
	string googleClient = string("google");
	std::shared_ptr<ssl::context> ctx(new ssl::context(mIOService, ssl::context::sslv23_client));
	boost::system::error_code err;
	ctx->set_options(ssl::context::default_workarounds, err);
	ctx->set_verify_mode(ssl::context::verify_none);
	mClients[googleClient]=std::make_shared<PushNotificationClient>(googleClient, this, ctx, GPN_ADDRESS, GPN_PORT, maxQueueSize, true);

	dirp=opendir(certdir.c_str());
	if (dirp==NULL){
		LOGE("Could not open push notification certificates directory (%s): %s",certdir.c_str(),strerror(errno));
		return;
	}
	while((dirent=readdir(dirp))!=NULL){
		if (dirent->d_type!=DT_REG && dirent->d_type!=DT_LNK) continue;
		string cert=string(dirent->d_name);
		string certpath= string(certdir)+"/"+cert;
		std::shared_ptr<ssl::context> ctx(new ssl::context(mIOService, ssl::context::sslv23_client));
		boost::system::error_code err;
		ctx->set_options(ssl::context::default_workarounds, err);
		ctx->set_password_callback(bind(&PushNotificationService::handle_password_callback, this, _1, _2));

		if (!ca.empty()) {
			ctx->set_verify_mode(ssl::context::verify_peer);
	#if BOOST_VERSION >= 104800
			ctx->set_verify_callback(bind(&PushNotificationService::handle_verify_callback, this, _1, _2));
	#endif
			ctx->load_verify_file(ca, err);
			if (err) {
				LOGE("load_verify_file: %s",err.message().c_str());
			}
		} else {
			ctx->set_verify_mode(ssl::context::verify_none);
		}
		ctx->add_verify_path("/etc/ssl/certs");

		if (!cert.empty()) {
			ctx->use_certificate_file(certpath, ssl::context::file_format::pem, err);
			if (err) {
				LOGE("use_certificate_file %s: %s",certpath.c_str(), err.message().c_str());
			}
		}
		string key=certpath;
		if (!key.empty()) {
			ctx->use_private_key_file(key, ssl::context::file_format::pem, err);
			if (err) {
				LOGE("use_private_key_file: %s",err.message().c_str());
			}
		}
		string certName = cert.substr(0, cert.size() - 4); // Remove .pem at the end of cert
		const char *apn_server;
		if (certName.find(".dev")!=string::npos)
			apn_server=APN_DEV_ADDRESS;
		else apn_server=APN_PROD_ADDRESS;
		mClients[certName]=std::make_shared<PushNotificationClient>(cert, this, ctx, apn_server, APN_PORT, maxQueueSize, true);
	}
	closedir(dirp);
}

PushNotificationService::PushNotificationService(const std::string &certdir, const std::string &cafile, int maxQueueSize, StatCounter64 *countFailed, StatCounter64 *countSent) :
		mIOService(), mThread(NULL), mCountFailed(countFailed), mCountSent(countSent) {
	setupClients(certdir, cafile, maxQueueSize);
}

PushNotificationService::~PushNotificationService() {
	stop();
}

int PushNotificationService::run() {
	LOGD("PushNotificationService Start");
	boost::asio::io_service::work work(mIOService);
	mIOService.run();
	LOGD("PushNotificationService End");
	return 0;
}

void PushNotificationService::clientEnded() {
}

boost::asio::io_service &PushNotificationService::getService() {
	return mIOService;
}

string PushNotificationService::handle_password_callback(size_t max_length, ssl::context_base::password_purpose purpose) const {
	return mPassword;
}

#if BOOST_VERSION >= 104800
bool PushNotificationService::handle_verify_callback(bool preverified, ssl::verify_context& ctx) const {
	char subject_name[256];
#if not(__GNUC__ == 4 && __GNUC_MINOR__ < 5 )
	SLOGD << "Verifying " << [&] () {
		X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
		X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
		return subject_name;
	}();
#else
	X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
	X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
	SLOGD << "Verifying " << subject_name;
#endif
	return preverified;
}
#endif
<commit_msg>Fix spurious test in push notif service<commit_after>/*
 Flexisip, a flexible SIP proxy server with media capabilities.
 Copyright (C) 2012  Belledonne Communications SARL.

 This program 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, 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 Affero General Public License for more details.

 You should have received a copy of the GNU Affero General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include <sys/types.h>
#include <dirent.h>

#include "pushnotificationservice.hh"
#include "pushnotificationclient.hh"
#include "common.hh"

#include <boost/bind.hpp>
#include <sstream>

const char *APN_DEV_ADDRESS = "gateway.sandbox.push.apple.com";
const char *APN_PROD_ADDRESS = "gateway.push.apple.com";
const char *APN_PORT = "2195";

const char *GPN_ADDRESS = "gcm.googleapis.com";
const char *GPN_PORT = "5235";

const char *WPPN_PORT = "80";

int MAX_QUEUE_SIZE = 10;

using namespace ::std;
namespace ssl = boost::asio::ssl;

int PushNotificationService::sendRequest(const std::shared_ptr<PushNotificationRequest> &pn) {
	std::shared_ptr<PushNotificationClient> client=mClients[pn->getAppIdentifier()];
	if (client==0){
		if (pn->getType().compare(string("wp"))==0) {
			string wpClient = pn->getAppIdentifier();
			std::shared_ptr<ssl::context> ctx(new ssl::context(mIOService, ssl::context::sslv23_client));
			boost::system::error_code err;
			ctx->set_options(ssl::context::default_workarounds, err);
			ctx->set_verify_mode(ssl::context::verify_none);
			mClients[wpClient] = std::make_shared<PushNotificationClient>(wpClient, this, ctx, pn->getAppIdentifier(), WPPN_PORT, MAX_QUEUE_SIZE, false);
			LOGD("Creating PNclient for client %s",pn->getAppIdentifier().c_str());
			client = mClients[wpClient];
		} else {
			LOGE("No push notification certificate for client %s",pn->getAppIdentifier().c_str());
			return -1;
		}
	}
	//this method is called from flexisip main thread, while service is running in its own thread.
	//To avoid using dedicated mutex, use the server post() method to delegate the processing of the push notification to the service thread.
	mIOService.post(std::bind(&PushNotificationClient::sendRequest,client,pn));
	return 0;
}

void PushNotificationService::start() {
	if (mThread && !mThread->joinable()) {
		delete mThread;
		mThread = NULL;
	}
	if (mThread == NULL) {
		LOGD("Start PushNotificationService");
		mHaveToStop = false;
		mThread = new thread(&PushNotificationService::run, this);
	}
}

void PushNotificationService::stop() {
	if (mThread != NULL) {
		LOGD("Stopping PushNotificationService");
		mHaveToStop = true;
		mIOService.stop();
		if (mThread->joinable()) {
			mThread->join();
		}
		delete mThread;
		mThread = NULL;
	}
}

void PushNotificationService::waitEnd() {
	if (mThread != NULL) {
		LOGD("Waiting for PushNotificationService to end");
		bool finished = false;
		while (!finished) {
			finished = true;
			map<string, std::shared_ptr<PushNotificationClient> >::const_iterator it;
			for (it = mClients.begin(); it != mClients.end(); ++it) {
				if (!it->second->isIdle()) {
					finished = false;
					break;
				}
			}
		}
	}
}

void PushNotificationService::setupClients(const string &certdir, const string &ca, int maxQueueSize) {
	struct dirent *dirent;
	DIR *dirp;
	MAX_QUEUE_SIZE = maxQueueSize;

	// Android Client
	string googleClient = string("google");
	std::shared_ptr<ssl::context> ctx(new ssl::context(mIOService, ssl::context::sslv23_client));
	boost::system::error_code err;
	ctx->set_options(ssl::context::default_workarounds, err);
	ctx->set_verify_mode(ssl::context::verify_none);
	mClients[googleClient]=std::make_shared<PushNotificationClient>(googleClient, this, ctx, GPN_ADDRESS, GPN_PORT, maxQueueSize, true);

	dirp=opendir(certdir.c_str());
	if (dirp==NULL){
		LOGE("Could not open push notification certificates directory (%s): %s",certdir.c_str(),strerror(errno));
		return;
	}
	while((dirent=readdir(dirp))!=NULL){
		if (dirent->d_type!=DT_REG && dirent->d_type!=DT_LNK) continue;
		string cert=string(dirent->d_name);
		string certpath= string(certdir)+"/"+cert;
		std::shared_ptr<ssl::context> ctx(new ssl::context(mIOService, ssl::context::sslv23_client));
		boost::system::error_code err;
		ctx->set_options(ssl::context::default_workarounds, err);
		ctx->set_password_callback(bind(&PushNotificationService::handle_password_callback, this, _1, _2));

		if (!ca.empty()) {
			ctx->set_verify_mode(ssl::context::verify_peer);
	#if BOOST_VERSION >= 104800
			ctx->set_verify_callback(bind(&PushNotificationService::handle_verify_callback, this, _1, _2));
	#endif
			ctx->load_verify_file(ca, err);
			if (err) {
				LOGE("load_verify_file: %s",err.message().c_str());
			}
		} else {
			ctx->set_verify_mode(ssl::context::verify_none);
		}
		ctx->add_verify_path("/etc/ssl/certs");

		if (!cert.empty()) {
			ctx->use_certificate_file(certpath, ssl::context::file_format::pem, err);
			if (err) {
				LOGE("use_certificate_file %s: %s",certpath.c_str(), err.message().c_str());
			}
		}
		string key=certpath;
		if (!key.empty()) {
			ctx->use_private_key_file(key, ssl::context::file_format::pem, err);
			if (err) {
				LOGE("use_private_key_file: %s",err.message().c_str());
			}
		}
		string certName = cert.substr(0, cert.size() - 4); // Remove .pem at the end of cert
		const char *apn_server;
		if (certName.find(".dev")!=string::npos)
			apn_server=APN_DEV_ADDRESS;
		else apn_server=APN_PROD_ADDRESS;
		mClients[certName]=std::make_shared<PushNotificationClient>(cert, this, ctx, apn_server, APN_PORT, maxQueueSize, true);
	}
	closedir(dirp);
}

PushNotificationService::PushNotificationService(const std::string &certdir, const std::string &cafile, int maxQueueSize, StatCounter64 *countFailed, StatCounter64 *countSent) :
		mIOService(), mThread(NULL), mCountFailed(countFailed), mCountSent(countSent) {
	setupClients(certdir, cafile, maxQueueSize);
}

PushNotificationService::~PushNotificationService() {
	stop();
}

int PushNotificationService::run() {
	LOGD("PushNotificationService Start");
	boost::asio::io_service::work work(mIOService);
	mIOService.run();
	LOGD("PushNotificationService End");
	return 0;
}

void PushNotificationService::clientEnded() {
}

boost::asio::io_service &PushNotificationService::getService() {
	return mIOService;
}

string PushNotificationService::handle_password_callback(size_t max_length, ssl::context_base::password_purpose purpose) const {
	return mPassword;
}

#if BOOST_VERSION >= 104800
bool PushNotificationService::handle_verify_callback(bool preverified, ssl::verify_context& ctx) const {
	char subject_name[256];
#if not(__GNUC__ == 4 && __GNUC_MINOR__ < 5 )
	SLOGD << "Verifying " << [&] () {
		X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
		X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
		return subject_name;
	}();
#else
	X509* cert = X509_STORE_CTX_get_current_cert(ctx.native_handle());
	X509_NAME_oneline(X509_get_subject_name(cert), subject_name, 256);
	SLOGD << "Verifying " << subject_name;
#endif
	return preverified;
}
#endif
<|endoftext|>