<commit_before>/*********************************************************\
 * Copyright (c) 2012-2021 The Unrimp Team
 *
 * 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.
\*********************************************************/

// Amalgamated/unity build
#ifdef _WIN32
	// Disable warnings in external headers, we can't fix them
	__pragma(warning(disable: 4191))	// warning C4191: 'type cast': unsafe conversion from 'FARPROC' to 'void (__cdecl *)(void)'
	__pragma(warning(disable: 5219))	// warning C5219: implicit conversion from 'mi_msecs_t' to 'double', possible loss of data
	__pragma(warning(disable: 4296))	// warning C4296: '>': expression is always false
	__pragma(warning(disable: 4365))	// warning C4365: 'argument': conversion from 'long' to 'unsigned int', signed/unsigned mismatch
	__pragma(warning(disable: 4625))	// warning C4625: 'mi_page_s': copy constructor was implicitly defined as deleted
	__pragma(warning(disable: 4626))	// warning C4626: 'mi_page_s': assignment operator was implicitly defined as deleted
	__pragma(warning(disable: 4668))	// warning C4668: '__GNUC__' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'
	__pragma(warning(disable: 5026))	// warning C5026: 'mi_page_s': move constructor was implicitly defined as deleted
	__pragma(warning(disable: 5027))	// warning C5027: 'mi_page_s': move assignment operator was implicitly defined as deleted
	__pragma(warning(disable: 5039))	// warning C5039: 'TpSetCallbackCleanupGroup': pointer or reference to potentially throwing function passed to 'extern "C"' function under -EHc. Undefined behavior may occur if this function throws an exception
#endif
#include "src/alloc.c"
#include "src/alloc-aligned.c"
#include "src/arena.c"
#include "src/bitmap.c"
#include "src/heap.c"
#include "src/init.c"
#include "src/options.c"
#include "src/os.c"
#include "src/page.c"
#include "src/random.c"
#include "src/region.c"
#include "src/segment.c"
#include "src/stats.c"
<commit_msg>Visual Studio 2019 16.9.5 compile fix<commit_after>/*********************************************************\
 * Copyright (c) 2012-2021 The Unrimp Team
 *
 * 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.
\*********************************************************/

// Amalgamated/unity build
#ifdef _WIN32
	// Disable warnings in external headers, we can't fix them
	__pragma(warning(disable: 4191))	// warning C4191: 'type cast': unsafe conversion from 'FARPROC' to 'void (__cdecl *)(void)'
	__pragma(warning(disable: 5219))	// warning C5219: implicit conversion from 'mi_msecs_t' to 'double', possible loss of data
	__pragma(warning(disable: 4296))	// warning C4296: '>': expression is always false
	__pragma(warning(disable: 4365))	// warning C4365: 'argument': conversion from 'long' to 'unsigned int', signed/unsigned mismatch
	__pragma(warning(disable: 4505))	// warning C4505: 'mi_os_get_aligned_hint': unreferenced local function has been removed
	__pragma(warning(disable: 4625))	// warning C4625: 'mi_page_s': copy constructor was implicitly defined as deleted
	__pragma(warning(disable: 4626))	// warning C4626: 'mi_page_s': assignment operator was implicitly defined as deleted
	__pragma(warning(disable: 4668))	// warning C4668: '__GNUC__' is not defined as a preprocessor macro, replacing with '0' for '#if/#elif'
	__pragma(warning(disable: 5026))	// warning C5026: 'mi_page_s': move constructor was implicitly defined as deleted
	__pragma(warning(disable: 5027))	// warning C5027: 'mi_page_s': move assignment operator was implicitly defined as deleted
	__pragma(warning(disable: 5039))	// warning C5039: 'TpSetCallbackCleanupGroup': pointer or reference to potentially throwing function passed to 'extern "C"' function under -EHc. Undefined behavior may occur if this function throws an exception
#endif
#include "src/alloc.c"
#include "src/alloc-aligned.c"
#include "src/arena.c"
#include "src/bitmap.c"
#include "src/heap.c"
#include "src/init.c"
#include "src/options.c"
#include "src/os.c"
#include "src/page.c"
#include "src/random.c"
#include "src/region.c"
#include "src/segment.c"
#include "src/stats.c"
<|endoftext|>


<commit_before>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2012 Heiko Strathmann
 */

#include <shogun/statistics/HSIC.h>
#include <shogun/features/Features.h>
#include <shogun/mathematics/Statistics.h>
#include <shogun/kernel/Kernel.h>

using namespace shogun;

CHSIC::CHSIC() : CKernelIndependenceTestStatistic()
{
	init();
}

CHSIC::CHSIC(CKernel* kernel_p, CKernel* kernel_q, CFeatures* p,CFeatures* q) :
		CKernelIndependenceTestStatistic(kernel_p, kernel_q, p, q)
{
	if (p->get_num_vectors()!=q->get_num_vectors())
	{
		SG_ERROR("%s: Only features with equal number of vectors "
				"are currently possible\n", get_name());
	}

	init();
}

CHSIC::~CHSIC()
{

}

void CHSIC::init()
{

}

float64_t CHSIC::compute_statistic()
{
	if (!m_kernel_p || m_kernel_q)
	{
		SG_ERROR("%s::compute_statistic(): No or only one kernel specified!\n",
				get_name());
	}

	/* compute kernel matrices (these have to be stored unfortunately */
	m_kernel_p->init(m_p, m_p);
	m_kernel_q->init(m_q, m_q);

	SGMatrix<float64_t> K=m_kernel_p->get_kernel_matrix();
	SGMatrix<float64_t> L=m_kernel_p->get_kernel_matrix();

	/* center matrices (replaces this H matrix from the paper) */
	K.center();
	L.center();

	/* compute MATLAB: sum(sum((H*K)' .* (H*L))), which is biased HSIC */
	index_t m=K.num_rows;
	float64_t result=0;
	for (index_t i=0; i<m; ++i)
	{
		for (index_t j=0; j<m; ++j)
			result+=K(j,i)*L(i,j);
	}

	result/=m*m;

	return result;
}

float64_t CHSIC::compute_p_value(float64_t statistic)
{
	return 0;
}

float64_t CHSIC::compute_threshold(float64_t alpha)
{
	return 0;
}
<commit_msg>fixed errors in computing statistic<commit_after>/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2012 Heiko Strathmann
 */

#include <shogun/statistics/HSIC.h>
#include <shogun/features/Features.h>
#include <shogun/mathematics/Statistics.h>
#include <shogun/kernel/Kernel.h>

using namespace shogun;

CHSIC::CHSIC() : CKernelIndependenceTestStatistic()
{
	init();
}

CHSIC::CHSIC(CKernel* kernel_p, CKernel* kernel_q, CFeatures* p,CFeatures* q) :
		CKernelIndependenceTestStatistic(kernel_p, kernel_q, p, q)
{
	if (p->get_num_vectors()!=q->get_num_vectors())
	{
		SG_ERROR("%s: Only features with equal number of vectors "
				"are currently possible\n", get_name());
	}

	init();
}

CHSIC::~CHSIC()
{

}

void CHSIC::init()
{

}

float64_t CHSIC::compute_statistic()
{
	if (!m_kernel_p || !m_kernel_q)
	{
		SG_ERROR("%s::compute_statistic(): No or only one kernel specified!\n",
				get_name());
	}

	/* compute kernel matrices (these have to be stored unfortunately */
	m_kernel_p->init(m_p, m_p);
	m_kernel_q->init(m_q, m_q);

	SGMatrix<float64_t> K=m_kernel_p->get_kernel_matrix();
	SGMatrix<float64_t> L=m_kernel_q->get_kernel_matrix();

	/* center matrices (MATLAB: Kc=H*K*H) */
	K.center();

	/* compute MATLAB: sum(sum(Kc' .* (L))), which is biased HSIC */
	index_t m=K.num_rows;
	float64_t result=0;
	for (index_t i=0; i<m; ++i)
	{
		for (index_t j=0; j<m; ++j)
			result+=K(j,i)*L(i,j);
	}

	result/=m*m;

	return result;
}

float64_t CHSIC::compute_p_value(float64_t statistic)
{
	return 0;
}

float64_t CHSIC::compute_threshold(float64_t alpha)
{
	return 0;
}
<|endoftext|>


<commit_before>#ifdef HAVE_CMAKE_CONFIG
  #include "cmake_config.h"
#elif defined (HAVE_CONFIG_H)
  #include "config.h"
#endif

#include <memory>

#include <dune/common/exceptions.hh>
#include <dune/common/mpihelper.hh>
#include <dune/common/timer.hh>

#include <dune/fem/misc/mpimanager.hh>
#include <dune/fem/misc/gridwidth.hh>

#include <dune/grid/part/leaf.hh>

#include <dune/stuff/common/parameter/tree.hh>
#include <dune/stuff/common/logging.hh>
#include <dune/stuff/grid/provider.hh>
#include <dune/stuff/grid/boundaryinfo.hh>
#include <dune/stuff/common/vector.hh>

#include <dune/detailed-solvers/linearelliptic/model.hh>

namespace Stuff = Dune::Stuff;
namespace Elliptic = Dune::DetailedSolvers::LinearElliptic;

static const int polOrder = 1;
static const int maxParamDim = 50;
typedef Stuff::GridProviderInterface<>            GridProviderType;
typedef Stuff::GridProviders<>                    GridProviders;
typedef GridProviderType::GridType                GridType;
typedef Dune::grid::Part::Leaf::Const< GridType > GridPartType;
typedef Stuff::GridboundaryInterface< typename GridPartType::GridViewType > GridboundariesType;
typedef Stuff::Gridboundaries< typename GridPartType::GridViewType >        Gridboundaries;
typedef GridPartType::ctype                                                               DomainFieldType;
static const int DUNE_UNUSED(                                                             dimDomain) = GridProviderType::dim;
typedef double                                                                            RangeFieldType;
static const int DUNE_UNUSED(                                                             dimRange) = 1;
typedef Elliptic::ModelInterface< DomainFieldType, dimDomain, RangeFieldType, dimRange >  ModelType;
typedef Elliptic::Models< DomainFieldType, dimDomain, RangeFieldType, dimRange >          Models;
typedef Stuff::Common::ExtendedParameterTree DescriptionType;

class Problem
{
public:
  static void writeDescriptionFile(const std::string filename, const std::string _id = id())
  {
    std::ofstream file;
    file.open(filename);
    file << "[" << _id << "]" << std::endl;
    writeKeysToFile("gridprovider", GridProviders::available(), file);
    writeKeysToFile("boundaryinfo", Gridboundaries::available(), file);
    writeKeysToFile("model", Models::available(), file);
    file << "[logging]" << std::endl;
    file << "info  = true" << std::endl;
    file << "debug = true" << std::endl;
    file << "file  = false" << std::endl;
    file << "[parameter]" << std::endl;
    file << "test.size = 2" << std::endl;
    file << "test.0    = [0.1; 0.1]" << std::endl;
    file << "test.1    = [1.0; 1.0]" << std::endl;
    file << "[linearsolver]" << std::endl;
    file << "type      = bicgstab.ilut" << std::endl;
    file << "            bicgstab.diagonal" << std::endl;
    file << "precision = 1e-12"  << std::endl;
    file << "maxIter   = 5000"  << std::endl;
    writeDescriptionsToFile< GridProviders >(file);
    writeDescriptionsToFile< Gridboundaries >(file);
    writeDescriptionsToFile< Models >(file);
    file.close();
  } // void writeParamFile(const std::string filename)

