<commit_before>#ifndef DUNE_RB_MODEL_STATIONARY_LINEAR_ELLIPTIC_INTERFACE_HH
#define DUNE_RB_MODEL_STATIONARY_LINEAR_ELLIPTIC_INTERFACE_HH

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

#include <vector>

#include <dune/common/shared_ptr.hh>

#include <dune/grid/io/file/vtk/vtkwriter.hh>

#include <dune/stuff/common/string.hh>
#include <dune/stuff/common/color.hh>
#include <dune/stuff/common/parameter.hh>
#include <dune/stuff/function/interface.hh>
#include <dune/stuff/function/fixed.hh>

namespace Dune {
namespace Detailed {
namespace Solvers {
namespace Stationary {
namespace Linear {
namespace Elliptic {
namespace Model {

// forward of the nonparametric default
template< class DomainFieldImp, int domainDim, class RangeFieldImp, int rangeDim >
class Default;

// forward to allow for specialization
template< class DomainFieldImp, int domainDim, class RangeFieldImp, int rangeDim >
class Interface;

template< class DomainFieldImp, int domainDim, class RangeFieldImp >
class Interface< DomainFieldImp, domainDim, RangeFieldImp, 1 >
{
public:
  typedef Interface< DomainFieldImp, domainDim, RangeFieldImp, 1 > ThisType;

  typedef DomainFieldImp  DomainFieldType;
  static const int        dimDomain = domainDim;

  typedef RangeFieldImp   RangeFieldType;
  static const int        dimRange = 1;

  typedef typename Stuff::Common::Parameter::FieldType  ParamFieldType;
  static const int                                      maxParamDim = Stuff::Common::Parameter::maxDim;
  typedef typename Stuff::Common::Parameter::Type       ParamType;

  typedef Dune::Stuff::Function::Interface< DomainFieldType, dimDomain, RangeFieldType, dimRange > FunctionType;

  static const std::string id()
  {
    return "model.stationary.linear.elliptic";
  }

  /** \defgroup type ´´These methods determine the type of the model (and also, which of the below methods have to be implemented).'' */
  /* @{ */
  virtual bool parametric() const
  {
    if (diffusion()->parametric() || force()->parametric() || dirichlet()->parametric() || neumann()->parametric())
      return true;
    else
      return false;
  }

  virtual bool separable() const
  {
    if (parametric()) {
      if (diffusion()->parametric() && !diffusion()->separable())
        return false;
      if (force()->parametric() && !force()->separable())
        return false;
      if (dirichlet()->parametric() && !dirichlet()->separable())
        return false;
      if (neumann()->parametric() && !neumann()->separable())
        return false;
      return true;
    } else
      return false;
  }
  /* @} */

  /** \defgroup purevirtual ´´These methods have to be implemented.'' */
  /* @{ */
  virtual Dune::shared_ptr< const FunctionType > diffusion() const = 0;

  virtual Dune::shared_ptr< const FunctionType > force() const = 0;

  virtual Dune::shared_ptr< const FunctionType > dirichlet() const = 0;

  virtual Dune::shared_ptr< const FunctionType > neumann() const = 0;
  /* @} */

  /** \defgroup parametric ´´These methods have to be implemented additionally, if parametric() == true.'' */
  /* @{ */
  virtual size_t paramSize() const
  {
    if (!parametric())
      return 0;
    else
      DUNE_THROW(Dune::NotImplemented,
                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:") << " implement me if parametric() == true!");
  }

  virtual const std::vector< ParamType >& paramRange() const
  {
    DUNE_THROW(Dune::NotImplemented,
               "\n" << Dune::Stuff::Common::colorStringRed("ERROR:") << " implement me if parametric() == true!");
  }

  virtual const std::vector< std::string >& paramExplanation() const
  {
    DUNE_THROW(Dune::NotImplemented,
               "\n" << Dune::Stuff::Common::colorStringRed("ERROR:") << " implement me if parametric() == true!");
  }

  /**
   * \brief     Maps a global to a local parameter.
   * \param[in] ParamType _globalMu
   *            global parameter
   * \param[in] std::string _id
   *            To identify the function, wrt which the localization is carried out. Has to be one of diffusion,
   *            force, dirichlet or neumann
   * \return    ParamType
   *            local parameter
   */
  virtual ParamType mapParam(const ParamType& /*_globalMu*/, const std::string /*_id*/) const
  {
    if (!parametric())
      return ParamType();
    else
      DUNE_THROW(Dune::NotImplemented,
                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:") << " implement me if parametric() == true!");
  }
  /* @} */

  virtual Dune::shared_ptr< const ThisType > fix(const ParamType& mu) const
  {
    typedef Dune::Stuff::Function::Fixed< DomainFieldType, dimDomain, RangeFieldType, dimRange > FixedFunctionType;
    typedef Default< DomainFieldType, dimDomain, RangeFieldType, dimRange > DefaultModelType;
    Dune::shared_ptr< DefaultModelType >
        defaultModel(Dune::make_shared< DefaultModelType >(diffusion()->parametric() ? Dune::make_shared< const FixedFunctionType >(diffusion(), mapParam(mu, "diffusion")) : diffusion(),
                                                      force()->parametric() ? Dune::make_shared< const FixedFunctionType >(force(), mapParam(mu, "force")) : force(),
                                                      dirichlet()->parametric() ? Dune::make_shared< const FixedFunctionType >(dirichlet(), mapParam(mu, "dirichlet")) : dirichlet(),
                                                      neumann()->parametric() ? Dune::make_shared< const FixedFunctionType >(neumann(), mapParam(mu, "neumann")) : neumann()));
    return defaultModel;
  }

//  void report(std::ostream& out = std::cout, std::string prefix = "") const
//  {
//    out << prefix << "parameter explanation:" << std::endl;
//    assert(paramExplanation().size() == paramSize());
//    assert(paramRange().size() == 2);
//    assert(paramRange()[0].size() == paramSize());
//    assert(paramRange()[1].size() == paramSize());
//    for (size_t pp = 0; pp < paramSize(); ++pp)
//      out << prefix << "  " << paramExplanation()[pp] << ", between " << paramRange()[0](pp) << " and " << paramRange()[1](pp) << std::endl;
//  }

  template< class GridViewType >
  void visualize(const GridViewType& gridView, std::string filename) const
  {
    // prepare data
    Dune::VTKWriter< GridViewType > vtkWriter(gridView);
    std::vector< std::pair< std::string, std::vector< RangeFieldType >* > > diffusionPlots
        = preparePlot(gridView, *(diffusion()), "diffusion");
    std::vector< std::pair< std::string, std::vector< RangeFieldType >* > > forcePlots
        = preparePlot(gridView, *(force()), "force");
    std::vector< std::pair< std::string, std::vector< RangeFieldType >* > > dirichletPlots
        = preparePlot(gridView, *(dirichlet()), "dirichlet");
    std::vector< std::pair< std::string, std::vector< RangeFieldType >* > > neumannPlots
        = preparePlot(gridView, *(neumann()), "neumann");
    // walk the grid view
    for (typename GridViewType::template Codim< 0 >::Iterator it = gridView.template begin< 0 >();
         it != gridView.template end< 0 >();
         ++it) {
      const typename GridViewType::template Codim< 0 >::Entity& entity = *it;
      const typename GridViewType::IndexSet::IndexType index = gridView.indexSet().index(entity);
      const typename FunctionType::DomainType center = entity.geometry().center();
      // do a piecewise constant projection of the data functions
      //   * diffusion
      if (diffusion()->parametric() && diffusion()->separable())
        for (size_t qq = 0; qq < diffusion()->numComponents(); ++qq)
          diffusionPlots[qq].second->operator[](index) = diffusion()->components()[qq]->evaluate(center);
      else if (!diffusion()->parametric())
        diffusionPlots[0].second->operator[](index) = diffusion()->evaluate(center);
      else
        DUNE_THROW(Dune::InvalidStateException,
                   "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                   << " visualize() not yet implemented for parametric but not separable data functions!");
      //   * force
      if (force()->parametric() && force()->separable())
        for (size_t qq = 0; qq < force()->numComponents(); ++qq)
          forcePlots[qq].second->operator[](index) = force()->components()[qq]->evaluate(center);
      else if (!force()->parametric())
        forcePlots[0].second->operator[](index) = force()->evaluate(center);
      else
        DUNE_THROW(Dune::InvalidStateException,
                   "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                   << " visualize() not yet implemented for parametric but not separable data functions!");
      //   * dirichlet
      if (dirichlet()->parametric() && dirichlet()->separable())
        for (size_t qq = 0; qq < dirichlet()->numComponents(); ++qq)
          dirichletPlots[qq].second->operator[](index) = dirichlet()->components()[qq]->evaluate(center);
      else if (!dirichlet()->parametric())
        dirichletPlots[0].second->operator[](index) = dirichlet()->evaluate(center);
      else
        DUNE_THROW(Dune::InvalidStateException,
                   "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                   << " visualize() not yet implemented for parametric but not separable data functions!");
      //   * neumann
      if (neumann()->parametric() && neumann()->separable())
        for (size_t qq = 0; qq < neumann()->numComponents(); ++qq)
          neumannPlots[qq].second->operator[](index) = neumann()->components()[qq]->evaluate(center);
      else if (!neumann()->parametric())
        neumannPlots[0].second->operator[](index) = neumann()->evaluate(center);
      else
        DUNE_THROW(Dune::InvalidStateException,
                   "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                   << " visualize() not yet implemented for parametric but not separable data functions!");
    } // walk the grid view
    // write
    //   * diffusion
    for (size_t qq = 0; qq < diffusionPlots.size(); ++qq)
      vtkWriter.addCellData(*(diffusionPlots[qq].second), diffusionPlots[qq].first);
    //   * force
    for (size_t qq = 0; qq < forcePlots.size(); ++qq)
      vtkWriter.addCellData(*(forcePlots[qq].second), forcePlots[qq].first);
    //   * dirichlet
    for (size_t qq = 0; qq < dirichletPlots.size(); ++qq)
      vtkWriter.addCellData(*(dirichletPlots[qq].second), dirichletPlots[qq].first);
    //   * neumann
    for (size_t qq = 0; qq < neumannPlots.size(); ++qq)
      vtkWriter.addCellData(*(neumannPlots[qq].second), neumannPlots[qq].first);
    vtkWriter.write(filename, Dune::VTK::ascii);
  } // void visualize(const GridViewType& gridView, std::string filename) const

private:
  template< class GridViewType, class FunctionType >
  std::vector< std::pair< std::string, std::vector< RangeFieldType >* > > preparePlot(const GridViewType& gridView,
                                                                                const FunctionType& function,
                                                                                const std::string name) const
  {
    std::vector< std::pair< std::string, std::vector< RangeFieldType >* > > ret;
    if (function.parametric()) {
      if (function.separable()) {
        const std::vector< std::string >& paramExplanations = function.paramExplanation();
        for (size_t qq = 0; qq < function.numCoefficients(); ++qq)
          ret.push_back(std::pair< std::string, std::vector< RangeFieldType >* >(
                          name + "_component_" + Dune::Stuff::Common::toString(qq) + ": " + paramExplanations[qq],
                          new std::vector< RangeFieldType >(gridView.indexSet().size(0), RangeFieldType(0))));
        if (function.numComponents() > function.numCoefficients())
          ret.push_back(std::pair< std::string, std::vector< RangeFieldType >* >(
                          name + "_component_" + Dune::Stuff::Common::toString(function.numCoefficients()),
                          new std::vector< RangeFieldType >(gridView.indexSet().size(0), RangeFieldType(0))));
      } else
        DUNE_THROW(Dune::InvalidStateException,
                   "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                   << " visualize() not yet implemented for parametric but not separable data functions!");
    } else {
      ret.push_back(std::pair< std::string, std::vector< RangeFieldType >* >(
                      name,
                      new std::vector< RangeFieldType >(gridView.indexSet().size(0), RangeFieldType(0))));
    }
    return ret;
  } // std::vector< std::pair< std::string, std::vector< RangeFieldType >* > > preparePlot(...) const

}; // class Interface

} // namespace Model
} // namespace Elliptic
} // namespace Linear
} // namespace Stationary
} // namespace Solvers
} // namespace Detailed
} // namespace Dune

#endif // DUNE_RB_MODEL_STATIONARY_LINEAR_ELLIPTIC_INTERFACE_HH
<commit_msg>[...elliptic.model.interface] 'fixed' forward<commit_after>#ifndef DUNE_RB_MODEL_STATIONARY_LINEAR_ELLIPTIC_INTERFACE_HH
#define DUNE_RB_MODEL_STATIONARY_LINEAR_ELLIPTIC_INTERFACE_HH

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

#include <vector>

#include <dune/common/shared_ptr.hh>

#include <dune/grid/io/file/vtk/vtkwriter.hh>

#include <dune/stuff/common/string.hh>
#include <dune/stuff/common/color.hh>
#include <dune/stuff/common/parameter.hh>
#include <dune/stuff/function/interface.hh>
#include <dune/stuff/function/fixed.hh>

namespace Dune {
namespace Detailed {
namespace Solvers {
namespace Stationary {
namespace Linear {
namespace Elliptic {
namespace Model {

// forward of the nonparametric default
template< class DomainFieldImp, int domainDim, class RangeFieldImp, int rangeDim >
class Default;

// forward to allow for specialization
template< class DomainFieldImp, int domainDim, class RangeFieldImp, int rangeDim >
class Interface
{
public:
  Interface() = delete;
};

template< class DomainFieldImp, int domainDim, class RangeFieldImp >
class Interface< DomainFieldImp, domainDim, RangeFieldImp, 1 >
{
public:
  typedef Interface< DomainFieldImp, domainDim, RangeFieldImp, 1 > ThisType;