  Problem(int argc, char** argv)
  {
    // mpi
    Dune::MPIManager::initialize(argc, argv);

    // parameter
    const std::string descriptionFilename = id() + ".description";
    description_ = DescriptionType(argc, argv, descriptionFilename);
    description_.assertSub(id());
    filename_ = description_.get(id() + ".filename", id());

    // logger
    const DescriptionType& logDescription = description_.sub("logging");
    int logFlags = Stuff::Common::LOG_CONSOLE;
    debugLogging_ = logDescription.get< bool >("debug", false);
    if (logDescription.get< bool >("info"))
      logFlags = logFlags | Stuff::Common::LOG_INFO;
    if (debugLogging_)
      logFlags = logFlags | Stuff::Common::LOG_DEBUG;
    if (logDescription.get< bool >("file", false))
      logFlags = logFlags | Stuff::Common::LOG_FILE;
    Stuff::Common::Logger().create(logFlags, id(), "", "");
    Stuff::Common::LogStream& info  = Stuff::Common::Logger().info();

    Dune::Timer timer;

    const std::string griproviderType = description_.get< std::string >(id() + ".gridprovider");
    info << "setting up grid with '" << griproviderType << "': " << std::endl;
    const std::shared_ptr< const GridProviderType > gridProvider(GridProviders::create(griproviderType, description_));
    grid_ = gridProvider->grid();
    const std::shared_ptr< const GridPartType > gridPart(new GridPartType(*grid_));
    info << "  done (took " << timer.elapsed()
         << " sec, has " << grid_->size(0) << " element";
    if (grid_->size(0) > 1)
      info << "s";
    info << " and a width of "
         << Dune::GridWidth::calcGridWidth(*gridPart) << ")" << std::endl;

    const std::string gridbboundaryType = description_.get< std::string >(id() + ".boundaryinfo");
    info << "setting up gridbboundary '" << gridbboundaryType << "'... " << std::flush;
    timer.reset();
    boundaryInfo_ = std::shared_ptr< const GridboundariesType >(Gridboundaries::create(gridbboundaryType,
                                                                                description_));
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "visualizing grid... " << std::flush;
    timer.reset();
    gridProvider->visualize(gridbboundaryType, description_, filename_ + ".grid");
    info << " done (took " << timer.elapsed() << " sek)" << std::endl;

    info << "setting up model";
    const std::string modelType = description_.get< std::string >(id() + ".model");
    if (!debugLogging_)
      info << "... ";
    else {
      info << ":" << std::endl;
      info << "  '" << modelType << "'... ";
    }
    info << std::flush;
    timer.reset();
    model_ = std::shared_ptr< const ModelType >(Models::create(modelType, description_));
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;
    info << "visualizing model... " << std::flush;
    timer.reset();
    model_->visualize(gridPart->gridView(), filename_ + ".model");
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;
  } // Problem

  std::string filename() const
  {
    return filename_;
  }

  const DescriptionType& description() const
  {
    return description_;
  }

  bool debugLogging() const
  {
    return debugLogging_;
  }

  std::shared_ptr< const GridType > grid() const
  {
    return grid_;
  }

  std::shared_ptr< const GridboundariesType > boundaryInfo() const
  {
    return boundaryInfo_;
  }

  std::shared_ptr< const ModelType > model() const
  {
    return model_;
  }

private:
  static void writeKeysToFile(const std::string name,
             const std::vector< std::string > keys,
             std::ofstream& file)
  {
    std::string whitespace = Stuff::Common::whitespaceify(name + " = ");
    file << name << " = " << keys[0] << std::endl;
    for (size_t ii = 1; ii < keys.size(); ++ii)
      file << whitespace << keys[ii] << std::endl;
  }

  template< class DescriptionProvider >
  static void writeDescriptionsToFile(std::ofstream& file)
  {
    for (auto type : DescriptionProvider::available()) {
      const Stuff::Common::ExtendedParameterTree& description = DescriptionProvider::createSampleDescription(type, type);
      description.reportNicely(file);
    }
  }

  std::string filename_;
  DescriptionType description_;
  bool debugLogging_;
  std::shared_ptr< const GridType > grid_;
  std::shared_ptr< const GridboundariesType > boundaryInfo_;
  std::shared_ptr< const ModelType > model_;
}; // class Problem
<commit_msg>[examples.linearelliptic.problem] GridType is now template parameter<commit_after>#include <memory>

#include <dune/common/exceptions.hh>
#include <dune/common/mpihelper.hh>
#include <dune/common/timer.hh>

#include <dune/fem/misc/mpimanager.hh>
#include <dune/fem/misc/gridwidth.hh>

#include <dune/grid/part/leaf.hh>

#include <dune/stuff/common/parameter/tree.hh>
#include <dune/stuff/common/logging.hh>
#include <dune/stuff/grid/provider.hh>
#include <dune/stuff/grid/boundaryinfo.hh>
#include <dune/stuff/common/vector.hh>

#include <dune/detailed-solvers/linearelliptic/model.hh>

#if defined HAVE_CONFIG_H || defined HAVE_CMAKE_CONFIG
template< class GridImp = Dune::GridSelector::GridType >
#else
template< class GridImp = Dune::SGrid< 2, 2 > >
#endif
class Problem
{
public:
  typedef GridImp                                         GridType;
  typedef Dune::Stuff::GridProviderInterface< GridType >  GridProviderType;
  typedef Dune::Stuff::GridProviders< GridType >          GridProviders;
  typedef Dune::grid::Part::Leaf::Const< GridType >       GridPartType;
  typedef Dune::Stuff::GridboundaryInterface< typename GridPartType::GridViewType > GridboundariesType;
  typedef Dune::Stuff::Gridboundaries< typename GridPartType::GridViewType >        Gridboundaries;
  typedef typename GridPartType::ctype   DomainFieldType;
  static const int DUNE_UNUSED( dimDomain) = GridProviderType::dim;
  typedef double                RangeFieldType;
  static const int DUNE_UNUSED( dimRange) = 1;
  typedef Dune::DetailedSolvers::LinearElliptic::ModelInterface< DomainFieldType, dimDomain, RangeFieldType, dimRange >  ModelType;
  typedef Dune::DetailedSolvers::LinearElliptic::Models< DomainFieldType, dimDomain, RangeFieldType, dimRange >          Models;
  typedef Dune::Stuff::Common::ExtendedParameterTree DescriptionType;

  static void writeDescriptionFile(const std::string filename, const std::string _id = id())
  {
    std::ofstream file;
    file.open(filename);
    file << "[" << _id << "]" << std::endl;
    writeKeysToFile("gridprovider", GridProviders::available(), file);
    writeKeysToFile("boundaryinfo", Gridboundaries::available(), file);
    writeKeysToFile("model", Models::available(), file);
    file << "[logging]" << std::endl;
    file << "info  = true" << std::endl;
    file << "debug = true" << std::endl;
    file << "file  = false" << std::endl;
    file << "[parameter]" << std::endl;
    file << "test.size = 2" << std::endl;
    file << "test.0    = [0.1; 0.1]" << std::endl;
    file << "test.1    = [1.0; 1.0]" << std::endl;
    file << "[linearsolver]" << std::endl;
    file << "type      = bicgstab.ilut" << std::endl;
    file << "            bicgstab.diagonal" << std::endl;
    file << "precision = 1e-12"  << std::endl;
    file << "maxIter   = 5000"  << std::endl;
    writeDescriptionsToFile< GridProviders >(file);
    writeDescriptionsToFile< Gridboundaries >(file);
    writeDescriptionsToFile< Models >(file);
    file.close();
  } // ... writeDescriptionFile(...)

  Problem(int argc, char** argv)
  {
    // mpi
    Dune::MPIManager::initialize(argc, argv);

    // parameter
    const std::string descriptionFilename = id() + ".description";
    description_ = DescriptionType(argc, argv, descriptionFilename);
    description_.assertSub(id());
    filename_ = description_.get(id() + ".filename", id());

    // logger
    const DescriptionType& logDescription = description_.sub("logging");
    int logFlags = Dune::Stuff::Common::LOG_CONSOLE;
    debugLogging_ = logDescription.get< bool >("debug", false);
    if (logDescription.get< bool >("info"))
      logFlags = logFlags | Dune::Stuff::Common::LOG_INFO;
    if (debugLogging_)
      logFlags = logFlags | Dune::Stuff::Common::LOG_DEBUG;
    if (logDescription.get< bool >("file", false))
      logFlags = logFlags | Dune::Stuff::Common::LOG_FILE;
    Dune::Stuff::Common::Logger().create(logFlags, id(), "", "");
    Dune::Stuff::Common::LogStream& info  = Dune::Stuff::Common::Logger().info();

    Dune::Timer timer;

    const std::string griproviderType = description_.get< std::string >(id() + ".gridprovider");
    info << "setting up grid with '" << griproviderType << "': " << std::endl;
    const std::shared_ptr< const GridProviderType > gridProvider(GridProviders::create(griproviderType, description_));
    grid_ = gridProvider->grid();
    const std::shared_ptr< const GridPartType > gridPart(new GridPartType(*grid_));
    info << "  done (took " << timer.elapsed()
         << " sec, has " << grid_->size(0) << " element";
    if (grid_->size(0) > 1)
      info << "s";
    info << " and a width of "
         << Dune::GridWidth::calcGridWidth(*gridPart) << ")" << std::endl;

    const std::string gridbboundaryType = description_.get< std::string >(id() + ".boundaryinfo");
    info << "setting up gridbboundary '" << gridbboundaryType << "'... " << std::flush;
    timer.reset();
    boundaryInfo_ = std::shared_ptr< const GridboundariesType >(Gridboundaries::create(gridbboundaryType,
                                                                                description_));
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;

    info << "visualizing grid... " << std::flush;
    timer.reset();
    gridProvider->visualize(gridbboundaryType, description_, filename_ + ".grid");
    info << " done (took " << timer.elapsed() << " sek)" << std::endl;

    info << "setting up model";
    const std::string modelType = description_.get< std::string >(id() + ".model");
    if (!debugLogging_)
      info << "... ";
    else {
      info << ":" << std::endl;
      info << "  '" << modelType << "'... ";
    }
    info << std::flush;
    timer.reset();
    model_ = std::shared_ptr< const ModelType >(Models::create(modelType, description_));
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;
    info << "visualizing model... " << std::flush;
    timer.reset();
    model_->visualize(gridPart->gridView(), filename_ + ".model");
    info << "done (took " << timer.elapsed() << " sec)" << std::endl;
  } // Problem