  typedef DomainFieldImp  DomainFieldType;
  static const int        dimDomain = domainDim;

  typedef RangeFieldImp   RangeFieldType;
  static const int        dimRange = 1;

  typedef typename Stuff::Common::Parameter::FieldType  ParamFieldType;
  static const int                                      maxParamDim = Stuff::Common::Parameter::maxDim;
  typedef typename Stuff::Common::Parameter::Type       ParamType;

  typedef Dune::Stuff::Function::Interface< DomainFieldType, dimDomain, RangeFieldType, dimRange > FunctionType;

  static const std::string id()
  {
    return "model.stationary.linear.elliptic";
  }

  /** \defgroup type ´´These methods determine the type of the model (and also, which of the below methods have to be implemented).'' */
  /* @{ */
  virtual bool parametric() const
  {
    if (diffusion()->parametric() || force()->parametric() || dirichlet()->parametric() || neumann()->parametric())
      return true;
    else
      return false;
  }

  virtual bool separable() const
  {
    if (parametric()) {
      if (diffusion()->parametric() && !diffusion()->separable())
        return false;
      if (force()->parametric() && !force()->separable())
        return false;
      if (dirichlet()->parametric() && !dirichlet()->separable())
        return false;
      if (neumann()->parametric() && !neumann()->separable())
        return false;
      return true;
    } else
      return false;
  }
  /* @} */

  /** \defgroup purevirtual ´´These methods have to be implemented.'' */
  /* @{ */
  virtual Dune::shared_ptr< const FunctionType > diffusion() const = 0;

  virtual Dune::shared_ptr< const FunctionType > force() const = 0;

  virtual Dune::shared_ptr< const FunctionType > dirichlet() const = 0;

  virtual Dune::shared_ptr< const FunctionType > neumann() const = 0;
  /* @} */

  /** \defgroup parametric ´´These methods have to be implemented additionally, if parametric() == true.'' */
  /* @{ */
  virtual size_t paramSize() const
  {
    if (!parametric())
      return 0;
    else
      DUNE_THROW(Dune::NotImplemented,
                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:") << " implement me if parametric() == true!");
  }

  virtual const std::vector< ParamType >& paramRange() const
  {
    DUNE_THROW(Dune::NotImplemented,
               "\n" << Dune::Stuff::Common::colorStringRed("ERROR:") << " implement me if parametric() == true!");
  }

  virtual const std::vector< std::string >& paramExplanation() const
  {
    DUNE_THROW(Dune::NotImplemented,
               "\n" << Dune::Stuff::Common::colorStringRed("ERROR:") << " implement me if parametric() == true!");
  }

  /**
   * \brief     Maps a global to a local parameter.
   * \param[in] ParamType _globalMu
   *            global parameter
   * \param[in] std::string _id
   *            To identify the function, wrt which the localization is carried out. Has to be one of diffusion,
   *            force, dirichlet or neumann
   * \return    ParamType
   *            local parameter
   */
  virtual ParamType mapParam(const ParamType& /*_globalMu*/, const std::string /*_id*/) const
  {
    if (!parametric())
      return ParamType();
    else
      DUNE_THROW(Dune::NotImplemented,
                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:") << " implement me if parametric() == true!");
  }
  /* @} */

  virtual Dune::shared_ptr< const ThisType > fix(const ParamType& mu) const
  {
    typedef Dune::Stuff::Function::Fixed< DomainFieldType, dimDomain, RangeFieldType, dimRange > FixedFunctionType;
    typedef Default< DomainFieldType, dimDomain, RangeFieldType, dimRange > DefaultModelType;
    Dune::shared_ptr< DefaultModelType >
        defaultModel(Dune::make_shared< DefaultModelType >(diffusion()->parametric() ? Dune::make_shared< const FixedFunctionType >(diffusion(), mapParam(mu, "diffusion")) : diffusion(),
                                                      force()->parametric() ? Dune::make_shared< const FixedFunctionType >(force(), mapParam(mu, "force")) : force(),
                                                      dirichlet()->parametric() ? Dune::make_shared< const FixedFunctionType >(dirichlet(), mapParam(mu, "dirichlet")) : dirichlet(),
                                                      neumann()->parametric() ? Dune::make_shared< const FixedFunctionType >(neumann(), mapParam(mu, "neumann")) : neumann()));
    return defaultModel;
  }

//  void report(std::ostream& out = std::cout, std::string prefix = "") const
//  {
//    out << prefix << "parameter explanation:" << std::endl;
//    assert(paramExplanation().size() == paramSize());
//    assert(paramRange().size() == 2);
//    assert(paramRange()[0].size() == paramSize());
//    assert(paramRange()[1].size() == paramSize());
//    for (size_t pp = 0; pp < paramSize(); ++pp)
//      out << prefix << "  " << paramExplanation()[pp] << ", between " << paramRange()[0](pp) << " and " << paramRange()[1](pp) << std::endl;
//  }

  template< class GridViewType >
  void visualize(const GridViewType& gridView, std::string filename) const
  {
    // prepare data
    Dune::VTKWriter< GridViewType > vtkWriter(gridView);
    std::vector< std::pair< std::string, std::vector< RangeFieldType >* > > diffusionPlots
        = preparePlot(gridView, *(diffusion()), "diffusion");
    std::vector< std::pair< std::string, std::vector< RangeFieldType >* > > forcePlots
        = preparePlot(gridView, *(force()), "force");
    std::vector< std::pair< std::string, std::vector< RangeFieldType >* > > dirichletPlots
        = preparePlot(gridView, *(dirichlet()), "dirichlet");
    std::vector< std::pair< std::string, std::vector< RangeFieldType >* > > neumannPlots
        = preparePlot(gridView, *(neumann()), "neumann");
    // walk the grid view
    for (typename GridViewType::template Codim< 0 >::Iterator it = gridView.template begin< 0 >();
         it != gridView.template end< 0 >();
         ++it) {
      const typename GridViewType::template Codim< 0 >::Entity& entity = *it;
      const typename GridViewType::IndexSet::IndexType index = gridView.indexSet().index(entity);
      const typename FunctionType::DomainType center = entity.geometry().center();
      // do a piecewise constant projection of the data functions
      //   * diffusion
      if (diffusion()->parametric() && diffusion()->separable())
        for (size_t qq = 0; qq < diffusion()->numComponents(); ++qq)
          diffusionPlots[qq].second->operator[](index) = diffusion()->components()[qq]->evaluate(center);
      else if (!diffusion()->parametric())
        diffusionPlots[0].second->operator[](index) = diffusion()->evaluate(center);
      else
        DUNE_THROW(Dune::InvalidStateException,
                   "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                   << " visualize() not yet implemented for parametric but not separable data functions!");
      //   * force
      if (force()->parametric() && force()->separable())
        for (size_t qq = 0; qq < force()->numComponents(); ++qq)
          forcePlots[qq].second->operator[](index) = force()->components()[qq]->evaluate(center);
      else if (!force()->parametric())
        forcePlots[0].second->operator[](index) = force()->evaluate(center);
      else
        DUNE_THROW(Dune::InvalidStateException,
                   "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                   << " visualize() not yet implemented for parametric but not separable data functions!");
      //   * dirichlet
      if (dirichlet()->parametric() && dirichlet()->separable())
        for (size_t qq = 0; qq < dirichlet()->numComponents(); ++qq)
          dirichletPlots[qq].second->operator[](index) = dirichlet()->components()[qq]->evaluate(center);
      else if (!dirichlet()->parametric())
        dirichletPlots[0].second->operator[](index) = dirichlet()->evaluate(center);
      else
        DUNE_THROW(Dune::InvalidStateException,
                   "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                   << " visualize() not yet implemented for parametric but not separable data functions!");
      //   * neumann
      if (neumann()->parametric() && neumann()->separable())
        for (size_t qq = 0; qq < neumann()->numComponents(); ++qq)
          neumannPlots[qq].second->operator[](index) = neumann()->components()[qq]->evaluate(center);
      else if (!neumann()->parametric())
        neumannPlots[0].second->operator[](index) = neumann()->evaluate(center);
      else
        DUNE_THROW(Dune::InvalidStateException,
                   "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                   << " visualize() not yet implemented for parametric but not separable data functions!");
    } // walk the grid view
    // write
    //   * diffusion
    for (size_t qq = 0; qq < diffusionPlots.size(); ++qq)
      vtkWriter.addCellData(*(diffusionPlots[qq].second), diffusionPlots[qq].first);
    //   * force
    for (size_t qq = 0; qq < forcePlots.size(); ++qq)
      vtkWriter.addCellData(*(forcePlots[qq].second), forcePlots[qq].first);
    //   * dirichlet
    for (size_t qq = 0; qq < dirichletPlots.size(); ++qq)
      vtkWriter.addCellData(*(dirichletPlots[qq].second), dirichletPlots[qq].first);
    //   * neumann
    for (size_t qq = 0; qq < neumannPlots.size(); ++qq)
      vtkWriter.addCellData(*(neumannPlots[qq].second), neumannPlots[qq].first);
    vtkWriter.write(filename, Dune::VTK::ascii);
  } // void visualize(const GridViewType& gridView, std::string filename) const

private:
  template< class GridViewType, class FunctionType >
  std::vector< std::pair< std::string, std::vector< RangeFieldType >* > > preparePlot(const GridViewType& gridView,
                                                                                const FunctionType& function,
                                                                                const std::string name) const
  {
    std::vector< std::pair< std::string, std::vector< RangeFieldType >* > > ret;
    if (function.parametric()) {
      if (function.separable()) {
        const std::vector< std::string >& paramExplanations = function.paramExplanation();
        for (size_t qq = 0; qq < function.numCoefficients(); ++qq)
          ret.push_back(std::pair< std::string, std::vector< RangeFieldType >* >(
                          name + "_component_" + Dune::Stuff::Common::toString(qq) + ": " + paramExplanations[qq],
                          new std::vector< RangeFieldType >(gridView.indexSet().size(0), RangeFieldType(0))));
        if (function.numComponents() > function.numCoefficients())
          ret.push_back(std::pair< std::string, std::vector< RangeFieldType >* >(
                          name + "_component_" + Dune::Stuff::Common::toString(function.numCoefficients()),
                          new std::vector< RangeFieldType >(gridView.indexSet().size(0), RangeFieldType(0))));
      } else
        DUNE_THROW(Dune::InvalidStateException,
                   "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                   << " visualize() not yet implemented for parametric but not separable data functions!");
    } else {
      ret.push_back(std::pair< std::string, std::vector< RangeFieldType >* >(
                      name,
                      new std::vector< RangeFieldType >(gridView.indexSet().size(0), RangeFieldType(0))));
    }
    return ret;
  } // std::vector< std::pair< std::string, std::vector< RangeFieldType >* > > preparePlot(...) const

}; // class Interface

} // namespace Model
} // namespace Elliptic
} // namespace Linear
} // namespace Stationary
} // namespace Solvers
} // namespace Detailed
} // namespace Dune

#endif // DUNE_RB_MODEL_STATIONARY_LINEAR_ELLIPTIC_INTERFACE_HH
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015-2016 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * 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: Akash Bagdia
 *          David Guillen Fandos
 */

#include "sim/clocked_object.hh"

#include "base/misc.hh"
#include "sim/power/power_model.hh"

ClockedObject::ClockedObject(const ClockedObjectParams *p) :
    SimObject(p), Clocked(*p->clk_domain),
    _currPwrState(p->default_p_state),
    prvEvalTick(0)
{
    // Register the power_model with the object
    if (p->power_model)
        p->power_model->setClockedObject(this);
}

void
ClockedObject::serialize(CheckpointOut &cp) const
{
    unsigned int currPwrState = (unsigned int)_currPwrState;

    SERIALIZE_SCALAR(currPwrState);
    SERIALIZE_SCALAR(prvEvalTick);
}

void
ClockedObject::unserialize(CheckpointIn &cp)
{
    unsigned int currPwrState;

    UNSERIALIZE_SCALAR(currPwrState);
    UNSERIALIZE_SCALAR(prvEvalTick);

    _currPwrState = Enums::PwrState(currPwrState);
}

void
ClockedObject::pwrState(Enums::PwrState p)
{
    // Function should ideally be called only when there is a state change
    if (_currPwrState == p) {
        warn_once("ClockedObject: Already in the requested power state, " \
                  "request ignored");
        return;
    }

    // No need to compute stats if in the same tick, update state though. This
    // can happen in cases like a) during start of the simulation multiple
    // state changes happens in init/startup phase, b) one takes a decision to
    // migrate state but decides to reverts back to the original state in the
    // same tick if other conditions are not met elsewhere.
    // Any state change related stats would have been recorded on previous call
    // to the pwrState() function.
    if (prvEvalTick == curTick() && curTick() != 0) {
        warn("ClockedObject: More than one power state change request "\
             "encountered within the same simulation tick");
        _currPwrState = p;
        return;
    }

    // Record stats for previous state.
    computeStats();

    _currPwrState = p;

    numPwrStateTransitions++;
}

void
ClockedObject::computeStats()
{
    // Calculate time elapsed from last (valid) state change
    Tick elapsed_time = curTick() - prvEvalTick;

    pwrStateResidencyTicks[_currPwrState] += elapsed_time;

    // Time spent in CLK_GATED state, this might change depending on
    // transition to other low power states in respective simulation
    // objects.
    if (_currPwrState == Enums::PwrState::CLK_GATED) {
        pwrStateClkGateDist.sample(elapsed_time);
    }

    prvEvalTick = curTick();
}

std::vector<double>
ClockedObject::pwrStateWeights() const
{
    // Get residency stats
    std::vector<double> ret;
    Stats::VCounter residencies;
    pwrStateResidencyTicks.value(residencies);

    // Account for current state too!
    Tick elapsed_time = curTick() - prvEvalTick;
    residencies[_currPwrState] += elapsed_time;

    ret.resize(Enums::PwrState::Num_PwrState);
    for (unsigned i = 0; i < Enums::PwrState::Num_PwrState; i++)
        ret[i] = residencies[i] / \
                     (pwrStateResidencyTicks.total() + elapsed_time);

    return ret;
}

void
ClockedObject::regStats()
{
    SimObject::regStats();

    using namespace Stats;

    numPwrStateTransitions
        .name(params()->name + ".numPwrStateTransitions")
        .desc("Number of power state transitions")
        .flags(nozero)
        ;

    // Each sample is time in ticks
    unsigned num_bins = std::max(params()->p_state_clk_gate_bins, 10U);
    pwrStateClkGateDist
        .init(params()->p_state_clk_gate_min, params()->p_state_clk_gate_max,
          (params()->p_state_clk_gate_max / num_bins))
        .name(params()->name + ".pwrStateClkGateDist")
        .desc("Distribution of time spent in the clock gated state")
        .flags(pdf | nozero | nonan)
        ;

    pwrStateResidencyTicks
        .init(Enums::PwrState::Num_PwrState)
        .name(params()->name + ".pwrStateResidencyTicks")
        .desc("Cumulative time (in ticks) in various power states")
        .flags(nozero)
        ;
    for (int i = 0; i < Enums::PwrState::Num_PwrState; i++) {
        pwrStateResidencyTicks.subname(i, Enums::PwrStateStrings[i]);
    }

    numPwrStateTransitions = 0;

    /**
     * For every stats dump, the power state residency and other distribution
     * stats should be computed just before the dump to ensure correct stats
     * value being reported for current dump window. It avoids things like
     * having any unreported time spent in a power state to be forwarded to the
     * next dump window which might have rather unpleasant effects (like
     * perturbing the distribution stats).
     */
    registerDumpCallback(new ClockedObjectDumpCallback(this));
}
<commit_msg>sim: Clocked object debug message updated for clarity<commit_after>/*
 * Copyright (c) 2015-2016 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * 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: Akash Bagdia
 *          David Guillen Fandos
 */

#include "sim/clocked_object.hh"

#include "base/misc.hh"
#include "sim/power/power_model.hh"

ClockedObject::ClockedObject(const ClockedObjectParams *p) :
    SimObject(p), Clocked(*p->clk_domain),
    _currPwrState(p->default_p_state),
    prvEvalTick(0)
{
    // Register the power_model with the object
    if (p->power_model)
        p->power_model->setClockedObject(this);
}

void
ClockedObject::serialize(CheckpointOut &cp) const
{
    unsigned int currPwrState = (unsigned int)_currPwrState;

    SERIALIZE_SCALAR(currPwrState);
    SERIALIZE_SCALAR(prvEvalTick);
}

void
ClockedObject::unserialize(CheckpointIn &cp)
{
    unsigned int currPwrState;

    UNSERIALIZE_SCALAR(currPwrState);
    UNSERIALIZE_SCALAR(prvEvalTick);

    _currPwrState = Enums::PwrState(currPwrState);
}

void
ClockedObject::pwrState(Enums::PwrState p)
{
    // Function should ideally be called only when there is a state change
    if (_currPwrState == p) {
        warn_once("ClockedObject: Already in the requested power state, " \
                  "request ignored");
        return;
    }

    // No need to compute stats if in the same tick, update state though. This
    // can happen in cases like a) during start of the simulation multiple
    // state changes happens in init/startup phase, b) one takes a decision to
    // migrate state but decides to reverts back to the original state in the
    // same tick if other conditions are not met elsewhere.
    // Any state change related stats would have been recorded on previous call
    // to the pwrState() function.
    if (prvEvalTick == curTick() && curTick() != 0) {
       warn("ClockedObject %s: More than one power state change request "\
             "encountered within the same simulation tick %d",
             name(), prvEvalTick);
        _currPwrState = p;
        return;
    }

    // Record stats for previous state.
    computeStats();

    _currPwrState = p;

    numPwrStateTransitions++;
}

void
ClockedObject::computeStats()
{
    // Calculate time elapsed from last (valid) state change
    Tick elapsed_time = curTick() - prvEvalTick;

    pwrStateResidencyTicks[_currPwrState] += elapsed_time;

    // Time spent in CLK_GATED state, this might change depending on
    // transition to other low power states in respective simulation
    // objects.
    if (_currPwrState == Enums::PwrState::CLK_GATED) {
        pwrStateClkGateDist.sample(elapsed_time);
    }

    prvEvalTick = curTick();
}

std::vector<double>
ClockedObject::pwrStateWeights() const
{
    // Get residency stats
    std::vector<double> ret;
    Stats::VCounter residencies;
    pwrStateResidencyTicks.value(residencies);

    // Account for current state too!
    Tick elapsed_time = curTick() - prvEvalTick;
    residencies[_currPwrState] += elapsed_time;

    ret.resize(Enums::PwrState::Num_PwrState);
    for (unsigned i = 0; i < Enums::PwrState::Num_PwrState; i++)
        ret[i] = residencies[i] / \
                     (pwrStateResidencyTicks.total() + elapsed_time);

    return ret;
}

void
ClockedObject::regStats()
{
    SimObject::regStats();

    using namespace Stats;

    numPwrStateTransitions
        .name(params()->name + ".numPwrStateTransitions")
        .desc("Number of power state transitions")
        .flags(nozero)
        ;

    // Each sample is time in ticks
    unsigned num_bins = std::max(params()->p_state_clk_gate_bins, 10U);
    pwrStateClkGateDist
        .init(params()->p_state_clk_gate_min, params()->p_state_clk_gate_max,
          (params()->p_state_clk_gate_max / num_bins))
        .name(params()->name + ".pwrStateClkGateDist")
        .desc("Distribution of time spent in the clock gated state")
        .flags(pdf | nozero | nonan)
        ;

    pwrStateResidencyTicks
        .init(Enums::PwrState::Num_PwrState)
        .name(params()->name + ".pwrStateResidencyTicks")
        .desc("Cumulative time (in ticks) in various power states")
        .flags(nozero)
        ;
    for (int i = 0; i < Enums::PwrState::Num_PwrState; i++) {
        pwrStateResidencyTicks.subname(i, Enums::PwrStateStrings[i]);
    }

    numPwrStateTransitions = 0;

    /**
     * For every stats dump, the power state residency and other distribution
     * stats should be computed just before the dump to ensure correct stats
     * value being reported for current dump window. It avoids things like
     * having any unreported time spent in a power state to be forwarded to the
     * next dump window which might have rather unpleasant effects (like
     * perturbing the distribution stats).
     */
    registerDumpCallback(new ClockedObjectDumpCallback(this));
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: BrowseNodeFactoryImpl.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2004-10-22 14:06:15 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <rtl/ustring>
#include <cppuhelper/implbase2.hxx>

#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/uno/RuntimeException.hpp>
#include <com/sun/star/registry/XRegistryKey.hpp>

#include <com/sun/star/script/browse/XBrowseNode.hpp>
#include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
#include <com/sun/star/script/browse/XBrowseNodeFactory.hpp>

namespace browsenodefactory
{
// for simplification
#define css ::com::sun::star

class BrowseNodeFactoryImpl :
    public ::cppu::WeakImplHelper2 <
        css::script::browse::XBrowseNodeFactory,
        css::lang::XServiceInfo >
{
private:
    css::uno::Reference< css::uno::XComponentContext > m_xComponentContext;
    css::uno::Reference< css::script::browse::XBrowseNode > m_xSelectorBrowseNode;

protected:
    virtual ~BrowseNodeFactoryImpl();

public:
    BrowseNodeFactoryImpl(
        css::uno::Reference< css::uno::XComponentContext > const & xComponentContext );

    // XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName()
        throw ( css::uno::RuntimeException );

    virtual sal_Bool SAL_CALL
        supportsService( ::rtl::OUString const & serviceName )
            throw ( css::uno::RuntimeException );

    virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL
        getSupportedServiceNames()
            throw ( css::uno::RuntimeException );

    // XBrowseNodeFactory
    virtual css::uno::Reference< css::script::browse::XBrowseNode > SAL_CALL
        createView( sal_Int16 viewType )
            throw ( css::uno::RuntimeException );
    private:
    css::uno::Reference< css::script::browse::XBrowseNode >
        getSelectorHierarchy()
            throw ( css::uno::RuntimeException );

    css::uno::Reference< css::script::browse::XBrowseNode >
        getOrganizerHierarchy()
            throw ( css::uno::RuntimeException );
};

} // namespace browsenodefactory
<commit_msg>INTEGRATION: CWS ooo19126 (1.3.42); FILE MERGED 2005/09/05 12:05:18 rt 1.3.42.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: BrowseNodeFactoryImpl.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 02:28:29 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include <rtl/ustring>
#include <cppuhelper/implbase2.hxx>

#include <com/sun/star/uno/XComponentContext.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/uno/RuntimeException.hpp>
#include <com/sun/star/registry/XRegistryKey.hpp>

#include <com/sun/star/script/browse/XBrowseNode.hpp>
#include <com/sun/star/script/browse/BrowseNodeTypes.hpp>
#include <com/sun/star/script/browse/XBrowseNodeFactory.hpp>

namespace browsenodefactory
{
// for simplification
#define css ::com::sun::star

class BrowseNodeFactoryImpl :
    public ::cppu::WeakImplHelper2 <
        css::script::browse::XBrowseNodeFactory,
        css::lang::XServiceInfo >
{
private:
    css::uno::Reference< css::uno::XComponentContext > m_xComponentContext;
    css::uno::Reference< css::script::browse::XBrowseNode > m_xSelectorBrowseNode;

protected:
    virtual ~BrowseNodeFactoryImpl();

public:
    BrowseNodeFactoryImpl(
        css::uno::Reference< css::uno::XComponentContext > const & xComponentContext );

    // XServiceInfo
    virtual ::rtl::OUString SAL_CALL getImplementationName()
        throw ( css::uno::RuntimeException );

    virtual sal_Bool SAL_CALL
        supportsService( ::rtl::OUString const & serviceName )
            throw ( css::uno::RuntimeException );

    virtual css::uno::Sequence< ::rtl::OUString > SAL_CALL
        getSupportedServiceNames()
            throw ( css::uno::RuntimeException );

    // XBrowseNodeFactory
    virtual css::uno::Reference< css::script::browse::XBrowseNode > SAL_CALL
        createView( sal_Int16 viewType )
            throw ( css::uno::RuntimeException );
    private:
    css::uno::Reference< css::script::browse::XBrowseNode >
        getSelectorHierarchy()
            throw ( css::uno::RuntimeException );

    css::uno::Reference< css::script::browse::XBrowseNode >
        getOrganizerHierarchy()
            throw ( css::uno::RuntimeException );
};

} // namespace browsenodefactory
<|endoftext|>


<commit_before>/*
 * rngs
 * ECE 541 Project 2
 * Kashev Dalmia - dalmia3
 * David Huang   - huang157
 */

#include <iostream>
#include <signal.h>

#include "stl_rng.h"
#include "mt19937.h"
#include "randu.h"

using namespace std;
using namespace rng;

static RandomNumberGenerator* randgen_ptr = nullptr;

/*
 * Function for cleaning up allocated memory for the RNG.
 */
void clean_up_rng(int signum) {
    delete randgen_ptr;
    randgen_ptr = nullptr;

    exit(signum);
}

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

    unsigned int rng = 2;

    if (argc >= 2)
    {
        rng = stoi(argv[1]);
    }

    switch(rng)
    {
        case 0: { // STL RNG using std::mt19937. For testing only.
            randgen_ptr = new StlRng();
            break;
        }
        case 1: { // MT19937
            randgen_ptr = new MT19937();
            break;
        }
        case 2: { // RANDU
            randgen_ptr = new RandU();
            break;
        }
        /*
         * Add more RNG types here! Remember to update rngs.py.
         */
        default: {
            StlRng randgen = StlRng();
            randgen_ptr = &randgen;
            break;
        }
    }

    randgen_ptr->seed(42);

    /*
     * Clean Up the RNG reference when the pipe to dieharder is closed.
     * See rngs.py for more calling details.
     */
    signal(SIGPIPE, clean_up_rng);

    uint32_t x = 0;
    while(true)
    {
        x = static_cast<uint32_t>((*randgen_ptr)());
        cout.write(reinterpret_cast<const char*>(&x), sizeof x);
    }

    return 0;
}
<commit_msg>adding ctrl+c handling<commit_after>/*
 * rngs
 * ECE 541 Project 2
 * Kashev Dalmia - dalmia3
 * David Huang   - huang157
 */

#include <iostream>
#include <signal.h>

#include "stl_rng.h"
#include "mt19937.h"
#include "randu.h"

using namespace std;
using namespace rng;

static RandomNumberGenerator* randgen_ptr = nullptr;

/*
 * Function for cleaning up allocated memory for the RNG.
 */
void clean_up_rng(int signum) {
    delete randgen_ptr;
    randgen_ptr = nullptr;

    exit(signum);
}

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