  std::string filename() const
  {
    return filename_;
  }

  const DescriptionType& description() const
  {
    return description_;
  }

  bool debugLogging() const
  {
    return debugLogging_;
  }

  std::shared_ptr< const GridType > grid() const
  {
    return grid_;
  }

  std::shared_ptr< const GridboundariesType > boundaryInfo() const
  {
    return boundaryInfo_;
  }

  std::shared_ptr< const ModelType > model() const
  {
    return model_;
  }

private:
  static void writeKeysToFile(const std::string name,
             const std::vector< std::string > keys,
             std::ofstream& file)
  {
    std::string whitespace = Dune::Stuff::Common::whitespaceify(name + " = ");
    file << name << " = " << keys[0] << std::endl;
    for (size_t ii = 1; ii < keys.size(); ++ii)
      file << whitespace << keys[ii] << std::endl;
  }

  template< class DescriptionProvider >
  static void writeDescriptionsToFile(std::ofstream& file)
  {
    for (auto type : DescriptionProvider::available()) {
      const Dune::Stuff::Common::ExtendedParameterTree& description = DescriptionProvider::createSampleDescription(type, type);
      description.reportNicely(file);
    }
  }

  std::string filename_;
  DescriptionType description_;
  bool debugLogging_;
  std::shared_ptr< const GridType > grid_;
  std::shared_ptr< const GridboundariesType > boundaryInfo_;
  std::shared_ptr< const ModelType > model_;
}; // class Problem
<|endoftext|>


<commit_before><commit_msg>Additional unit test for sorting.<commit_after><|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <errno.h>
#include <signal.h>
#include <stdio.h> // For perror.
#include <string.h>

#include <map>
#include <set>

#include <process/clock.hpp>
#include <process/defer.hpp>
#include <process/dispatch.hpp>
#include <process/id.hpp>

#include <stout/check.hpp>
#include <stout/exit.hpp>
#include <stout/foreach.hpp>
#include <stout/lambda.hpp>
#include <stout/nothing.hpp>
#include <stout/option.hpp>
#include <stout/os.hpp>
#include <stout/uuid.hpp>

#include "common/type_utils.hpp"

#include "slave/flags.hpp"
#include "slave/process_isolator.hpp"
#include "slave/state.hpp"

using namespace process;

using std::map;
using std::set;
using std::string;

using process::defer;
using process::wait; // Necessary on some OS's to disambiguate.

namespace mesos {
namespace internal {
namespace slave {

using launcher::ExecutorLauncher;

using state::SlaveState;
using state::FrameworkState;
using state::ExecutorState;
using state::RunState;

ProcessIsolator::ProcessIsolator()
  : ProcessBase(ID::generate("process-isolator")),
    initialized(false) {}

void ProcessIsolator::initialize(
    const Flags& _flags,
    const Resources& _,
    bool _local,
    const PID<Slave>& _slave)
{
  flags = _flags;
  local = _local;
  slave = _slave;

  initialized = true;
}

void ProcessIsolator::launchExecutor(
    const SlaveID& slaveId,
    const FrameworkID& frameworkId,
    const FrameworkInfo& frameworkInfo,
    const ExecutorInfo& executorInfo,
    const UUID& uuid,
    const string& directory,
    const Resources& resources)
{
  CHECK(initialized) << "Cannot launch executors before initialization!";

  const ExecutorID& executorId = executorInfo.executor_id();

  LOG(INFO) << "Launching " << executorId
            << " (" << executorInfo.command().value() << ")"
            << " in " << directory
            << " with resources " << resources
            << "' for framework " << frameworkId;

  ProcessInfo* info = new ProcessInfo(frameworkId, executorId);

  infos[frameworkId][executorId] = info;

  // Use pipes to determine which child has successfully changed session.
  int pipes[2];
  if (pipe(pipes) < 0) {
    PLOG(FATAL) << "Failed to create a pipe";
  }

  // Set the FD_CLOEXEC flags on these pipes
  Try<Nothing> cloexec = os::cloexec(pipes[0]);
  CHECK_SOME(cloexec) << "Error setting FD_CLOEXEC on pipe[0]";

  cloexec = os::cloexec(pipes[1]);
  CHECK_SOME(cloexec) << "Error setting FD_CLOEXEC on pipe[1]";

  // Create the ExecutorLauncher instance before the fork for the
  // child process to use.
  ExecutorLauncher launcher(
      slaveId,
      frameworkId,
      executorInfo.executor_id(),
      uuid,
      executorInfo.command(),
      frameworkInfo.user(),
      directory,
      flags.work_dir,
      slave,
      flags.frameworks_home,
      flags.hadoop_home,
      !local,
      flags.switch_user,
      frameworkInfo.checkpoint());

  // We get the environment map for launching mesos-launcher before
  // the fork, because we have seen deadlock issues with ostringstream
  // in the forked process before it calls exec.
  map<string, string> env = launcher.getLauncherEnvironment();

  pid_t pid;
  if ((pid = fork()) == -1) {
    PLOG(FATAL) << "Failed to fork to launch new executor";
  }

  if (pid > 0) {
    os::close(pipes[1]);

    // Get the child's pid via the pipe.
    if (read(pipes[0], &pid, sizeof(pid)) == -1) {
      PLOG(FATAL) << "Failed to get child PID from pipe";
    }

    os::close(pipes[0]);

    // In parent process.
    LOG(INFO) << "Forked executor at " << pid;

    // Record the pid (should also be the pgid since we setsid below).
    infos[frameworkId][executorId]->pid = pid;

    reaper.monitor(pid)
      .onAny(defer(PID<ProcessIsolator>(this),
                   &ProcessIsolator::reaped,
                   pid,
                   lambda::_1));

    // Tell the slave this executor has started.
    dispatch(slave, &Slave::executorStarted, frameworkId, executorId, pid);
  } else {
    // In child process, we make cleanup easier by putting process
    // into it's own session. DO NOT USE GLOG!
    os::close(pipes[0]);

    // NOTE: We setsid() in a loop because setsid() might fail if another
    // process has the same process group id as the calling process.
    while ((pid = setsid()) == -1) {
      perror("Could not put executor in its own session");

      std::cout << "Forking another process and retrying ..." << std::endl;

      if ((pid = fork()) == -1) {
        perror("Failed to fork to launch executor");
        abort();
      }

      if (pid > 0) {
        // In parent process.
        // It is ok to suicide here, though process reaper signals the exit,
        // because the process isolator ignores unknown processes.
        exit(0);
      }
    }

    if (write(pipes[1], &pid, sizeof(pid)) != sizeof(pid)) {
      perror("Failed to write PID on pipe");
      abort();
    }

    os::close(pipes[1]);

    // Setup the environment for launcher.
    foreachpair (const string& key, const string& value, env) {
      os::setenv(key, value);
    }

    const char** args = (const char**) new char*[2];

    // Determine path for mesos-launcher.
    Try<string> realpath = os::realpath(
        path::join(flags.launcher_dir, "mesos-launcher"));

    if (realpath.isError()) {
      EXIT(1) << "Failed to determine the canonical path "
              << "for the mesos-launcher: " << realpath.error();
    }

    // Grab a copy of the path so that we can reliably use 'c_str()'.
    const string& path = realpath.get();

    args[0] = path.c_str();
    args[1] = NULL;

    // Execute the mesos-launcher!
    execvp(args[0], (char* const*) args);

    // If we get here, the execvp call failed.
    perror("Failed to execvp the mesos-launcher");
    abort();
  }
}

// NOTE: This function can be called by the isolator itself or by the
// slave if it doesn't hear about an executor exit after it sends a
// shutdown message.
void ProcessIsolator::killExecutor(
    const FrameworkID& frameworkId,
    const ExecutorID& executorId)
{
  CHECK(initialized) << "Cannot kill executors before initialization!";

  if (!infos.contains(frameworkId) ||
      !infos[frameworkId].contains(executorId) ||
      infos[frameworkId][executorId]->killed) {
    LOG(ERROR) << "Asked to kill an unknown/killed executor! " << executorId;
    return;
  }

  const Option<pid_t>& pid = infos[frameworkId][executorId]->pid;

  if (pid.isSome()) {
    // TODO(vinod): Call killtree on the pid of the actual executor process
    // that is running the tasks (stored in the local storage by the
    // executor module).
    os::killtree(pid.get(), SIGKILL, true, true, &LOG(INFO));

    // Also kill all processes that belong to the process group of the executor.
    // This is valuable in situations where the top level executor process
    // exited and hence killtree is unable to kill any spawned orphans.
    // NOTE: This assumes that the process group id of the executor process is
    // same as its pid (which is expected to be the case with setsid()).
    // TODO(vinod): Also (recursively) kill processes belonging to the
    // same session, but have a different process group id.
    if (killpg(pid.get(), SIGKILL) == -1 && errno != ESRCH) {
      PLOG(WARNING) << "Failed to kill process group " << pid.get();
    }

    infos[frameworkId][executorId]->killed = true;
  }
}

void ProcessIsolator::resourcesChanged(
    const FrameworkID& frameworkId,
    const ExecutorID& executorId,
    const Resources& resources)
{
  CHECK(initialized) << "Cannot do resourcesChanged before initialization!";

  if (!infos.contains(frameworkId) ||
      !infos[frameworkId].contains(executorId) ||
      infos[frameworkId][executorId]->killed) {
    LOG(INFO) << "Asked to update resources for an unknown/killed executor '"
              << executorId << "' of framework " << frameworkId;
    return;
  }

  ProcessInfo* info = CHECK_NOTNULL(infos[frameworkId][executorId]);

  info->resources = resources;

  // Do nothing; subclasses may override this.
}

Future<Nothing> ProcessIsolator::recover(
    const Option<SlaveState>& state)
{
  LOG(INFO) << "Recovering isolator";

  if (state.isNone()) {
    return Nothing();
  }

  foreachvalue (const FrameworkState& framework, state.get().frameworks) {
    foreachvalue (const ExecutorState& executor, framework.executors) {
      LOG(INFO) << "Recovering executor '" << executor.id
                << "' of framework " << framework.id;

      if (executor.info.isNone()) {
        LOG(WARNING) << "Skipping recovery of executor '" << executor.id
                     << "' of framework " << framework.id
                     << " because its info cannot be recovered";
        continue;
      }

      if (executor.latest.isNone()) {
        LOG(WARNING) << "Skipping recovery of executor '" << executor.id
                     << "' of framework " << framework.id
                     << " because its latest run cannot be recovered";
        continue;
      }

      // We are only interested in the latest run of the executor!
      const UUID& uuid = executor.latest.get();
      CHECK(executor.runs.contains(uuid));
      const RunState& run  = executor.runs.get(uuid).get();

      ProcessInfo* info =
        new ProcessInfo(framework.id, executor.id, run.forkedPid);

      infos[framework.id][executor.id] = info;

      // Add the pid to the reaper to monitor exit status.
      if (run.forkedPid.isSome()) {
        reaper.monitor(run.forkedPid.get())
          .onAny(defer(PID<ProcessIsolator>(this),
                       &ProcessIsolator::reaped,
                       run.forkedPid.get(),
                       lambda::_1));
      }
    }
  }

  return Nothing();
}

Future<ResourceStatistics> ProcessIsolator::usage(
    const FrameworkID& frameworkId,
    const ExecutorID& executorId)
{
  if (!infos.contains(frameworkId) ||
      !infos[frameworkId].contains(executorId) ||
      infos[frameworkId][executorId]->killed) {
    return Future<ResourceStatistics>::failed("Unknown/killed executor");
  }

  ProcessInfo* info = infos[frameworkId][executorId];
  CHECK_NOTNULL(info);

  ResourceStatistics result;

  result.set_timestamp(Clock::now().secs());

  // Set the resource allocations.
  const Option<Bytes>& mem = info->resources.mem();
  if (mem.isSome()) {
    result.set_mem_limit_bytes(mem.get().bytes());
  }

  const Option<double>& cpus = info->resources.cpus();
  if (cpus.isSome()) {
    result.set_cpus_limit(cpus.get());
  }

  CHECK_SOME(info->pid);

  Result<os::Process> process = os::process(info->pid.get());

  if (!process.isSome()) {
    return Future<ResourceStatistics>::failed(
        process.isError() ? process.error() : "Process does not exist");
  }

  result.set_timestamp(Clock::now().secs());
  result.set_mem_rss_bytes(process.get().rss.bytes());
  result.set_cpus_user_time_secs(process.get().utime.secs());
  result.set_cpus_system_time_secs(process.get().stime.secs());

  // Now aggregate all descendant process usage statistics.
  const Try<set<pid_t> >& children = os::children(info->pid.get(), true);

  if (children.isError()) {
    return Future<ResourceStatistics>::failed(
        "Failed to get children of " + stringify(info->pid.get()) + ": " +
        children.error());
  }

  // Aggregate the usage of all child processes.
  foreach (pid_t child, children.get()) {
    process = os::process(child);

    if (process.isError()) {
      LOG(WARNING) << "Failed to get status of descendant process " << child
                   << " of parent " << info->pid.get() << ": "
                   << process.error();
      continue;
    }

    result.set_mem_rss_bytes(
        result.mem_rss_bytes() + process.get().rss.bytes());
    result.set_cpus_user_time_secs(
        result.cpus_user_time_secs() + process.get().utime.secs());
    result.set_cpus_system_time_secs(
        result.cpus_system_time_secs() + process.get().stime.secs());
  }

  return result;
}

void ProcessIsolator::reaped(pid_t pid, const Future<Option<int> >& status)
{
  foreachkey (const FrameworkID& frameworkId, infos) {
    foreachkey (const ExecutorID& executorId, infos[frameworkId]) {
      ProcessInfo* info = infos[frameworkId][executorId];

      if (info->pid.isSome() && info->pid.get() == pid) {
        if (!status.isReady()) {
          LOG(ERROR) << "Failed to get the status for executor '" << executorId
                     << "' of framework " << frameworkId << ": "
                     << (status.isFailed() ? status.failure() : "discarded");
          return;
        }

        LOG(INFO) << "Telling slave of terminated executor '" << executorId
                  << "' of framework " << frameworkId;

        dispatch(slave,
                 &Slave::executorTerminated,
                 frameworkId,
                 executorId,
                 status.get(),
                 false,
                 "Executor terminated");

        if (!info->killed) {
          // Try and cleanup after the executor.
          killExecutor(frameworkId, executorId);
        }

        if (infos[frameworkId].size() == 1) {
          infos.erase(frameworkId);
        } else {
          infos[frameworkId].erase(executorId);
        }
        delete info;

        return;
      }
    }
  }
}

} // namespace slave {
} // namespace internal {
} // namespace mesos {
<commit_msg>Fixed a crash in the ProcessIsolator.<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <errno.h>
#include <signal.h>
#include <stdio.h> // For perror.
#include <string.h>

#include <map>
#include <set>

#include <process/clock.hpp>
#include <process/defer.hpp>
#include <process/dispatch.hpp>
#include <process/id.hpp>

#include <stout/check.hpp>
#include <stout/exit.hpp>
#include <stout/foreach.hpp>
#include <stout/lambda.hpp>
#include <stout/nothing.hpp>
#include <stout/option.hpp>
#include <stout/os.hpp>
#include <stout/uuid.hpp>

#include "common/type_utils.hpp"

#include "slave/flags.hpp"
#include "slave/process_isolator.hpp"
#include "slave/state.hpp"

using namespace process;

using std::map;
using std::set;
using std::string;

using process::defer;
using process::wait; // Necessary on some OS's to disambiguate.

namespace mesos {
namespace internal {
namespace slave {

using launcher::ExecutorLauncher;

using state::SlaveState;
using state::FrameworkState;
using state::ExecutorState;
using state::RunState;

ProcessIsolator::ProcessIsolator()
  : ProcessBase(ID::generate("process-isolator")),
    initialized(false) {}

void ProcessIsolator::initialize(
    const Flags& _flags,
    const Resources& _,
    bool _local,
    const PID<Slave>& _slave)
{
  flags = _flags;
  local = _local;
  slave = _slave;

  initialized = true;
}

void ProcessIsolator::launchExecutor(
    const SlaveID& slaveId,
    const FrameworkID& frameworkId,
    const FrameworkInfo& frameworkInfo,
    const ExecutorInfo& executorInfo,
    const UUID& uuid,
    const string& directory,
    const Resources& resources)
{
  CHECK(initialized) << "Cannot launch executors before initialization!";

  const ExecutorID& executorId = executorInfo.executor_id();

  LOG(INFO) << "Launching " << executorId
            << " (" << executorInfo.command().value() << ")"
            << " in " << directory
            << " with resources " << resources
            << "' for framework " << frameworkId;

  ProcessInfo* info = new ProcessInfo(frameworkId, executorId);

  infos[frameworkId][executorId] = info;

  // Use pipes to determine which child has successfully changed session.
  int pipes[2];
  if (pipe(pipes) < 0) {
    PLOG(FATAL) << "Failed to create a pipe";
  }

  // Set the FD_CLOEXEC flags on these pipes
  Try<Nothing> cloexec = os::cloexec(pipes[0]);
  CHECK_SOME(cloexec) << "Error setting FD_CLOEXEC on pipe[0]";

  cloexec = os::cloexec(pipes[1]);
  CHECK_SOME(cloexec) << "Error setting FD_CLOEXEC on pipe[1]";

  // Create the ExecutorLauncher instance before the fork for the
  // child process to use.
  ExecutorLauncher launcher(
      slaveId,
      frameworkId,
      executorInfo.executor_id(),
      uuid,
      executorInfo.command(),
      frameworkInfo.user(),
      directory,
      flags.work_dir,
      slave,
      flags.frameworks_home,
      flags.hadoop_home,
      !local,
      flags.switch_user,
      frameworkInfo.checkpoint());

  // We get the environment map for launching mesos-launcher before
  // the fork, because we have seen deadlock issues with ostringstream
  // in the forked process before it calls exec.
  map<string, string> env = launcher.getLauncherEnvironment();

  pid_t pid;
  if ((pid = fork()) == -1) {
    PLOG(FATAL) << "Failed to fork to launch new executor";
  }

  if (pid > 0) {
    os::close(pipes[1]);

    // Get the child's pid via the pipe.
    if (read(pipes[0], &pid, sizeof(pid)) == -1) {
      PLOG(FATAL) << "Failed to get child PID from pipe";
    }

    os::close(pipes[0]);

    // In parent process.
    LOG(INFO) << "Forked executor at " << pid;

    // Record the pid (should also be the pgid since we setsid below).
    infos[frameworkId][executorId]->pid = pid;

    reaper.monitor(pid)
      .onAny(defer(PID<ProcessIsolator>(this),
                   &ProcessIsolator::reaped,
                   pid,
                   lambda::_1));

    // Tell the slave this executor has started.
    dispatch(slave, &Slave::executorStarted, frameworkId, executorId, pid);
  } else {
    // In child process, we make cleanup easier by putting process
    // into it's own session. DO NOT USE GLOG!
    os::close(pipes[0]);

    // NOTE: We setsid() in a loop because setsid() might fail if another
    // process has the same process group id as the calling process.
    while ((pid = setsid()) == -1) {
      perror("Could not put executor in its own session");

      std::cout << "Forking another process and retrying ..." << std::endl;

      if ((pid = fork()) == -1) {
        perror("Failed to fork to launch executor");
        abort();
      }

      if (pid > 0) {
        // In parent process.
        // It is ok to suicide here, though process reaper signals the exit,
        // because the process isolator ignores unknown processes.
        exit(0);
      }
    }

    if (write(pipes[1], &pid, sizeof(pid)) != sizeof(pid)) {
      perror("Failed to write PID on pipe");
      abort();
    }

    os::close(pipes[1]);

    // Setup the environment for launcher.
    foreachpair (const string& key, const string& value, env) {
      os::setenv(key, value);
    }

    const char** args = (const char**) new char*[2];

    // Determine path for mesos-launcher.
    Try<string> realpath = os::realpath(
        path::join(flags.launcher_dir, "mesos-launcher"));

    if (realpath.isError()) {
      EXIT(1) << "Failed to determine the canonical path "
              << "for the mesos-launcher: " << realpath.error();
    }

    // Grab a copy of the path so that we can reliably use 'c_str()'.
    const string& path = realpath.get();

    args[0] = path.c_str();
    args[1] = NULL;

    // Execute the mesos-launcher!
    execvp(args[0], (char* const*) args);

    // If we get here, the execvp call failed.
    perror("Failed to execvp the mesos-launcher");
    abort();
  }
}

// NOTE: This function can be called by the isolator itself or by the
// slave if it doesn't hear about an executor exit after it sends a
// shutdown message.
void ProcessIsolator::killExecutor(
    const FrameworkID& frameworkId,
    const ExecutorID& executorId)
{
  CHECK(initialized) << "Cannot kill executors before initialization!";

  if (!infos.contains(frameworkId) ||
      !infos[frameworkId].contains(executorId) ||
      infos[frameworkId][executorId]->killed) {
    LOG(ERROR) << "Asked to kill an unknown/killed executor! " << executorId;
    return;
  }

  const Option<pid_t>& pid = infos[frameworkId][executorId]->pid;

  if (pid.isSome()) {
    // TODO(vinod): Call killtree on the pid of the actual executor process
    // that is running the tasks (stored in the local storage by the
    // executor module).
    os::killtree(pid.get(), SIGKILL, true, true, &LOG(INFO));

    // Also kill all processes that belong to the process group of the executor.
    // This is valuable in situations where the top level executor process
    // exited and hence killtree is unable to kill any spawned orphans.
    // NOTE: This assumes that the process group id of the executor process is
    // same as its pid (which is expected to be the case with setsid()).
    // TODO(vinod): Also (recursively) kill processes belonging to the
    // same session, but have a different process group id.
    if (killpg(pid.get(), SIGKILL) == -1 && errno != ESRCH) {
      PLOG(WARNING) << "Failed to kill process group " << pid.get();
    }

    infos[frameworkId][executorId]->killed = true;
  }
}

void ProcessIsolator::resourcesChanged(
    const FrameworkID& frameworkId,
    const ExecutorID& executorId,
    const Resources& resources)
{
  CHECK(initialized) << "Cannot do resourcesChanged before initialization!";

  if (!infos.contains(frameworkId) ||
      !infos[frameworkId].contains(executorId) ||
      infos[frameworkId][executorId]->killed) {
    LOG(INFO) << "Asked to update resources for an unknown/killed executor '"
              << executorId << "' of framework " << frameworkId;
    return;
  }

  ProcessInfo* info = CHECK_NOTNULL(infos[frameworkId][executorId]);

  info->resources = resources;

  // Do nothing; subclasses may override this.
}

Future<Nothing> ProcessIsolator::recover(
    const Option<SlaveState>& state)
{
  LOG(INFO) << "Recovering isolator";

  if (state.isNone()) {
    return Nothing();
  }

  foreachvalue (const FrameworkState& framework, state.get().frameworks) {
    foreachvalue (const ExecutorState& executor, framework.executors) {
      LOG(INFO) << "Recovering executor '" << executor.id
                << "' of framework " << framework.id;

      if (executor.info.isNone()) {
        LOG(WARNING) << "Skipping recovery of executor '" << executor.id
                     << "' of framework " << framework.id
                     << " because its info cannot be recovered";
        continue;
      }

      if (executor.latest.isNone()) {
        LOG(WARNING) << "Skipping recovery of executor '" << executor.id
                     << "' of framework " << framework.id
                     << " because its latest run cannot be recovered";
        continue;
      }

      // We are only interested in the latest run of the executor!
      const UUID& uuid = executor.latest.get();
      CHECK(executor.runs.contains(uuid));
      const RunState& run  = executor.runs.get(uuid).get();

      ProcessInfo* info =
        new ProcessInfo(framework.id, executor.id, run.forkedPid);

      infos[framework.id][executor.id] = info;

      // Add the pid to the reaper to monitor exit status.
      if (run.forkedPid.isSome()) {
        reaper.monitor(run.forkedPid.get())
          .onAny(defer(PID<ProcessIsolator>(this),
                       &ProcessIsolator::reaped,
                       run.forkedPid.get(),
                       lambda::_1));
      }
    }
  }

  return Nothing();
}

Future<ResourceStatistics> ProcessIsolator::usage(
    const FrameworkID& frameworkId,
    const ExecutorID& executorId)
{
  if (!infos.contains(frameworkId) ||
      !infos[frameworkId].contains(executorId) ||
      infos[frameworkId][executorId]->killed) {
    return Future<ResourceStatistics>::failed("Unknown/killed executor");
  }

  ProcessInfo* info = infos[frameworkId][executorId];
  CHECK_NOTNULL(info);

  ResourceStatistics result;

  result.set_timestamp(Clock::now().secs());

  // Set the resource allocations.
  const Option<Bytes>& mem = info->resources.mem();
  if (mem.isSome()) {
    result.set_mem_limit_bytes(mem.get().bytes());
  }

  const Option<double>& cpus = info->resources.cpus();
  if (cpus.isSome()) {
    result.set_cpus_limit(cpus.get());
  }

  CHECK_SOME(info->pid);

  Result<os::Process> process = os::process(info->pid.get());

  if (!process.isSome()) {
    return Future<ResourceStatistics>::failed(
        process.isError() ? process.error() : "Process does not exist");
  }

  result.set_timestamp(Clock::now().secs());
  result.set_mem_rss_bytes(process.get().rss.bytes());
  result.set_cpus_user_time_secs(process.get().utime.secs());
  result.set_cpus_system_time_secs(process.get().stime.secs());

  // Now aggregate all descendant process usage statistics.
  const Try<set<pid_t> >& children = os::children(info->pid.get(), true);

  if (children.isError()) {
    return Future<ResourceStatistics>::failed(
        "Failed to get children of " + stringify(info->pid.get()) + ": " +
        children.error());
  }

  // Aggregate the usage of all child processes.
  foreach (pid_t child, children.get()) {
    process = os::process(child);

    // Skip processes that disappear.
    if (process.isNone()) {
      continue;
    }

    if (process.isError()) {
      LOG(WARNING) << "Failed to get status of descendant process " << child
                   << " of parent " << info->pid.get() << ": "
                   << process.error();
      continue;
    }

    result.set_mem_rss_bytes(
        result.mem_rss_bytes() + process.get().rss.bytes());
    result.set_cpus_user_time_secs(
        result.cpus_user_time_secs() + process.get().utime.secs());
    result.set_cpus_system_time_secs(
        result.cpus_system_time_secs() + process.get().stime.secs());
  }

  return result;
}

void ProcessIsolator::reaped(pid_t pid, const Future<Option<int> >& status)
{
  foreachkey (const FrameworkID& frameworkId, infos) {
    foreachkey (const ExecutorID& executorId, infos[frameworkId]) {
      ProcessInfo* info = infos[frameworkId][executorId];

      if (info->pid.isSome() && info->pid.get() == pid) {
        if (!status.isReady()) {
          LOG(ERROR) << "Failed to get the status for executor '" << executorId
                     << "' of framework " << frameworkId << ": "
                     << (status.isFailed() ? status.failure() : "discarded");
          return;
        }

        LOG(INFO) << "Telling slave of terminated executor '" << executorId
                  << "' of framework " << frameworkId;

        dispatch(slave,
                 &Slave::executorTerminated,
                 frameworkId,
                 executorId,
                 status.get(),
                 false,
                 "Executor terminated");

        if (!info->killed) {
          // Try and cleanup after the executor.
          killExecutor(frameworkId, executorId);
        }

        if (infos[frameworkId].size() == 1) {
          infos.erase(frameworkId);
        } else {
          infos[frameworkId].erase(executorId);
        }
        delete info;

        return;
      }
    }
  }
}

} // namespace slave {
} // namespace internal {
} // namespace mesos {
<|endoftext|>