    unsigned int rng = 2;

    if (argc >= 2)
    {
        rng = stoi(argv[1]);
    }

    switch(rng)
    {
        case 0: { // STL RNG using std::mt19937. For testing only.
            randgen_ptr = new StlRng();
            break;
        }
        case 1: { // MT19937
            randgen_ptr = new MT19937();
            break;
        }
        case 2: { // RANDU
            randgen_ptr = new RandU();
            break;
        }
        /*
         * Add more RNG types here! Remember to update rngs.py.
         */
        default: {
            StlRng randgen = StlRng();
            randgen_ptr = &randgen;
            break;
        }
    }

    randgen_ptr->seed(42);

    /*
     * Clean Up the RNG reference when the pipe to dieharder is closed,
     * or when the user sends ctrl+c to the program.
     * See rngs.py for more calling details.
     */
    signal(SIGPIPE, clean_up_rng);
    signal(SIGINT,  clean_up_rng);

    uint32_t x = 0;
    while(true)
    {
        x = static_cast<uint32_t>((*randgen_ptr)());
        cout.write(reinterpret_cast<const char*>(&x), sizeof x);
    }

    return 0;
}
<|endoftext|>


<commit_before>// Copyright 2010-2014 RethinkDB, all rights reserved.
#include "extproc/http_runner.hpp"

#include "extproc/http_job.hpp"
#include "containers/archive/stl_types.hpp"
#include "arch/timing.hpp"

RDB_IMPL_ME_SERIALIZABLE_3(http_opts_t::http_auth_t, 0, type, username, password);
RDB_IMPL_ME_SERIALIZABLE_14(http_opts_t, 0, auth, method, result_format, url,
                            proxy, url_params, header, data, form_data, timeout_ms,
                            attempts, max_redirects, depaginate, verify);

std::string http_method_to_str(http_method_t method) {
    switch(method) {
    case http_method_t::GET:    return std::string("GET");
    case http_method_t::HEAD:   return std::string("HEAD");
    case http_method_t::POST:   return std::string("POST");
    case http_method_t::PUT:    return std::string("PUT");
    case http_method_t::PATCH:  return std::string("PATCH");
    case http_method_t::DELETE: return std::string("DELETE");
    default:                    return std::string("UNKNOWN");
    }
}

http_opts_t::http_opts_t() :
    auth(),
    method(http_method_t::GET),
    result_format(http_result_format_t::AUTO),
    proxy(),
    url(),
    url_params(),
    header(),
    data(),
    form_data(),
    timeout_ms(30000),
    attempts(5),
    max_redirects(0),
    depaginate(false),
    verify(true) { }

http_opts_t::http_auth_t::http_auth_t() :
    type(http_auth_type_t::NONE),
    username(),
    password() { }

void http_opts_t::http_auth_t::make_basic_auth(std::string &&user,
                                               std::string &&pass) {
    type = http_auth_type_t::BASIC;
    username.assign(std::move(user));
    password.assign(std::move(pass));
}

void http_opts_t::http_auth_t::make_digest_auth(std::string &&user,
                                                std::string &&pass) {
    type = http_auth_type_t::DIGEST;
    username.assign(std::move(user));
    password.assign(std::move(pass));
}

http_runner_t::http_runner_t(extproc_pool_t *_pool) :
    pool(_pool) { }

http_result_t http_runner_t::http(const http_opts_t *opts,
                                  signal_t *interruptor) {
    signal_timer_t timeout;
    wait_any_t combined_interruptor(interruptor, &timeout);
    http_job_t job(pool, &combined_interruptor);

    assert_thread();
    timeout.start(opts->timeout_ms);

    try {
        return job.http(opts);
    } catch (...) {
        // This will mark the worker as errored so we don't try to re-sync with it
        //  on the next line (since we're in a catch statement, we aren't allowed)
        job.worker_error();
        throw;
    }
}

<commit_msg>Removed version zero info on serialize macros in http_runner.cc.<commit_after>// Copyright 2010-2014 RethinkDB, all rights reserved.
#include "extproc/http_runner.hpp"

#include "extproc/http_job.hpp"
#include "containers/archive/stl_types.hpp"
#include "arch/timing.hpp"

RDB_IMPL_ME_SERIALIZABLE_3(http_opts_t::http_auth_t, type, username, password);
RDB_IMPL_ME_SERIALIZABLE_14(http_opts_t, auth, method, result_format, url,
                            proxy, url_params, header, data, form_data, timeout_ms,
                            attempts, max_redirects, depaginate, verify);

std::string http_method_to_str(http_method_t method) {
    switch(method) {
    case http_method_t::GET:    return std::string("GET");
    case http_method_t::HEAD:   return std::string("HEAD");
    case http_method_t::POST:   return std::string("POST");
    case http_method_t::PUT:    return std::string("PUT");
    case http_method_t::PATCH:  return std::string("PATCH");
    case http_method_t::DELETE: return std::string("DELETE");
    default:                    return std::string("UNKNOWN");
    }
}

http_opts_t::http_opts_t() :
    auth(),
    method(http_method_t::GET),
    result_format(http_result_format_t::AUTO),
    proxy(),
    url(),
    url_params(),
    header(),
    data(),
    form_data(),
    timeout_ms(30000),
    attempts(5),
    max_redirects(0),
    depaginate(false),
    verify(true) { }

http_opts_t::http_auth_t::http_auth_t() :
    type(http_auth_type_t::NONE),
    username(),
    password() { }

void http_opts_t::http_auth_t::make_basic_auth(std::string &&user,
                                               std::string &&pass) {
    type = http_auth_type_t::BASIC;
    username.assign(std::move(user));
    password.assign(std::move(pass));
}

void http_opts_t::http_auth_t::make_digest_auth(std::string &&user,
                                                std::string &&pass) {
    type = http_auth_type_t::DIGEST;
    username.assign(std::move(user));
    password.assign(std::move(pass));
}

http_runner_t::http_runner_t(extproc_pool_t *_pool) :
    pool(_pool) { }

http_result_t http_runner_t::http(const http_opts_t *opts,
                                  signal_t *interruptor) {
    signal_timer_t timeout;
    wait_any_t combined_interruptor(interruptor, &timeout);
    http_job_t job(pool, &combined_interruptor);

    assert_thread();
    timeout.start(opts->timeout_ms);

    try {
        return job.http(opts);
    } catch (...) {
        // This will mark the worker as errored so we don't try to re-sync with it
        //  on the next line (since we're in a catch statement, we aren't allowed)
        job.worker_error();
        throw;
    }
}

<|endoftext|>


<commit_before>#include "stdafx.h"
#include "renderer.h"

Renderer::Renderer(bool useSwapChain)
{
    _renderDeferred = false;
    _isInitialized = false;
    _useSwapChain = useSwapChain;
    _rasterizerUseMultiSampling = true;
    _bufferCount = 2;
    _swapChainFlags = 0;
    _renderTarget = DeferredTarget::Create(Res::Get()->RenderQuality);
}

HRESULT Renderer::Initialize()
{
    _isInitialized = false;

    auto result = CreateSwapChain();
    if (FAILED(result))
    {
        return result;
    }

    result = CreateRasterizer();
    if (FAILED(result))
    {
        return result;
    }

    result = CreateViewPort();
    if (FAILED(result))
    {
        return result;
    }

    _isInitialized = true;
    return result;
}

HRESULT Renderer::CreateSwapChainDesciption()
{
    _swapChainDescription = { 0 };

    _swapChainDescription.BufferCount = _bufferCount;
    _swapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;

    _swapChainDescription.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    _swapChainDescription.Flags = _swapChainFlags;

    _swapChainDescription.BufferDesc.RefreshRate.Numerator = 0;
    _swapChainDescription.BufferDesc.RefreshRate.Denominator = 1;
    _swapChainDescription.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
    _swapChainDescription.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

    _swapChainDescription.SampleDesc.Quality = Res::Get()->RenderQuality->Quality;
    _swapChainDescription.SampleDesc.Count = Res::Get()->RenderQuality->SampleCount;
    _swapChainDescription.BufferDesc.Format = Res::Get()->RenderQuality->DephStencilTextureFormat;
    _swapChainDescription.BufferDesc.Width = Res::Get()->RenderQuality->Width;
    _swapChainDescription.BufferDesc.Height = Res::Get()->RenderQuality->Height;

    auto handle = *Res::Get()->WindowHandle;
    _swapChainDescription.OutputWindow = handle;

    if (Res::Get()->FullScreen)
    {
        _swapChainDescription.Windowed = false;
    }
    else
    {
        _swapChainDescription.Windowed = true;
    }
    return 0;
}

HRESULT Renderer::CreateSwapChain()
{
    auto result = CreateSwapChainDesciption();
    if (FAILED(result))
    {
        return result;
    }

    IDXGIDevice *dxgiDevice = 0;
    IDXGIAdapter *dxgiAdapter = 0;
    IDXGIFactory *dxgiFactory = 0;

    result = Res::Get()->Device->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgiDevice);
    if (FAILED(result))
    {
        return result;
    }