<commit_before>/*
  Copyright (c) 2018, 2019 Jouni Siren

  Author: Jouni Siren <jouni.siren@iki.fi>

  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 <gbwt/gbwt.h>

using namespace gbwt;

//------------------------------------------------------------------------------

const std::string tool_name = "GBWT metadata tool";

void printUsage(int exit_code = EXIT_SUCCESS);

//------------------------------------------------------------------------------

int
main(int argc, char** argv)
{
  if(argc < 2) { printUsage(); }

  int c = 0;
  bool set_samples = false, set_haplotypes = false, set_contigs = false;
  size_type new_samples = 0, new_haplotypes = 0, new_contigs = 0;
  bool clear_paths = false, clear_samples = false, clear_contigs = false;
  bool remove_metadata = false;
  while((c = getopt(argc, argv, "s:h:c:PSRr")) != -1)
  {
    switch(c)
    {
    case 's':
      set_samples = true;
      new_samples = std::stoul(optarg);
      break;
    case 'h':
      set_haplotypes = true;
      new_haplotypes = std::stoul(optarg);
      break;
    case 'c':
      set_contigs = true;
      new_contigs = std::stoul(optarg);
      break;
    case 'P':
      clear_paths = true;
      break;
    case 'S':
      clear_samples = true;
      break;
    case 'C':
      clear_contigs = true;
      break;
    case 'r':
      remove_metadata = true;
      break;
    case '?':
      std::exit(EXIT_FAILURE);
    default:
      std::exit(EXIT_FAILURE);
    }
  }

  if(optind >= argc) { printUsage(EXIT_FAILURE); }
  std::string index_base = argv[optind];

  Version::print(std::cout, tool_name);
  GBWT gbwt;
  if(!sdsl::load_from_file(gbwt, index_base + GBWT::EXTENSION))
  {
    std::cerr << "metadata: Cannot load the index from " << (index_base + GBWT::EXTENSION) << std::endl;
    std::exit(EXIT_FAILURE);
  }

  bool modified = false;
  if(clear_paths)
  {
    gbwt.metadata.clearPathNames();
    modified = true;
  }
  if(clear_samples)
  {
    gbwt.metadata.clearSampleNames();
    modified = true;
  }
  if(set_samples)
  {
    gbwt.metadata.setSamples(new_samples);
    modified = true;
  }
  if(set_haplotypes)
  {
    gbwt.metadata.setHaplotypes(new_haplotypes);
    modified = true;
  }
  if(clear_contigs)
  {
    gbwt.metadata.clearContigNames();
    modified = true;
  }
  if(set_contigs)
  {
    gbwt.metadata.setContigs(new_contigs);
    modified = true;
  }
  if(remove_metadata)
  {
    gbwt.clearMetadata();
    modified = true;
  }
  if(modified && !remove_metadata) { gbwt.addMetadata(); }

  printStatistics(gbwt, index_base);
  if(modified)
  {
    if(!sdsl::store_to_file(gbwt, index_base + GBWT::EXTENSION))
    {
      std::cerr << "metadata: Cannot write the index to " << (index_base + GBWT::EXTENSION) << std::endl;
      std::exit(EXIT_FAILURE);
    }
  }

  return 0;
}

//------------------------------------------------------------------------------

void
printUsage(int exit_code)
{
  Version::print(std::cerr, tool_name);

  std::cerr << "Usage: metadata [options] basename" << std::endl;
  std::cerr << "  -s N  Set the number of samples to N" << std::endl;
  std::cerr << "  -h N  Set the number of haplotypes to N" << std::endl;
  std::cerr << "  -c N  Set the number of contigs to N" << std::endl;
  std::cerr << "  -P    Remove path names" << std::endl;
  std::cerr << "  -S    Remove sample names" << std::endl;
  std::cerr << "  -C    Remove contig names" << std::endl;
  std::cerr << "  -r    Remove all metadata" << std::endl;
  std::cerr << std::endl;

  std::exit(exit_code);
}

//------------------------------------------------------------------------------
<commit_msg>metadata_tool options<commit_after>/*
  Copyright (c) 2018, 2019 Jouni Siren

  Author: Jouni Siren <jouni.siren@iki.fi>

  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 <gbwt/gbwt.h>

using namespace gbwt;

//------------------------------------------------------------------------------

const std::string tool_name = "GBWT metadata tool";

void printUsage(int exit_code = EXIT_SUCCESS);

//------------------------------------------------------------------------------

int
main(int argc, char** argv)
{
  if(argc < 2) { printUsage(); }

  int c = 0;
  bool set_samples = false, set_haplotypes = false, set_contigs = false;
  size_type new_samples = 0, new_haplotypes = 0, new_contigs = 0;
  bool clear_paths = false, clear_samples = false, clear_contigs = false;
  bool remove_metadata = false;
  while((c = getopt(argc, argv, "s:h:c:PSCr")) != -1)
  {
    switch(c)
    {
    case 's':
      set_samples = true;
      new_samples = std::stoul(optarg);
      break;
    case 'h':
      set_haplotypes = true;
      new_haplotypes = std::stoul(optarg);
      break;
    case 'c':
      set_contigs = true;
      new_contigs = std::stoul(optarg);
      break;
    case 'P':
      clear_paths = true;
      break;
    case 'S':
      clear_samples = true;
      break;
    case 'C':
      clear_contigs = true;
      break;
    case 'r':
      remove_metadata = true;
      break;
    case '?':
      std::exit(EXIT_FAILURE);
    default:
      std::exit(EXIT_FAILURE);
    }
  }

  if(optind >= argc) { printUsage(EXIT_FAILURE); }
  std::string index_base = argv[optind];

  Version::print(std::cout, tool_name);
  GBWT gbwt;
  if(!sdsl::load_from_file(gbwt, index_base + GBWT::EXTENSION))
  {
    std::cerr << "metadata: Cannot load the index from " << (index_base + GBWT::EXTENSION) << std::endl;
    std::exit(EXIT_FAILURE);
  }

  bool modified = false;
  if(clear_paths)
  {
    gbwt.metadata.clearPathNames();
    modified = true;
  }
  if(clear_samples)
  {
    gbwt.metadata.clearSampleNames();
    modified = true;
  }
  if(set_samples)
  {
    gbwt.metadata.setSamples(new_samples);
    modified = true;
  }
  if(set_haplotypes)
  {
    gbwt.metadata.setHaplotypes(new_haplotypes);
    modified = true;
  }
  if(clear_contigs)
  {
    gbwt.metadata.clearContigNames();
    modified = true;
  }
  if(set_contigs)
  {
    gbwt.metadata.setContigs(new_contigs);
    modified = true;
  }
  if(remove_metadata)
  {
    gbwt.clearMetadata();
    modified = true;
  }
  if(modified && !remove_metadata) { gbwt.addMetadata(); }

  printStatistics(gbwt, index_base);
  if(modified)
  {
    if(!sdsl::store_to_file(gbwt, index_base + GBWT::EXTENSION))
    {
      std::cerr << "metadata: Cannot write the index to " << (index_base + GBWT::EXTENSION) << std::endl;
      std::exit(EXIT_FAILURE);
    }
  }

  return 0;
}

//------------------------------------------------------------------------------

void
printUsage(int exit_code)
{
  Version::print(std::cerr, tool_name);

  std::cerr << "Usage: metadata [options] basename" << std::endl;
  std::cerr << "  -s N  Set the number of samples to N" << std::endl;
  std::cerr << "  -h N  Set the number of haplotypes to N" << std::endl;
  std::cerr << "  -c N  Set the number of contigs to N" << std::endl;
  std::cerr << "  -P    Remove path names" << std::endl;
  std::cerr << "  -S    Remove sample names" << std::endl;
  std::cerr << "  -C    Remove contig names" << std::endl;
  std::cerr << "  -r    Remove all metadata" << std::endl;
  std::cerr << std::endl;

  std::exit(exit_code);
}

//------------------------------------------------------------------------------
<|endoftext|>


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

#ifdef BOARD_xsim
static int numWords = 0x5000/4;
static int iterCnt = 1;
#elif defined(SIMULATION)
static int numWords = 4096;
static int iterCnt = 8;
#else
static int numWords = 0x1240000/4; // make sure to allocate at least one entry of each size
static int iterCnt = 8;
#endif
#ifdef PCIE
static int burstLen = 32;
static int burstLenMin = 32;
static int burstLenMax = 32;
#else
static int burstLen = 16;
static int burstLenMin = 2;
static int burstLenMax = 32;
#endif

#ifdef NumEngineServers
int numEngineServers = NumEngineServers;
#else
int numEngineServers = 1;
#endif

static sem_t test_sem;
static size_t alloc_sz = numWords*sizeof(unsigned int);

class MemwriteIndication : public MemwriteIndicationWrapper
{
public:
    MemwriteIndication(int id, int tile=DEFAULT_TILE) : MemwriteIndicationWrapper(id,tile) {}
    void started(uint32_t words) {
        fprintf(stderr, "Memwrite::started: words=%x\n", words);
    }
    void writeDone ( uint32_t srcGen ) {
        fprintf(stderr, "Memwrite::writeDone (%08x)\n", srcGen);
        sem_post(&test_sem);
    }
    void reportStateDbg(uint32_t streamWrCnt, uint32_t srcGen) {
        fprintf(stderr, "Memwrite::reportStateDbg: streamWrCnt=%08x srcGen=%d\n", streamWrCnt, srcGen);
    }
};

int main(int argc, const char **argv)
{
    int mismatch = 0;
    uint32_t sg = 0;
    int max_error = 10;

    if (sem_init(&test_sem, 1, 0)) {
        fprintf(stderr, "error: failed to init test_sem\n");
        exit(1);
    }
    fprintf(stderr, "testmemwrite: start %s %s\n", __DATE__, __TIME__);
    DmaManager *dma = platformInit();
    MemwriteRequestProxy *device = new MemwriteRequestProxy(IfcNames_MemwriteRequestS2H);
    MemwriteIndication deviceIndication(IfcNames_MemwriteIndicationH2S);

    alloc_sz *= numEngineServers;

    fprintf(stderr, "main::allocating %lx bytes of memory...\n", (long)alloc_sz);
    int dstAlloc = portalAlloc(alloc_sz, 0);
    unsigned int *dstBuffer = (unsigned int *)portalMmap(dstAlloc, alloc_sz);
#ifdef FPGA0_CLOCK_FREQ
    long req_freq = FPGA0_CLOCK_FREQ, freq = 0;
    setClockFrequency(0, req_freq, &freq);
    fprintf(stderr, "Requested FCLK[0]=%ld actually %ld\n", req_freq, freq);
#endif
    unsigned int ref_dstAlloc = dma->reference(dstAlloc);
    for (int i = 0; i < numWords*numEngineServers; i++)
        dstBuffer[i] = 0xDEADBEEF;
    portalCacheFlush(dstAlloc, dstBuffer, alloc_sz, 1);
    fprintf(stderr, "testmemwrite: flush and invalidate complete\n");

    burstLen = burstLenMin; // words
    while (burstLen <= burstLenMax) {
      fprintf(stderr, "testmemwrite: starting write %#08x words burstLen=%d words\n", numWords, burstLen);
      portalTimerStart(0);
      device->startWrite(ref_dstAlloc, 0, numWords, burstLen, iterCnt);
      sem_wait(&test_sem);
      mismatch = 0;
      for (int i = 0; i < numWords; i++) {
        if (dstBuffer[i] != sg) {
	  mismatch++;
	  if (max_error-- > 0)
	    fprintf(stderr, "testmemwrite: [%d] actual %08x expected %08x\n", i, dstBuffer[i], sg);
        }
        sg++;
      }
      platformStatistics();
      fprintf(stderr, "testmemwrite: mismatch count %d.\n", mismatch);
      burstLen *= 2;
      if (mismatch)
	exit(mismatch);

      // now try with larger burstLen
      burstLen *= 2;
    }
}
<commit_msg>increase burrstLenMin to 4 words (128 bits) so that memwrite128 will not hang<commit_after>/* Copyright (c) 2014 Quanta Research Cambridge, Inc
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included
 * in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */
#include "monkit.h"
#include "dmaManager.h"
#include "MemwriteIndication.h"
#include "MemwriteRequest.h"

#ifdef BOARD_xsim
static int numWords = 0x5000/4;
static int iterCnt = 1;
#elif defined(SIMULATION)
static int numWords = 4096;
static int iterCnt = 8;
#else
static int numWords = 0x1240000/4; // make sure to allocate at least one entry of each size
static int iterCnt = 8;
#endif
#ifdef PCIE
static int burstLen = 32;
static int burstLenMin = 32;
static int burstLenMax = 32;
#else
static int burstLen = 16;
static int burstLenMin = 4;
static int burstLenMax = 32;
#endif

#ifdef NumEngineServers
int numEngineServers = NumEngineServers;
#else
int numEngineServers = 1;
#endif

static sem_t test_sem;
static size_t alloc_sz = numWords*sizeof(unsigned int);

class MemwriteIndication : public MemwriteIndicationWrapper
{
public:
    MemwriteIndication(int id, int tile=DEFAULT_TILE) : MemwriteIndicationWrapper(id,tile) {}
    void started(uint32_t words) {
        fprintf(stderr, "Memwrite::started: words=%x\n", words);
    }
    void writeDone ( uint32_t srcGen ) {
        fprintf(stderr, "Memwrite::writeDone (%08x)\n", srcGen);
        sem_post(&test_sem);
    }
    void reportStateDbg(uint32_t streamWrCnt, uint32_t srcGen) {
        fprintf(stderr, "Memwrite::reportStateDbg: streamWrCnt=%08x srcGen=%d\n", streamWrCnt, srcGen);
    }
};

int main(int argc, const char **argv)
{
    int mismatch = 0;
    uint32_t sg = 0;
    int max_error = 10;

    if (sem_init(&test_sem, 1, 0)) {
        fprintf(stderr, "error: failed to init test_sem\n");
        exit(1);
    }
    fprintf(stderr, "testmemwrite: start %s %s\n", __DATE__, __TIME__);
    DmaManager *dma = platformInit();
    MemwriteRequestProxy *device = new MemwriteRequestProxy(IfcNames_MemwriteRequestS2H);
    MemwriteIndication deviceIndication(IfcNames_MemwriteIndicationH2S);

    alloc_sz *= numEngineServers;

    fprintf(stderr, "main::allocating %lx bytes of memory...\n", (long)alloc_sz);
    int dstAlloc = portalAlloc(alloc_sz, 0);
    unsigned int *dstBuffer = (unsigned int *)portalMmap(dstAlloc, alloc_sz);
#ifdef FPGA0_CLOCK_FREQ
    long req_freq = FPGA0_CLOCK_FREQ, freq = 0;
    setClockFrequency(0, req_freq, &freq);
    fprintf(stderr, "Requested FCLK[0]=%ld actually %ld\n", req_freq, freq);
#endif
    unsigned int ref_dstAlloc = dma->reference(dstAlloc);
    for (int i = 0; i < numWords*numEngineServers; i++)
        dstBuffer[i] = 0xDEADBEEF;
    portalCacheFlush(dstAlloc, dstBuffer, alloc_sz, 1);
    fprintf(stderr, "testmemwrite: flush and invalidate complete\n");

    burstLen = burstLenMin; // words
    while (burstLen <= burstLenMax) {
      fprintf(stderr, "testmemwrite: starting write %#08x words burstLen=%d words\n", numWords, burstLen);
      portalTimerStart(0);
      device->startWrite(ref_dstAlloc, 0, numWords, burstLen, iterCnt);
      sem_wait(&test_sem);
      mismatch = 0;
      for (int i = 0; i < numWords; i++) {
        if (dstBuffer[i] != sg) {
	  mismatch++;
	  if (max_error-- > 0)
	    fprintf(stderr, "testmemwrite: [%d] actual %08x expected %08x\n", i, dstBuffer[i], sg);
        }
        sg++;
      }
      platformStatistics();
      fprintf(stderr, "testmemwrite: mismatch count %d.\n", mismatch);
      burstLen *= 2;
      if (mismatch)
	exit(mismatch);

      // now try with larger burstLen
      burstLen *= 2;
    }
}
<|endoftext|>