    result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&dxgiAdapter);
    if (FAILED(result))
    {
        return result;
    }

    result = dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void **)&dxgiFactory);
    if (FAILED(result))
    {
        return result;
    }

    result = dxgiFactory->CreateSwapChain(Res::Get()->Device, &_swapChainDescription, &_swapChain);
    if (FAILED(result))
    {
        return result;
    }

    result = _swapChain->GetBuffer(0, IID_PPV_ARGS(&_backBufferTexture));
    if (FAILED(result))
    {
        return result;
    }

    dxgiDevice->Release();
    dxgiAdapter->Release();
    dxgiFactory->Release();

    auto quality = new RenderingQuality();
    quality->TextureFormat = _swapChainDescription.BufferDesc.Format;

    _backBufferTarget = D3DHelpers::CreateRenderTarget(_backBufferTexture, D3D11_RTV_DIMENSION_TEXTURE2DMS, quality);
    return 0;
}

HRESULT Renderer::CreateRasterizerDescription()
{
    auto isRightHand = false;

    _rasterizerDesc.AntialiasedLineEnable = _rasterizerUseMultiSampling;
    _rasterizerDesc.DepthBias = 0;
    _rasterizerDesc.DepthBiasClamp = 0.0f;
    _rasterizerDesc.DepthClipEnable = true;
    _rasterizerDesc.FillMode = D3D11_FILL_SOLID;

    _rasterizerDesc.MultisampleEnable = _rasterizerUseMultiSampling;
    _rasterizerDesc.ScissorEnable = false;
    _rasterizerDesc.SlopeScaledDepthBias = 0.0f;

    _rasterizerDesc.CullMode = D3D11_CULL_BACK;//D3D11_CULL_NONE;//
    _rasterizerDesc.FrontCounterClockwise = true;

    return 0;
}

HRESULT Renderer::CreateRasterizer()
{
    auto result = CreateRasterizerDescription();
    if (FAILED(result))
    {
        return result;
    }

    result = Res::Get()->Device->CreateRasterizerState(&_rasterizerDesc, &Res::Get()->RasterizerState);
    if (FAILED(result))
    {
        return result;
    }

    Res::Get()->DeviceContext->RSSetState(Res::Get()->RasterizerState);

    return 0;
}

HRESULT Renderer::CreateViewPort()
{
    auto viewPort = Res::Get()->ViewPort;
    Res::Get()->DeviceContext->RSSetViewports(1, viewPort);
    return 0;
}

void Renderer::ClearScene()
{
    _renderTarget->ClearRenderTargets();
}

void Renderer::Render(Scene *scene)
{
    if (!_isInitialized)
    {
        return;
    }

    ClearScene();

    Res::Get()->DeviceContext->ClearRenderTargetView(_backBufferTarget, Res::Get()->DefaultColor);

    for (unsigned int m = 0; m < scene->GetModels()->size(); m++)
    {
        auto model = scene->GetModels()->at(m);
        auto material = model.GetMaterial();
        auto shaders = material->GetShaders();

        unsigned int offset = 0;

        auto vertexBuffer = model.GetVertexBuffer();
        auto strides = shaders->VertexShader->GetInputSize();
        auto indexBuffer = model.GetIndexBuffer();

        Res::Get()->DeviceContext->IASetInputLayout(shaders->VertexShader->GetInputLayout());
        Res::Get()->DeviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &strides, &offset);
        Res::Get()->DeviceContext->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0);
        Res::Get()->DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

        auto vertexShader = shaders->VertexShader;
        if (vertexShader)
        {
            vertexShader->Render();
        }

        auto hullShader = shaders->HullShader;
        if (hullShader)
        {
            hullShader->Render();
        }

        auto domainShader = shaders->DomainShader;
        if (domainShader)
        {
            domainShader->Render();
        }

        auto geometryShader = shaders->GeometryShader;
        if (geometryShader)
        {
            geometryShader->Render();
        }

        // To stream output

        auto pixelshader = shaders->PixelShader;
        if (pixelshader)
        {
            pixelshader->Render();
        }

        Res::Get()->DeviceContext->OMSetRenderTargets(1, &_backBufferTarget, _renderTarget->GetDepthStencilView());
        Res::Get()->DeviceContext->DrawIndexed(model.GetIndexCount(), 0, 0);
    }

    auto postProcessor = scene->GetPostProcessor();
    if (postProcessor)
    {
        postProcessor->Render();
    }

    _swapChain->Present(1, 0);
}

void Renderer::Tesselate(Shaders *shaders)
{
    if (!shaders->HullShader || !shaders->DomainShader)
    {
        return;
    }
}

void Renderer::Resize()
{
    Initialize();
}<commit_msg>dunno why swap chain is null sometimes o.O<commit_after>#include "stdafx.h"
#include "renderer.h"

Renderer::Renderer(bool useSwapChain)
{
    _renderDeferred = false;
    _isInitialized = false;
    _useSwapChain = useSwapChain;
    _rasterizerUseMultiSampling = true;
    _bufferCount = 2;
    _swapChainFlags = 0;
    _renderTarget = DeferredTarget::Create(Res::Get()->RenderQuality);
}

HRESULT Renderer::Initialize()
{
    _isInitialized = false;

    auto result = CreateSwapChain();
    if (FAILED(result))
    {
        return result;
    }

    result = CreateRasterizer();
    if (FAILED(result))
    {
        return result;
    }

    result = CreateViewPort();
    if (FAILED(result))
    {
        return result;
    }

    _isInitialized = true;
    return result;
}

HRESULT Renderer::CreateSwapChainDesciption()
{
    _swapChainDescription = { 0 };

    _swapChainDescription.BufferCount = _bufferCount;
    _swapChainDescription.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;

    _swapChainDescription.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
    _swapChainDescription.Flags = _swapChainFlags;

    _swapChainDescription.BufferDesc.RefreshRate.Numerator = 0;
    _swapChainDescription.BufferDesc.RefreshRate.Denominator = 1;
    _swapChainDescription.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
    _swapChainDescription.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;

    _swapChainDescription.SampleDesc.Quality = Res::Get()->RenderQuality->Quality;
    _swapChainDescription.SampleDesc.Count = Res::Get()->RenderQuality->SampleCount;
    _swapChainDescription.BufferDesc.Format = Res::Get()->RenderQuality->DephStencilTextureFormat;
    _swapChainDescription.BufferDesc.Width = Res::Get()->RenderQuality->Width;
    _swapChainDescription.BufferDesc.Height = Res::Get()->RenderQuality->Height;

    auto handle = *Res::Get()->WindowHandle;
    _swapChainDescription.OutputWindow = handle;

    if (Res::Get()->FullScreen)
    {
        _swapChainDescription.Windowed = false;
    }
    else
    {
        _swapChainDescription.Windowed = true;
    }
    return 0;
}

HRESULT Renderer::CreateSwapChain()
{
    auto result = CreateSwapChainDesciption();
    if (FAILED(result))
    {
        return result;
    }

    IDXGIDevice *dxgiDevice = 0;
    IDXGIAdapter *dxgiAdapter = 0;
    IDXGIFactory *dxgiFactory = 0;

    result = Res::Get()->Device->QueryInterface(__uuidof(IDXGIDevice), (void **)&dxgiDevice);
    if (FAILED(result))
    {
        return result;
    }

    result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&dxgiAdapter);
    if (FAILED(result))
    {
        return result;
    }