<commit_before><commit_msg>Beast Mode Enabled !<commit_after><|endoftext|>


<commit_before>
#include "Globals.h"  // NOTE: MSVC stupidness requires this to be the same across all modules

#include "BeaconEntity.h"
#include "../BlockArea.h"

cBeaconEntity::cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
	super(E_BLOCK_BEACON, a_BlockX, a_BlockY, a_BlockZ, a_World)
{
}

int cBeaconEntity::GetPyramidLevel()
{
	cBlockArea Area;
	Area.Read(
		m_World,
		GetPosX() - 4,
		GetPosX() + 4,
		GetPosY() - 5,
		GetPosY() - 1,
		GetPosZ() - 4,
		GetPosZ() + 4
	);

	int Layer = 1;
	int MiddleXZ = 4;

	for (int Y = Area.GetSizeY() - 1; Y > 0; Y--)
	{
		for (int X = MiddleXZ - Layer; X <= (MiddleXZ + Layer); X++)
		{
			for (int Z = MiddleXZ - Layer; Z <= (MiddleXZ + Layer); Z++)
			{
				if (!IsMineralBlock(Area.GetRelBlockType(X, Y, Z)))
				{
					return Layer;
				}
			}
		}
		Layer++;
	}

	return Layer;
}

bool cBeaconEntity::IsMineralBlock(BLOCKTYPE a_BlockType)
{
	switch(a_BlockType)
	{
		case E_BLOCK_DIAMOND_BLOCK:
		case E_BLOCK_GOLD_BLOCK:
		case E_BLOCK_IRON_BLOCK:
		case E_BLOCK_EMERALD_BLOCK:
		{
			return true;
		}
	}
	return false;
}

bool cBeaconEntity::Tick(float a_Dt, cChunk & a_Chunk)
{
	std::cout << GetPyramidLevel() << "\n";
	return false;
}

void cBeaconEntity::SaveToJson(Json::Value& a_Value)
{
}

void cBeaconEntity::SendTo(cClientHandle & a_Client)
{
}

void cBeaconEntity::UsedBy(cPlayer * a_Player)
{
}<commit_msg>Removed debug message.<commit_after>
#include "Globals.h"  // NOTE: MSVC stupidness requires this to be the same across all modules

#include "BeaconEntity.h"
#include "../BlockArea.h"

cBeaconEntity::cBeaconEntity(int a_BlockX, int a_BlockY, int a_BlockZ, cWorld * a_World) :
	super(E_BLOCK_BEACON, a_BlockX, a_BlockY, a_BlockZ, a_World)
{
}

int cBeaconEntity::GetPyramidLevel()
{
	cBlockArea Area;
	Area.Read(
		m_World,
		GetPosX() - 4,
		GetPosX() + 4,
		GetPosY() - 5,
		GetPosY() - 1,
		GetPosZ() - 4,
		GetPosZ() + 4
	);

	int Layer = 1;
	int MiddleXZ = 4;

	for (int Y = Area.GetSizeY() - 1; Y > 0; Y--)
	{
		for (int X = MiddleXZ - Layer; X <= (MiddleXZ + Layer); X++)
		{
			for (int Z = MiddleXZ - Layer; Z <= (MiddleXZ + Layer); Z++)
			{
				if (!IsMineralBlock(Area.GetRelBlockType(X, Y, Z)))
				{
					return Layer;
				}
			}
		}
		Layer++;
	}

	return Layer;
}

bool cBeaconEntity::IsMineralBlock(BLOCKTYPE a_BlockType)
{
	switch(a_BlockType)
	{
		case E_BLOCK_DIAMOND_BLOCK:
		case E_BLOCK_GOLD_BLOCK:
		case E_BLOCK_IRON_BLOCK:
		case E_BLOCK_EMERALD_BLOCK:
		{
			return true;
		}
	}
	return false;
}

bool cBeaconEntity::Tick(float a_Dt, cChunk & a_Chunk)
{
	return false;
}

void cBeaconEntity::SaveToJson(Json::Value& a_Value)
{
}

void cBeaconEntity::SendTo(cClientHandle & a_Client)
{
}

void cBeaconEntity::UsedBy(cPlayer * a_Player)
{
}<|endoftext|>


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

#include "analogSensor.h"

#include <QtCore/QDebug>

#include <trikKernel/configurer.h>
#include <QsLog.h>

#include "i2cCommunicator.h"
#include "configurerHelper.h"

using namespace trikControl;

AnalogSensor::AnalogSensor(const QString &port, const trikKernel::Configurer &configurer, I2cCommunicator &communicator)
	: mCommunicator(communicator)
{
	mI2cCommandNumber = ConfigurerHelper::configureInt(configurer, mState, port, "i2cCommandNumber");
	mIRType = configurer.attributeByPort(port, "type") == "IR" ? Type::IR : Type::CustomIR;
	// We use linear subjection to normalize sensor values:
	// normalizedValue = k * rawValue + b
	// To calculate k and b we need two raw values and two corresponding them normalized values.

	if (mIRType == Type::CustomIR){
		CalculateLNS(port, configurer);
	} else {
			CalculateKB(port, configurer);
	       }

	mState.ready();
}

AnalogSensor::Status AnalogSensor::status() const
{
	return DeviceInterface::combine(mCommunicator, mState.status());
}

int AnalogSensor::read()
{
	if (!mState.isReady() || mCommunicator.status() != DeviceInterface::Status::ready) {
		return 0;
	}
	QByteArray command(1, '\0');
	command[0] = static_cast<char>(mI2cCommandNumber & 0xFF);
	if (mIRType == Type::IR){
		return mK * mCommunicator.read(command) + mB;
	}

	return mS/((mCommunicator.read(command)) + mL) + mN;

}

int AnalogSensor::readRawData()
{
	if (!mState.isReady() || mCommunicator.status() != DeviceInterface::Status::ready) {
		return 0;
	}

	QByteArray command(1, '\0');
	command[0] = static_cast<char>(mI2cCommandNumber & 0xFF);

	return mCommunicator.read(command);
}

void AnalogSensor::CalculateLNS(const QString &port, const trikKernel::Configurer &configurer)
{
	const float x1 = ConfigurerHelper::configureInt(configurer, mState, port, "x1");
	const float x2 = ConfigurerHelper::configureInt(configurer, mState, port, "x2");
	const float x3 = ConfigurerHelper::configureInt(configurer, mState, port, "x3");
	const float y1 = ConfigurerHelper::configureInt(configurer, mState, port, "y1");
	const float y2 = ConfigurerHelper::configureInt(configurer, mState, port, "y2");
	const float y3 = ConfigurerHelper::configureInt(configurer, mState, port, "y3");
	const float d1 = (x3*(y1 - y3)*(x2 - x1)) / (y1 - y2);
	const float d2 = x1*x2;
	const float d3 = x2*x3;
	const float d4 = x3 - x1 - (y1 - y3)*(x2 - x1) / (y1 - y2);
	const float d5 = (y1 - y2)*(x1 + mL)*(x2 + mL);
	const float d6 = (x3 + mL) * (x2 - x1);
	mL = (d1 + d2 - d3) / d4;
	mN = y3 - d5 / d6;
	mS = (y1 - y2)*(x2 + mL)*(x1 + mL) / (x2 - x1);
}

void AnalogSensor::CalculateKB(const QString &port, const trikKernel::Configurer &configurer)
{
	const int rawValue1 = ConfigurerHelper::configureInt(configurer, mState, port, "rawValue1");
	const int rawValue2 = ConfigurerHelper::configureInt(configurer, mState, port, "rawValue2");
	const int normalizedValue1 = ConfigurerHelper::configureInt(configurer, mState, port, "normalizedValue1");
	const int normalizedValue2 = ConfigurerHelper::configureInt(configurer, mState, port, "normalizedValue2");
	if (rawValue1 == rawValue2) {
		QLOG_ERROR() <<  "Sensor calibration error: rawValue1 = rawValue2!";
		mState.fail();
		mK = 0;
		mB = 0;
	} else {
		mK = static_cast<qreal>(normalizedValue2 - normalizedValue1) / (rawValue2 - rawValue1);
		mB = normalizedValue1 - mK * rawValue1;
		}
}

<commit_msg>Corrected function for counting coefficients mL mN mS<commit_after>/* Copyright 2013 - 2015 Nikita Batov and CyberTech Labs Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. */

#include "analogSensor.h"

#include <QtCore/QDebug>

#include <trikKernel/configurer.h>
#include <QsLog.h>

#include "i2cCommunicator.h"
#include "configurerHelper.h"

using namespace trikControl;

AnalogSensor::AnalogSensor(const QString &port, const trikKernel::Configurer &configurer, I2cCommunicator &communicator)
	: mCommunicator(communicator)
{
	mI2cCommandNumber = ConfigurerHelper::configureInt(configurer, mState, port, "i2cCommandNumber");
	mIRType = configurer.attributeByPort(port, "type") == "IR" ? Type::IR : Type::CustomIR;
	// We use linear subjection to normalize sensor values:
	// normalizedValue = k * rawValue + b
	// To calculate k and b we need two raw values and two corresponding them normalized values.

	if (mIRType == Type::CustomIR){
		CalculateLNS(port, configurer);
	} else {
			CalculateKB(port, configurer);
	       }

	mState.ready();
}

AnalogSensor::Status AnalogSensor::status() const
{
	return DeviceInterface::combine(mCommunicator, mState.status());
}

int AnalogSensor::read()
{
	if (!mState.isReady() || mCommunicator.status() != DeviceInterface::Status::ready) {
		return 0;
	}
	QByteArray command(1, '\0');
	command[0] = static_cast<char>(mI2cCommandNumber & 0xFF);
	if (mIRType == Type::IR){
		return mK * mCommunicator.read(command) + mB;
	}

	return mS/((mCommunicator.read(command)) + mL) + mN;

}

int AnalogSensor::readRawData()
{
	if (!mState.isReady() || mCommunicator.status() != DeviceInterface::Status::ready) {
		return 0;
	}

	QByteArray command(1, '\0');
	command[0] = static_cast<char>(mI2cCommandNumber & 0xFF);

	return mCommunicator.read(command);
}