    result = dxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void **)&dxgiFactory);
    if (FAILED(result))
    {
        return result;
    }

    result = dxgiFactory->CreateSwapChain(Res::Get()->Device, &_swapChainDescription, &_swapChain);
    if (FAILED(result))
    {
        return result;
    }

    result = _swapChain->GetBuffer(0, IID_PPV_ARGS(&_backBufferTexture));
    if (FAILED(result))
    {
        return result;
    }

    dxgiDevice->Release();
    dxgiAdapter->Release();
    dxgiFactory->Release();

    auto quality = new RenderingQuality();
    quality->TextureFormat = _swapChainDescription.BufferDesc.Format;

    _backBufferTarget = D3DHelpers::CreateRenderTarget(_backBufferTexture, D3D11_RTV_DIMENSION_TEXTURE2DMS, quality);
    return 0;
}

HRESULT Renderer::CreateRasterizerDescription()
{
    auto isRightHand = false;

    _rasterizerDesc.AntialiasedLineEnable = _rasterizerUseMultiSampling;
    _rasterizerDesc.DepthBias = 0;
    _rasterizerDesc.DepthBiasClamp = 0.0f;
    _rasterizerDesc.DepthClipEnable = true;
    _rasterizerDesc.FillMode = D3D11_FILL_SOLID;

    _rasterizerDesc.MultisampleEnable = _rasterizerUseMultiSampling;
    _rasterizerDesc.ScissorEnable = false;
    _rasterizerDesc.SlopeScaledDepthBias = 0.0f;

    _rasterizerDesc.CullMode = D3D11_CULL_BACK;//D3D11_CULL_NONE;//
    _rasterizerDesc.FrontCounterClockwise = true;

    return 0;
}

HRESULT Renderer::CreateRasterizer()
{
    auto result = CreateRasterizerDescription();
    if (FAILED(result))
    {
        return result;
    }

    result = Res::Get()->Device->CreateRasterizerState(&_rasterizerDesc, &Res::Get()->RasterizerState);
    if (FAILED(result))
    {
        return result;
    }

    Res::Get()->DeviceContext->RSSetState(Res::Get()->RasterizerState);

    return 0;
}

HRESULT Renderer::CreateViewPort()
{
    auto viewPort = Res::Get()->ViewPort;
    Res::Get()->DeviceContext->RSSetViewports(1, viewPort);
    return 0;
}

void Renderer::ClearScene()
{
    _renderTarget->ClearRenderTargets();
}

void Renderer::Render(Scene *scene)
{
    if (!_isInitialized)
    {
        return;
    }

    ClearScene();

    Res::Get()->DeviceContext->ClearRenderTargetView(_backBufferTarget, Res::Get()->DefaultColor);

    for (unsigned int m = 0; m < scene->GetModels()->size(); m++)
    {
        auto model = scene->GetModels()->at(m);
        auto material = model.GetMaterial();
        auto shaders = material->GetShaders();

        unsigned int offset = 0;

        auto vertexBuffer = model.GetVertexBuffer();
        auto strides = shaders->VertexShader->GetInputSize();
        auto indexBuffer = model.GetIndexBuffer();

        Res::Get()->DeviceContext->IASetInputLayout(shaders->VertexShader->GetInputLayout());
        Res::Get()->DeviceContext->IASetVertexBuffers(0, 1, &vertexBuffer, &strides, &offset);
        Res::Get()->DeviceContext->IASetIndexBuffer(indexBuffer, DXGI_FORMAT_R32_UINT, 0);
        Res::Get()->DeviceContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

        auto vertexShader = shaders->VertexShader;
        if (vertexShader)
        {
            vertexShader->Render();
        }

        auto hullShader = shaders->HullShader;
        if (hullShader)
        {
            hullShader->Render();
        }

        auto domainShader = shaders->DomainShader;
        if (domainShader)
        {
            domainShader->Render();
        }

        auto geometryShader = shaders->GeometryShader;
        if (geometryShader)
        {
            geometryShader->Render();
        }

        // To stream output

        auto pixelshader = shaders->PixelShader;
        if (pixelshader)
        {
            pixelshader->Render();
        }

        Res::Get()->DeviceContext->OMSetRenderTargets(1, &_backBufferTarget, _renderTarget->GetDepthStencilView());
        Res::Get()->DeviceContext->DrawIndexed(model.GetIndexCount(), 0, 0);
    }

    auto postProcessor = scene->GetPostProcessor();
    if (postProcessor)
    {
        postProcessor->Render();
    }

    if (!_swapChain)
    {
        return;
    }
    _swapChain->Present(1, 0);
}

void Renderer::Tesselate(Shaders *shaders)
{
    if (!shaders->HullShader || !shaders->DomainShader)
    {
        return;
    }
}

void Renderer::Resize()
{
    Initialize();
}<|endoftext|>


<commit_before>/*
 * Copyright (c) 2012-2013 ARM Limited
 * Copyright (c) 2013 Cornell University
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * 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: Andreas Hansson
 *          Christopher Torng
 */

/**
 * @file
 * ClockedObject declaration and implementation.
 */

#ifndef __SIM_CLOCKED_OBJECT_HH__
#define __SIM_CLOCKED_OBJECT_HH__

#include "base/intmath.hh"
#include "base/misc.hh"
#include "params/ClockedObject.hh"
#include "sim/core.hh"
#include "sim/clock_domain.hh"
#include "sim/sim_object.hh"

/**
 * The ClockedObject class extends the SimObject with a clock and
 * accessor functions to relate ticks to the cycles of the object.
 */
class ClockedObject : public SimObject
{

  private:

    // the tick value of the next clock edge (>= curTick()) at the
    // time of the last call to update()
    mutable Tick tick;

    // The cycle counter value corresponding to the current value of
    // 'tick'
    mutable Cycles cycle;

    /**
     * Prevent inadvertent use of the copy constructor and assignment
     * operator by making them private.
     */
    ClockedObject(ClockedObject&);
    ClockedObject& operator=(ClockedObject&);

    /**
     *  Align cycle and tick to the next clock edge if not already done.
     */
    void update() const
    {
        // both tick and cycle are up-to-date and we are done, note
        // that the >= is important as it captures cases where tick
        // has already passed curTick()
        if (tick >= curTick())
            return;

        // optimise for the common case and see if the tick should be
        // advanced by a single clock period
        tick += clockPeriod();
        ++cycle;

        // see if we are done at this point
        if (tick >= curTick())
            return;

        // if not, we have to recalculate the cycle and tick, we
        // perform the calculations in terms of relative cycles to
        // allow changes to the clock period in the future
        Cycles elapsedCycles(divCeil(curTick() - tick, clockPeriod()));
        cycle += elapsedCycles;
        tick += elapsedCycles * clockPeriod();
    }

    /**
     * The clock domain this clocked object belongs to
     */
    ClockDomain &clockDomain;

  protected:

    /**
     * Create a clocked object and set the clock domain based on the
     * parameters.
     */
    ClockedObject(const ClockedObjectParams* p) :
        SimObject(p), tick(0), cycle(0), clockDomain(*p->clk_domain)
    {
        // Register with the clock domain, so that if the clock domain
        // frequency changes, we can update this object's tick.
        clockDomain.registerWithClockDomain(this);
    }

    /**
     * Virtual destructor due to inheritance.
     */
    virtual ~ClockedObject() { }

    /**
     * Reset the object's clock using the current global tick value. Likely
     * to be used only when the global clock is reset. Currently, this done
     * only when Ruby is done warming up the memory system.
     */
    void resetClock() const
    {
        Cycles elapsedCycles(divCeil(curTick(), clockPeriod()));
        cycle = elapsedCycles;
        tick = elapsedCycles * clockPeriod();
    }

  public:

    /**
     * Update the tick to the current tick.
     *
     */
    inline void updateClockPeriod() const
    {
        update();
    }

    /**
     * Determine the tick when a cycle begins, by default the current
     * one, but the argument also enables the caller to determine a
     * future cycle.
     *
     * @param cycles The number of cycles into the future
     *
     * @return The tick when the clock edge occurs
     */
    inline Tick clockEdge(Cycles cycles = Cycles(0)) const
    {
        // align tick to the next clock edge
        update();

        // figure out when this future cycle is
        return tick + clockPeriod() * cycles;
    }

    /**
     * Determine the current cycle, corresponding to a tick aligned to
     * a clock edge.
     *
     * @return The current cycle count
     */
    inline Cycles curCycle() const
    {
        // align cycle to the next clock edge.
        update();

        return cycle;
    }

    /**
     * Based on the clock of the object, determine the tick when the next
     * cycle begins, in other words, return the next clock edge.
     * (This can never be the current tick.)
     *
     * @return The tick when the next cycle starts
     */
    Tick nextCycle() const
    { return clockEdge(Cycles(1)); }

    inline uint64_t frequency() const
    {
        return SimClock::Frequency / clockPeriod();
    }

    inline Tick clockPeriod() const
    {
        return clockDomain.clockPeriod();
    }

    inline Cycles ticksToCycles(Tick t) const
    { return Cycles(divCeil(t, clockPeriod())); }

};

#endif //__SIM_CLOCKED_OBJECT_HH__
<commit_msg>sim: More rigorous clocking comments<commit_after>/*
 * Copyright (c) 2012-2013 ARM Limited
 * Copyright (c) 2013 Cornell University
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * 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: Andreas Hansson
 *          Christopher Torng
 */

/**
 * @file
 * ClockedObject declaration and implementation.
 */

#ifndef __SIM_CLOCKED_OBJECT_HH__
#define __SIM_CLOCKED_OBJECT_HH__

#include "base/intmath.hh"
#include "base/misc.hh"
#include "params/ClockedObject.hh"
#include "sim/core.hh"
#include "sim/clock_domain.hh"
#include "sim/sim_object.hh"

/**
 * The ClockedObject class extends the SimObject with a clock and
 * accessor functions to relate ticks to the cycles of the object.
 */
class ClockedObject : public SimObject
{

  private:

    // the tick value of the next clock edge (>= curTick()) at the
    // time of the last call to update()
    mutable Tick tick;

    // The cycle counter value corresponding to the current value of
    // 'tick'
    mutable Cycles cycle;

    /**
     * Prevent inadvertent use of the copy constructor and assignment
     * operator by making them private.
     */
    ClockedObject(ClockedObject&);
    ClockedObject& operator=(ClockedObject&);

    /**
     *  Align cycle and tick to the next clock edge if not already done. When
     *  complete, tick must be at least curTick().
     */
    void update() const
    {
        // both tick and cycle are up-to-date and we are done, note
        // that the >= is important as it captures cases where tick
        // has already passed curTick()
        if (tick >= curTick())
            return;

        // optimise for the common case and see if the tick should be
        // advanced by a single clock period
        tick += clockPeriod();
        ++cycle;

        // see if we are done at this point
        if (tick >= curTick())
            return;

        // if not, we have to recalculate the cycle and tick, we
        // perform the calculations in terms of relative cycles to
        // allow changes to the clock period in the future
        Cycles elapsedCycles(divCeil(curTick() - tick, clockPeriod()));
        cycle += elapsedCycles;
        tick += elapsedCycles * clockPeriod();
    }

    /**
     * The clock domain this clocked object belongs to
     */
    ClockDomain &clockDomain;

  protected:

    /**
     * Create a clocked object and set the clock domain based on the
     * parameters.
     */
    ClockedObject(const ClockedObjectParams* p) :
        SimObject(p), tick(0), cycle(0), clockDomain(*p->clk_domain)
    {
        // Register with the clock domain, so that if the clock domain
        // frequency changes, we can update this object's tick.
        clockDomain.registerWithClockDomain(this);
    }

    /**
     * Virtual destructor due to inheritance.
     */
    virtual ~ClockedObject() { }

    /**
     * Reset the object's clock using the current global tick value. Likely
     * to be used only when the global clock is reset. Currently, this done
     * only when Ruby is done warming up the memory system.
     */
    void resetClock() const
    {
        Cycles elapsedCycles(divCeil(curTick(), clockPeriod()));
        cycle = elapsedCycles;
        tick = elapsedCycles * clockPeriod();
    }

  public:

    /**
     * Update the tick to the current tick.
     *
     */
    inline void updateClockPeriod() const
    {
        update();
    }

    /**
     * Determine the tick when a cycle begins, by default the current one, but
     * the argument also enables the caller to determine a future cycle. When
     * curTick() is on a clock edge, the number of cycles in the parameter is
     * added to curTick() to be returned. When curTick() is not aligned to a
     * clock edge, the number of cycles in the parameter is added to the next
     * clock edge.
     *
     * @param cycles The number of cycles into the future
     *
     * @return The start tick when the requested clock edge occurs. Precisely,
     * this tick can be
     *     curTick() + [0, clockPeriod()) + clockPeriod() * cycles
     */
    inline Tick clockEdge(Cycles cycles = Cycles(0)) const
    {
        // align tick to the next clock edge
        update();

        // figure out when this future cycle is
        return tick + clockPeriod() * cycles;
    }

    /**
     * Determine the current cycle, corresponding to a tick aligned to
     * a clock edge.
     *
     * @return When curTick() is on a clock edge, return the Cycle corresponding
     * to that clock edge. When curTick() is not on a clock edge, return the
     * Cycle corresponding to the next clock edge.
     */
    inline Cycles curCycle() const
    {
        // align cycle to the next clock edge.
        update();

        return cycle;
    }

    /**
     * Based on the clock of the object, determine the start tick of the first
     * cycle that is at least one cycle in the future. When curTick() is at the
     * current cycle edge, this returns the next clock edge. When calling this
     * during the middle of a cycle, this returns 2 clock edges in the future.
     *
     * @return The start tick of the first cycle that is at least one cycle in
     * the future. Precisely, the returned tick can be in the range
     *     curTick() + [clockPeriod(), 2 * clockPeriod())
     */
    Tick nextCycle() const
    { return clockEdge(Cycles(1)); }

    inline uint64_t frequency() const
    {
        return SimClock::Frequency / clockPeriod();
    }

    inline Tick clockPeriod() const
    {
        return clockDomain.clockPeriod();
    }

    inline Cycles ticksToCycles(Tick t) const
    { return Cycles(divCeil(t, clockPeriod())); }

};

#endif //__SIM_CLOCKED_OBJECT_HH__
<|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS dba205c (1.4.10); FILE MERGED 2006/10/09 12:11:03 fs 1.4.10.2: no UTF-8 encoding for registry directory, use UCS2/Unicode directly Issue number:  #i69327# Submitted by:  rvojta@openoffice.org Reviewed by:   fs@openoffice.org 2006/10/09 12:09:29 fs 1.4.10.1: moving changes from dba205b herein, in preparation of #i69327#<commit_after><|endoftext|>