void AnalogSensor::CalculateLNS(const QString &port, const trikKernel::Configurer &configurer)
{
	const float x1 = ConfigurerHelper::configureInt(configurer, mState, port, "x1");
	const float x2 = ConfigurerHelper::configureInt(configurer, mState, port, "x2");
	const float x3 = ConfigurerHelper::configureInt(configurer, mState, port, "x3");
	const float y1 = ConfigurerHelper::configureInt(configurer, mState, port, "y1");
	const float y2 = ConfigurerHelper::configureInt(configurer, mState, port, "y2");
	const float y3 = ConfigurerHelper::configureInt(configurer, mState, port, "y3");
	const float d1 = (x3*(y1 - y3)*(x2 - x1)) / (y1 - y2);
	const float d2 = x1*x2;
	const float d3 = x2*x3;
	const float d4 = x3 - x1 - (y1 - y3)*(x2 - x1) / (y1 - y2);
	mN = (-1)*(d1 + d2 - d3) / d4;
	const float d5 = (y1 - y2)*(x1 - mN)*(x2 - mN);
	const float d6 = (x3 - mN) * (x2 - x1);
	mL = (-1)*y3 + d5 / d6;
	mS = (y1 - y2)*(x2 - mN)*(x1 - mN) / (x2 - x1);
}

void AnalogSensor::CalculateKB(const QString &port, const trikKernel::Configurer &configurer)
{
	const int rawValue1 = ConfigurerHelper::configureInt(configurer, mState, port, "rawValue1");
	const int rawValue2 = ConfigurerHelper::configureInt(configurer, mState, port, "rawValue2");
	const int normalizedValue1 = ConfigurerHelper::configureInt(configurer, mState, port, "normalizedValue1");
	const int normalizedValue2 = ConfigurerHelper::configureInt(configurer, mState, port, "normalizedValue2");
	if (rawValue1 == rawValue2) {
		QLOG_ERROR() <<  "Sensor calibration error: rawValue1 = rawValue2!";
		mState.fail();
		mK = 0;
		mB = 0;
	} else {
		mK = static_cast<qreal>(normalizedValue2 - normalizedValue1) / (rawValue2 - rawValue1);
		mB = normalizedValue1 - mK * rawValue1;
		}
}

<|endoftext|>


<commit_before><commit_msg>Initialized t1 = atoms[i].xs when detecting interacting pairs in ligand::ligand<commit_after><|endoftext|>


<commit_before>#include <Bull/Render/HardwareBuffer.hpp>

namespace Bull
{
    /*! \brief Bind a buffer
     *
     * \param buffer The buffer to bind
     *
     */
    void HardwareBuffer::bind(const HardwareBuffer& buffer)
    {
        ensureContext();
        gl::bindBuffer(buffer.m_type, buffer.m_id);
    }

    /*! \brief Unbind any buffer
     *
     * \param type The type of buffer to unbind
     *
     */
    void HardwareBuffer::unbind(Type type)
    {
        ensureContext();
        gl::bindBuffer(type, 0);
    }

    /*! \brief Constructor
     *
     * \param type The type the of OpenGL buffer to create
     *
     */
    HardwareBuffer::HardwareBuffer(Type type) :
        m_id(0),
        m_type(type)
    {
        /// Nothing
    }

    /*! \brief Destructor
     *
     */
    HardwareBuffer::~HardwareBuffer()
    {
        destroy();
    }

    /*! \brief Create the buffer in the VRAM
     *
     * \param size  The size of the buffer
     * \param usage The usage of the buffer
     *
     * \return Return true if the buffer was created successfully, false otherwise
     *
     */
    bool HardwareBuffer::create(std::size_t size, Usage usage)
    {
        ensureContext();

        if(m_id)
        {
            destroy();
        }

        gl::genBuffers(1, &m_id);
        gl::bindBuffer(m_type, m_id);
        gl::bufferData(m_type, size, nullptr, usage);

        return true;
    }

    /*! \brief Fill the buffer
     *
     * \param data   Data to use to fill the buffer
     * \param size   The size of data
     * \param offset The offset of the data in the buffer
     *
     * \return Return true if the buffer was filled successfully, false otherwise
     *
     */
    bool HardwareBuffer::fill(const void* data, std::size_t size, std::size_t offset)
    {
        ensureContext();

        if(m_id)
        {
            gl::bindBuffer(m_type, m_id);
            gl::bufferSubData(m_type, offset, size, data);

            return true;
        }

        return false;

    }

    /*! \brief Flush the buffer
     *
     */
    void HardwareBuffer::flush()
    {
        if(m_id)
        {
            ensureContext();

            gl::bindBuffer(m_type, m_id);
            gl::bufferData(m_type, 0, nullptr, StaticDraw);
        }
    }

    /*! \brief Destroy the buffer
     *
     */
    void HardwareBuffer::destroy()
    {
        if(m_id)
        {
            ensureContext();

            gl::deleteBuffers(1, &m_id);
        }
    }

    /*! \brief Get the buffer system handler
     *
     * \return Return the native buffer system handler
     *
     */
    unsigned int HardwareBuffer::getSystemHandler() const
    {
        return m_id;
    }
}
<commit_msg>[Render/HardwareBuffer] Use glBufferMap with big buffers<commit_after>#include <Bull/Render/HardwareBuffer.hpp>

namespace Bull
{
    /*! \brief Bind a buffer
     *
     * \param buffer The buffer to bind
     *
     */
    void HardwareBuffer::bind(const HardwareBuffer& buffer)
    {
        ensureContext();
        gl::bindBuffer(buffer.m_type, buffer.m_id);
    }

    /*! \brief Unbind any buffer
     *
     * \param type The type of buffer to unbind
     *
     */
    void HardwareBuffer::unbind(Type type)
    {
        ensureContext();
        gl::bindBuffer(type, 0);
    }

    /*! \brief Constructor
     *
     * \param type The type the of OpenGL buffer to create
     *
     */
    HardwareBuffer::HardwareBuffer(Type type) :
        m_id(0),
        m_type(type)
    {
        /// Nothing
    }

    /*! \brief Destructor
     *
     */
    HardwareBuffer::~HardwareBuffer()
    {
        destroy();
    }

    /*! \brief Create the buffer in the VRAM
     *
     * \param size  The size of the buffer
     * \param usage The usage of the buffer
     *
     * \return Return true if the buffer was created successfully, false otherwise
     *
     */
    bool HardwareBuffer::create(std::size_t size, Usage usage)
    {
        ensureContext();

        if(m_id)
        {
            destroy();
        }

        gl::genBuffers(1, &m_id);
        gl::bindBuffer(m_type, m_id);
        gl::bufferData(m_type, size, nullptr, usage);

        return true;
    }

    /*! \brief Fill the buffer
     *
     * \param data   Data to use to fill the buffer
     * \param size   The size of data
     * \param offset The offset of the data in the buffer
     *
     * \return Return true if the buffer was filled successfully, false otherwise
     *
     */
    bool HardwareBuffer::fill(const void* data, std::size_t size, std::size_t offset)
    {
        ensureContext();

        if(m_id)
        {
            gl::bindBuffer(m_type, m_id);

            /// It seems that glBufferSubData is more efficient than glMapBuffer with small buffers
            /// http://www.stevestreeting.com/2007/03/17/glmapbuffer-vs-glbuffersubdata-the-return/
            if(size < 32 * 1024)
            {
                gl::bufferSubData(m_type, offset, size, data);
            }
            else
            {
                void* ptr = gl::mapBuffer(m_type, GL_WRITE_ONLY);

                std::memcpy(ptr, &data[offset], size)

                gl::unmapBuffer(m_type);
            }

            return true;
        }

        return false;

    }

    /*! \brief Flush the buffer
     *
     */
    void HardwareBuffer::flush()
    {
        if(m_id)
        {
            ensureContext();

            gl::bindBuffer(m_type, m_id);
            gl::bufferData(m_type, 0, nullptr, StaticDraw);
        }
    }

    /*! \brief Destroy the buffer
     *
     */
    void HardwareBuffer::destroy()
    {
        if(m_id)
        {
            ensureContext();

            gl::deleteBuffers(1, &m_id);
        }
    }

    /*! \brief Get the buffer system handler
     *
     * \return Return the native buffer system handler
     *
     */
    unsigned int HardwareBuffer::getSystemHandler() const
    {
        return m_id;
    }
}
<|endoftext|>


<commit_before><commit_msg>make cheops submits template based<commit_after><|endoftext|>


<commit_before><commit_msg>Bugfix: Quasiquote with non-list unquoted item now works<commit_after><|endoftext|>


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

#include "systemc/utils/tracefile.hh"

#include <ctime>
#include <iomanip>

#include "base/logging.hh"
#include "base/output.hh"
#include "sim/core.hh"
#include "systemc/ext/core/sc_main.hh"
#include "systemc/ext/utils/functions.hh"

namespace sc_gem5
{

TraceFile::TraceFile(const std::string &name) :
    _os(simout.create(name, true, true)), timeUnitTicks(0),
    timeUnitValue(1.0), timeUnitUnit(::sc_core::SC_PS), _traceDeltas(false)
{}

TraceFile::~TraceFile()
{
    simout.close(_os);
}

std::ostream &TraceFile::stream() { return *_os->stream(); }

void
TraceFile::set_time_unit(double d, ::sc_core::sc_time_unit tu)
{
    timeUnitValue = d;
    timeUnitUnit = tu;
}

void
TraceFile::finalizeTime()
{
    timeUnitTicks = ::sc_core::sc_time(timeUnitValue, timeUnitUnit).value();
}

} // namespace sc_gem5
<commit_msg>systemc: Print an Info when setting a tracefile's time unit.<commit_after>/*
 * Copyright 2018 Google, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#include "systemc/utils/tracefile.hh"

#include <ctime>
#include <iomanip>

#include "base/logging.hh"
#include "base/output.hh"
#include "sim/core.hh"
#include "systemc/core/time.hh"
#include "systemc/ext/core/sc_main.hh"
#include "systemc/ext/utils/functions.hh"

namespace sc_gem5
{

TraceFile::TraceFile(const std::string &name) :
    _os(simout.create(name, true, true)), timeUnitTicks(0),
    timeUnitValue(1.0), timeUnitUnit(::sc_core::SC_PS), _traceDeltas(false)
{}

TraceFile::~TraceFile()
{
    simout.close(_os);
}

std::ostream &TraceFile::stream() { return *_os->stream(); }

void
TraceFile::set_time_unit(double d, ::sc_core::sc_time_unit tu)
{
    timeUnitValue = d;
    timeUnitUnit = tu;

    double secs = d * TimeUnitScale[tu];
    for (tu = ::sc_core::SC_SEC; tu > ::sc_core::SC_FS;
            tu = (::sc_core::sc_time_unit)(tu - 1)) {
        if (TimeUnitScale[tu] <= secs)
            break;
    }

    uint64_t i = static_cast<uint64_t>(secs / TimeUnitScale[tu]);
    std::ostringstream ss;
    ss << i << " " << TimeUnitNames[tu] << " (" << _os->name() << ")";
    SC_REPORT_INFO("(I703) tracing timescale unit set", ss.str().c_str());
}

void
TraceFile::finalizeTime()
{
    timeUnitTicks = ::sc_core::sc_time(timeUnitValue, timeUnitUnit).value();
}

} // namespace sc_gem5
<|endoftext|>