<commit_before>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_SPACE_DISCONTINUOUSLAGRANGE_FEM_LOCALFUNCTIONS_HH
#define DUNE_GDT_SPACE_DISCONTINUOUSLAGRANGE_FEM_LOCALFUNCTIONS_HH

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

#include <dune/common/static_assert.hh>
#include <dune/common/typetraits.hh>
#include <dune/common/exceptions.hh>

#include <dune/grid/sgrid.hh>
#include <dune/grid/yaspgrid.hh>
#include <dune/grid/alugrid.hh>

#include <dune/localfunctions/lagrange/equidistantpoints.hh>
#include <dune/localfunctions/lagrange.hh>

#include <dune/fem/space/common/allgeomtypes.hh>

#include <dune/fem_localfunctions/localfunctions/transformations.hh>
#include <dune/fem_localfunctions/basefunctions/genericbasefunctionsetstorage.hh>
#include <dune/fem_localfunctions/basefunctionsetmap/basefunctionsetmap.hh>
#include <dune/fem_localfunctions/space/genericdiscretefunctionspace.hh>

#include <dune/stuff/common/color.hh>

#include "../../mapper/fem.hh"
#include "../../basefunctionset/fem-localfunctions.hh"
#include "../constraints.hh"
#include "../interface.hh"

namespace Dune {
namespace GDT {
namespace DiscontinuousLagrangeSpace {

// forward, to be used in the traits and to allow for specialization
template< class GridPartImp, int polynomialOrder, class RangeFieldImp, int rangeDim, int rangeDimCols = 1 >
class FemLocalfunctionsWrapper;

// forward, to allow for specialization
template< class GridPartImp, int polynomialOrder, class RangeFieldImp, int rangeDim, int rangeDimCols = 1 >
class FemLocalfunctionsWrapperTraits;

/**
 *  \brief Traits class for ContinuousLagrangeSpace for dimRange 1x1.
 */
template< class GridPartImp, int polynomialOrder, class RangeFieldImp >
class FemLocalfunctionsWrapperTraits< GridPartImp, polynomialOrder, RangeFieldImp, 1, 1 >
{
public:
  typedef GridPartImp                   GridPartType;
  static const int                      polOrder = polynomialOrder;
  dune_static_assert((polOrder >= 1), "ERROR: wrong polOrder given!");
private:
  typedef typename GridPartType::ctype  DomainFieldType;
  static const unsigned int             dimDomain = GridPartType::dimension;
public:
  typedef RangeFieldImp                 RangeFieldType;
  static const unsigned int             dimRange = 1;
  static const unsigned int             dimRangeCols = 1;
  typedef FemLocalfunctionsWrapper< GridPartType, polOrder, RangeFieldType, dimRange, dimRangeCols > derived_type;
//  typedef FemLocalfunctionsWrapperTraits< GridPartType, polOrder, RangeFieldType, dimRange, dimRangeCols > ThisType;
  typedef Dune::LagrangeLocalFiniteElement< Dune::EquidistantPointSet,
                                            dimDomain,
                                            DomainFieldType,
                                            RangeFieldType > ContinuousFiniteElementType;
  typedef Dune::DGLocalFiniteElement< ContinuousFiniteElementType > FiniteElementType;
private:
  typedef Dune::FemLocalFunctions::BaseFunctionSetMap<  GridPartType,
                                                        FiniteElementType,
                                                        Dune::FemLocalFunctions::NoTransformation,
                                                        Dune::FemLocalFunctions::SimpleStorage,
                                                        polOrder,
                                                        polOrder >  BaseFunctionSetMapType;
public:
  typedef Dune::FemLocalFunctions::DiscreteFunctionSpace< BaseFunctionSetMapType >  BackendType;
  typedef Mapper::FemDofWrapper< typename BackendType::MapperType >                 MapperType;
  typedef BaseFunctionSet::FemLocalfunctionsWrapper< BaseFunctionSetMapType,
              DomainFieldType, dimDomain, RangeFieldType, dimRange, dimRangeCols >  BaseFunctionSetType;
  typedef typename BaseFunctionSetType::EntityType                                  EntityType;
private:
  template< class G, int p, class R, int r, int rC >
  friend class FemLocalfunctionsWrapper;
}; // class FemLocalfunctionsWrapperTraits< ..., 1, 1 >

template< class GridPartImp, int polynomialOrder, class RangeFieldImp >
class FemLocalfunctionsWrapper< GridPartImp, polynomialOrder, RangeFieldImp, 1, 1 >
  : public SpaceInterface< FemLocalfunctionsWrapperTraits< GridPartImp, polynomialOrder, RangeFieldImp, 1, 1 > >
{
  typedef SpaceInterface< FemLocalfunctionsWrapperTraits< GridPartImp, polynomialOrder, RangeFieldImp, 1, 1 > > BaseType;
public:
  typedef FemLocalfunctionsWrapperTraits< GridPartImp, polynomialOrder, RangeFieldImp, 1, 1 > Traits;

  typedef typename Traits::GridPartType   GridPartType;
  typedef typename GridPartType::ctype    DomainFieldType;
  static const int                        polOrder = Traits::polOrder;
  static const unsigned int               dimDomain = GridPartType::dimension;
  typedef typename Traits::RangeFieldType RangeFieldType;
  static const unsigned int               dimRange = Traits::dimRange;
  static const unsigned int               dimRangeCols = Traits::dimRangeCols;

  typedef typename Traits::BackendType          BackendType;
  typedef typename Traits::MapperType           MapperType;
  typedef typename Traits::BaseFunctionSetType  BaseFunctionSetType;
  typedef typename Traits::EntityType           EntityType;

  typedef Dune::Stuff::LA::SparsityPatternDefault PatternType;

private:
  typedef typename Traits::BaseFunctionSetMapType BaseFunctionSetMapType;

public:
  FemLocalfunctionsWrapper(const GridPartType& gridP)
    : gridPart_(assertGridPart(gridP))
    , baseFunctionSetMap_(gridPart_)
    , backend_(const_cast< GridPartType& >(gridPart_), baseFunctionSetMap_)
    , mapper_(backend_.mapper())
  {}

  ~FemLocalfunctionsWrapper() {}

  const GridPartType& gridPart() const
  {
    return gridPart_;
  }

  const BackendType& backend() const
  {
    return backend_;
  }

  bool continuous() const
  {
    return true;
  }

  const MapperType& mapper() const
  {
    return mapper_;
  }

  BaseFunctionSetType baseFunctionSet(const EntityType& entity) const
  {
    return BaseFunctionSetType(baseFunctionSetMap_, entity);
  }

  template< class R >
  void localConstraints(const EntityType& /*entity*/,
                        Constraints::LocalDefault< R >& /*ret*/) const
  {
    dune_static_assert(Dune::AlwaysFalse< R >::value, "ERROR: not implemented for arbitrary constraints!");
  }

  using BaseType::computePattern;

  template< class LocalGridPartType, class OtherSpaceType >
  PatternType* computePattern(const LocalGridPartType& localGridPart,
                              const OtherSpaceType& otherSpace) const
  {
    return BaseType::computeVolumeAndCouplingPattern(localGridPart, otherSpace);
  }

private:
  static const GridPartType& assertGridPart(const GridPartType& gP)
  {
    // static grid check
    typedef typename GridPartType::GridType GridType;
#if HAVE_ALUGRID
    dune_static_assert(!(Dune::is_same< GridType, Dune::ALUCubeGrid< dimDomain, dimDomain > >::value),
                       "This space is only implemented for simplicial grids!");
#endif
    dune_static_assert(!(Dune::is_same< GridType, Dune::SGrid< dimDomain, dimDomain > >::value),
                       "This space is only implemented for simplicial grids!");
    dune_static_assert(!(Dune::is_same< GridType, Dune::YaspGrid< dimDomain > >::value),
                       "This space is only implemented for simplicial grids!");
    // dynamic gridpart check
    typedef typename Dune::Fem::AllGeomTypes< typename GridPartType::IndexSetType,
                                              typename GridPartType::GridType > AllGeometryTypes;
    const AllGeometryTypes allGeometryTypes(gP.indexSet());
    const std::vector< Dune::GeometryType >& geometryTypes = allGeometryTypes.geomTypes(0);
    if (!(geometryTypes.size() == 1 && geometryTypes[0].isSimplex()))
      DUNE_THROW(Dune::NotImplemented,
                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                 << " this space is only implemented for simplicial grids!");
    return gP;
  } // ... assertGridPart(...)

  const GridPartType& gridPart_;
  BaseFunctionSetMapType baseFunctionSetMap_;
  const BackendType backend_;
  const MapperType mapper_;
}; // class FemLocalfunctionsWrapper< ..., 1, 1 >

} // namespace DiscontinuousLagrangeSpace
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_SPACE_DISCONTINUOUSLAGRANGE_FEM_LOCALFUNCTIONS_HH
<commit_msg>[space.discontinuouslagrange.fem-localfunctions] major update Updated to new requirements and made copyable.<commit_after>// This file is part of the dune-gdt project:
//   http://users.dune-project.org/projects/dune-gdt
// Copyright holders: Felix Albrecht
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_GDT_SPACE_DISCONTINUOUSLAGRANGE_FEM_LOCALFUNCTIONS_HH
#define DUNE_GDT_SPACE_DISCONTINUOUSLAGRANGE_FEM_LOCALFUNCTIONS_HH

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

#include <dune/common/static_assert.hh>
#include <dune/common/typetraits.hh>
#include <dune/common/exceptions.hh>

#include <dune/grid/sgrid.hh>
#include <dune/grid/yaspgrid.hh>
#include <dune/grid/alugrid.hh>

#include <dune/localfunctions/lagrange/equidistantpoints.hh>
#include <dune/localfunctions/lagrange.hh>

#include <dune/fem/space/common/allgeomtypes.hh>

#include <dune/fem_localfunctions/localfunctions/transformations.hh>
#include <dune/fem_localfunctions/basefunctions/genericbasefunctionsetstorage.hh>
#include <dune/fem_localfunctions/basefunctionsetmap/basefunctionsetmap.hh>
#include <dune/fem_localfunctions/space/genericdiscretefunctionspace.hh>

#include <dune/stuff/common/color.hh>

#include "../../mapper/fem.hh"
#include "../../basefunctionset/fem-localfunctions.hh"
#include "../constraints.hh"
#include "../interface.hh"

namespace Dune {
namespace GDT {
namespace DiscontinuousLagrangeSpace {

// forward, to be used in the traits and to allow for specialization
template< class GridPartImp, int polynomialOrder, class RangeFieldImp, int rangeDim, int rangeDimCols = 1 >
class FemLocalfunctionsWrapper;

// forward, to allow for specialization
template< class GridPartImp, int polynomialOrder, class RangeFieldImp, int rangeDim, int rangeDimCols = 1 >
class FemLocalfunctionsWrapperTraits;

/**
 *  \brief Traits class for ContinuousLagrangeSpace for dimRange 1x1.
 */
template< class GridPartImp, int polynomialOrder, class RangeFieldImp >
class FemLocalfunctionsWrapperTraits< GridPartImp, polynomialOrder, RangeFieldImp, 1, 1 >
{
public:
  typedef GridPartImp                   GridPartType;
  static const int                      polOrder = polynomialOrder;
  dune_static_assert((polOrder >= 1), "ERROR: wrong polOrder given!");
private:
  typedef typename GridPartType::ctype  DomainFieldType;
  static const unsigned int             dimDomain = GridPartType::dimension;
public:
  typedef RangeFieldImp                 RangeFieldType;
  static const unsigned int             dimRange = 1;
  static const unsigned int             dimRangeCols = 1;
  typedef FemLocalfunctionsWrapper< GridPartType, polOrder, RangeFieldType, dimRange, dimRangeCols > derived_type;
  typedef Dune::LagrangeLocalFiniteElement< Dune::EquidistantPointSet,
                                            dimDomain,
                                            DomainFieldType,
                                            RangeFieldType > ContinuousFiniteElementType;
  typedef Dune::DGLocalFiniteElement< ContinuousFiniteElementType > FiniteElementType;
private:
  typedef Dune::FemLocalFunctions::BaseFunctionSetMap<  GridPartType,
                                                        FiniteElementType,
                                                        Dune::FemLocalFunctions::NoTransformation,
                                                        Dune::FemLocalFunctions::SimpleStorage,
                                                        polOrder,
                                                        polOrder >  BaseFunctionSetMapType;
public:
  typedef Dune::FemLocalFunctions::DiscreteFunctionSpace< BaseFunctionSetMapType >  BackendType;
  typedef Mapper::FemDofWrapper< typename BackendType::MapperType >                 MapperType;
  typedef BaseFunctionSet::FemLocalfunctionsWrapper< BaseFunctionSetMapType,
              DomainFieldType, dimDomain, RangeFieldType, dimRange, dimRangeCols >  BaseFunctionSetType;
  typedef typename BaseFunctionSetType::EntityType                                  EntityType;
private:
  template< class G, int p, class R, int r, int rC >
  friend class FemLocalfunctionsWrapper;
}; // class FemLocalfunctionsWrapperTraits< ..., 1, 1 >

template< class GridPartImp, int polynomialOrder, class RangeFieldImp >
class FemLocalfunctionsWrapper< GridPartImp, polynomialOrder, RangeFieldImp, 1, 1 >
  : public SpaceInterface< FemLocalfunctionsWrapperTraits< GridPartImp, polynomialOrder, RangeFieldImp, 1, 1 > >
{
  typedef SpaceInterface< FemLocalfunctionsWrapperTraits< GridPartImp, polynomialOrder, RangeFieldImp, 1, 1 > >
    BaseType;
  typedef FemLocalfunctionsWrapper< GridPartImp, polynomialOrder, RangeFieldImp, 1, 1 > ThisType;
public:
  typedef FemLocalfunctionsWrapperTraits< GridPartImp, polynomialOrder, RangeFieldImp, 1, 1 > Traits;

  typedef typename Traits::GridPartType   GridPartType;
  typedef typename GridPartType::ctype    DomainFieldType;
  static const int                        polOrder = Traits::polOrder;
  static const unsigned int               dimDomain = GridPartType::dimension;
  typedef typename Traits::RangeFieldType RangeFieldType;
  static const unsigned int               dimRange = Traits::dimRange;
  static const unsigned int               dimRangeCols = Traits::dimRangeCols;

  typedef typename Traits::BackendType          BackendType;
  typedef typename Traits::MapperType           MapperType;
  typedef typename Traits::BaseFunctionSetType  BaseFunctionSetType;
  typedef typename Traits::EntityType           EntityType;

  typedef Dune::Stuff::LA::SparsityPatternDefault PatternType;

private:
  typedef typename Traits::BaseFunctionSetMapType BaseFunctionSetMapType;

public:
  FemLocalfunctionsWrapper(std::shared_ptr< const GridPartType > gridP)
    : gridPart_(assertGridPart(gridP))
    , baseFunctionSetMap_(new BaseFunctionSetMapType(*gridPart_))
    , backend_(new BackendType(const_cast< GridPartType& >(*gridPart_), *baseFunctionSetMap_))
    , mapper_(new MapperType(backend_->mapper()))
  {}

  FemLocalfunctionsWrapper(const ThisType& other)
    : gridPart_(other.gridPart_)
    , baseFunctionSetMap_(other.baseFunctionSetMap_)
    , backend_(other.backend_)
    , mapper_(other.mapper_)
  {}

  ThisType& operator=(const ThisType& other)
  {
    if (this != &other) {
      gridPart_ = other.gridPart_;
      baseFunctionSetMap_ = other.baseFunctionSetMap_;
      backend_ = other.backend_;
      mapper_ = other.mapper_;
    }
    return *this;
  }

  ~FemLocalfunctionsWrapper() {}

  std::shared_ptr< const GridPartType > gridPart() const
  {
    return gridPart_;
  }

  const BackendType& backend() const
  {
    return *backend_;
  }

  bool continuous() const
  {
    return false;
  }

  const MapperType& mapper() const
  {
    return *mapper_;
  }

  BaseFunctionSetType baseFunctionSet(const EntityType& entity) const
  {
    return BaseFunctionSetType(*baseFunctionSetMap_, entity);
  }

  template< class R >
  void localConstraints(const EntityType& /*entity*/,
                        Constraints::LocalDefault< R >& /*ret*/) const
  {
    dune_static_assert(Dune::AlwaysFalse< R >::value, "ERROR: not implemented for arbitrary constraints!");
  }

  using BaseType::computePattern;

  template< class LocalGridPartType, class OtherSpaceType >
  PatternType* computePattern(const LocalGridPartType& localGridPart,
                              const OtherSpaceType& otherSpace) const
  {
    return BaseType::computeCodim0AndCodim1Pattern(localGridPart, otherSpace);
  }

private:
  static std::shared_ptr< const GridPartType > assertGridPart(const std::shared_ptr< const GridPartType > gP)
  {
    // static grid check
    typedef typename GridPartType::GridType GridType;
#if HAVE_ALUGRID
    dune_static_assert(!(Dune::is_same< GridType, Dune::ALUCubeGrid< dimDomain, dimDomain > >::value),
                       "This space is only implemented for simplicial grids!");
#endif
    dune_static_assert(!(Dune::is_same< GridType, Dune::SGrid< dimDomain, dimDomain > >::value),
                       "This space is only implemented for simplicial grids!");
    dune_static_assert(!(Dune::is_same< GridType, Dune::YaspGrid< dimDomain > >::value),
                       "This space is only implemented for simplicial grids!");
    // dynamic gridpart check
    typedef typename Dune::Fem::AllGeomTypes< typename GridPartType::IndexSetType,
                                              typename GridPartType::GridType > AllGeometryTypes;
    const AllGeometryTypes allGeometryTypes(gP->indexSet());
    const std::vector< Dune::GeometryType >& geometryTypes = allGeometryTypes.geomTypes(0);
    if (!(geometryTypes.size() == 1 && geometryTypes[0].isSimplex()))
      DUNE_THROW(Dune::NotImplemented,
                 "\n" << Dune::Stuff::Common::colorStringRed("ERROR:")
                 << " this space is only implemented for simplicial grids!");
    return gP;
  } // ... assertGridPart(...)

  std::shared_ptr< const GridPartType > gridPart_;
  std::shared_ptr< BaseFunctionSetMapType > baseFunctionSetMap_;
  std::shared_ptr< const BackendType > backend_;
  std::shared_ptr< const MapperType > mapper_;
}; // class FemLocalfunctionsWrapper< ..., 1, 1 >

} // namespace DiscontinuousLagrangeSpace
} // namespace GDT
} // namespace Dune

#endif // DUNE_GDT_SPACE_DISCONTINUOUSLAGRANGE_FEM_LOCALFUNCTIONS_HH
<|endoftext|>


<commit_before>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2019 Ryo Suzuki
//	Copyright (c) 2016-2019 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# pragma once
# if __has_include(<opencv2/core.hpp>)
# include <opencv2/core.hpp>
# include "Image.hpp"

namespace s3d
{
	namespace OpenCV_Bridge
	{
		void RedToBinary(const Image& from, cv::Mat_<uint8>& to, uint32 threshold);

		void RedToBinary2x(const Image& from, cv::Mat_<uint8>& to, uint32 threshold);

		void AlphaToBinary(const Image& from, cv::Mat_<uint8>& to, uint32 threshold);

		void AlphaToBinary2x(const Image& from, cv::Mat_<uint8>& to, uint32 threshold);

		void ToGrayScale(const Image& from, cv::Mat_<uint8>& to);

		void ToMatVec3b(const Image& from, cv::Mat_<cv::Vec3b>& to);

		void ToMatVec3f255(const Image& from, cv::Mat_<cv::Vec3f>& to);

		void FromMat(const cv::Mat_<cv::Vec3b>& from, Image& to, bool preserveAlpha = false);

		void FromGrayScale(const cv::Mat_<uint8>& from, Image& to, bool preserveAlpha = false);

		cv::Mat_<uint8> ImRead_GrayScale(const FilePath& path);

		cv::Mat_<uint8> ImRead_GrayScale(const Image& image);

		cv::Mat_<cv::Vec3b> ImRead_BGR(const FilePath& path);

		cv::Mat_<cv::Vec3b> ImRead_BGR(const Image& image);
	}
}

# endif
<commit_msg>warning 抑制<commit_after>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2019 Ryo Suzuki
//	Copyright (c) 2016-2019 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# pragma once
# include "Fwd.hpp"
# if __has_include(<opencv2/core.hpp>)
SIV3D_DISABLE_MSVC_WARNINGS_PUSH(5054)
# include <opencv2/core.hpp>
SIV3D_DISABLE_MSVC_WARNINGS_POP()
# include "Image.hpp"

namespace s3d
{
	namespace OpenCV_Bridge
	{
		void RedToBinary(const Image& from, cv::Mat_<uint8>& to, uint32 threshold);

		void RedToBinary2x(const Image& from, cv::Mat_<uint8>& to, uint32 threshold);

		void AlphaToBinary(const Image& from, cv::Mat_<uint8>& to, uint32 threshold);

		void AlphaToBinary2x(const Image& from, cv::Mat_<uint8>& to, uint32 threshold);

		void ToGrayScale(const Image& from, cv::Mat_<uint8>& to);

		void ToMatVec3b(const Image& from, cv::Mat_<cv::Vec3b>& to);

		void ToMatVec3f255(const Image& from, cv::Mat_<cv::Vec3f>& to);

		void FromMat(const cv::Mat_<cv::Vec3b>& from, Image& to, bool preserveAlpha = false);

		void FromGrayScale(const cv::Mat_<uint8>& from, Image& to, bool preserveAlpha = false);

		cv::Mat_<uint8> ImRead_GrayScale(const FilePath& path);

		cv::Mat_<uint8> ImRead_GrayScale(const Image& image);

		cv::Mat_<cv::Vec3b> ImRead_BGR(const FilePath& path);

		cv::Mat_<cv::Vec3b> ImRead_BGR(const Image& image);
	}
}

# endif
<|endoftext|>


<commit_before><commit_msg>[FIXED] list为空时anim的LoadList会增加空图层<commit_after><|endoftext|>


<commit_before>#include <algorithm>
#include <iostream>

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

using namespace Halide;
using namespace Halide::Internal;

using std::string;
using std::map;
using std::vector;

namespace tiramisu
{

namespace
{

string stmt_to_string(const string &str, const Stmt &s)
{
    std::ostringstream stream;
    stream << str << s << "\n";
    return stream.str();
}

} // anonymous namespace

Module lower_halide_pipeline(const string &pipeline_name,
                             const Target &t,
                             const vector<Argument> &args,
                             const Internal::LoweredFunc::LinkageType linkage_type,
                             Stmt s)
{
    Module result_module(pipeline_name, t);

    // TODO(tiramisu): Compute the env (function DAG). This is needed for
    // the sliding window and storage folding passes.
    map<string, Function> env;

    std::cout << "Lower halide pipeline...\n" << s << "\n";

    DEBUG(3, tiramisu::str_dump("Performing sliding window optimization...\n"));
    s = sliding_window(s, env);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after sliding window:\n", s)));

    DEBUG(3, tiramisu::str_dump("Removing code that depends on undef values...\n"));
    s = remove_undef(s);
    DEBUG(4, tiramisu::str_dump(
              stmt_to_string("Lowering after removing code that depends on undef values:\n", s)));

    // This uniquifies the variable names, so we're good to simplify
    // after this point. This lets later passes assume syntactic
    // equivalence means semantic equivalence.
    DEBUG(3, tiramisu::str_dump("Uniquifying variable names...\n"));
    s = uniquify_variable_names(s);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after uniquifying variable names:\n", s)));

    DEBUG(3, tiramisu::str_dump("Simplifying...\n")); // without removing dead lets, because storage flattening needs the strides
    s = simplify(s, false);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after simplification:\n", s)));

    DEBUG(3, tiramisu::str_dump("Performing storage folding optimization...\n"));
    s = storage_folding(s, env);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after storage folding:\n", s)));

    DEBUG(3, tiramisu::str_dump("Simplifying...\n")); // without removing dead lets, because storage flattening needs the strides
    s = simplify(s, false);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after simplification:\n", s)));

    DEBUG(3, tiramisu::str_dump("Injecting prefetches...\n"));
    s = inject_prefetch(s, env);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after injecting prefetches:\n", s)));

    DEBUG(3, tiramisu::str_dump("Dynamically skipping stages...\n"));
    s = skip_stages(s, order);
    DEBUG(3, tiramisu::str_dump("Lowering after dynamically skipping stages:\n", s)));

    DEBUG(3, tiramisu::str_dump("Destructuring tuple-valued realizations...\n"));
    s = split_tuples(s, env);
    DEBUG(3, tiramisu::str_dump("Lowering after destructuring tuple-valued realizations:\n", s));
    DEBUG(3, tiramisu::str_dump("\n\n"));

    DEBUG(3, tiramisu::str_dump("Performing storage flattening...\n"));
    s = storage_flattening(s, outputs, env, t);
    DEBUG(4, tiramisu::str_dump("Lowering after storage flattening:\n", s)));
    DEBUG(4, tiramisu::str_dump("\n\n"));

    // TODO(tiramisu): This pass is important to figure out all the buffer symbols.
    // Maybe we should put it somewhere else instead of here.
    DEBUG(3, tiramisu::str_dump("Unpacking buffer arguments...\n"));
    s = unpack_buffers(s);
    DEBUG(0, tiramisu::str_dump(stmt_to_string("Lowering after unpacking buffer arguments:\n", s)));

    if (t.has_gpu_feature() ||
        t.has_feature(Target::OpenGLCompute) ||
        t.has_feature(Target::OpenGL) ||
        (t.arch != Target::Hexagon && (t.features_any_of({Target::HVX_64, Target::HVX_128})))) {
        DEBUG(3, tiramisu::str_dump("Selecting a GPU API for GPU loops...\n"));
        s = select_gpu_api(s, t);
        DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after selecting a GPU API:\n", s)));

        DEBUG(3, tiramisu::str_dump("Injecting host <-> dev buffer copies...\n"));
        s = inject_host_dev_buffer_copies(s, t);
        DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after injecting host <-> dev buffer copies:\n",
                                    s)));
    }

    if (t.has_feature(Target::OpenGL))
    {
        DEBUG(3, tiramisu::str_dump("Injecting OpenGL texture intrinsics...\n"));
        s = inject_opengl_intrinsics(s);
        DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after OpenGL intrinsics:\n", s)));
    }

    if (t.has_gpu_feature() ||
            t.has_feature(Target::OpenGLCompute))
    {
        DEBUG(3, tiramisu::str_dump("Injecting per-block gpu synchronization...\n"));
        s = fuse_gpu_thread_loops(s);
        DEBUG(4, tiramisu::str_dump(
                  stmt_to_string("Lowering after injecting per-block gpu synchronization:\n", s)));
    }

    DEBUG(3, tiramisu::str_dump("Simplifying...\n"));
    s = simplify(s);
    s = unify_duplicate_lets(s);
    s = remove_trivial_for_loops(s);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after second simplifcation:\n", s)));

    DEBUG(3, tiramisu::str_dump("Reduce prefetch dimension...\n"));
    s = reduce_prefetch_dimension(s, t);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after reduce prefetch dimension:\n", s)));

    DEBUG(3, tiramisu::str_dump("Unrolling...\n"));
    s = unroll_loops(s);
    s = simplify(s);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after unrolling:\n", s)));

    DEBUG(3, tiramisu::str_dump("Vectorizing...\n"));
    s = vectorize_loops(s, t);
    s = simplify(s);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after vectorizing:\n", s)));

    DEBUG(3, tiramisu::str_dump("Detecting vector interleavings...\n"));
    s = rewrite_interleavings(s);
    s = simplify(s);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after rewriting vector interleavings:\n", s)));

    DEBUG(3, tiramisu::str_dump("Partitioning loops to simplify boundary conditions...\n"));
    s = partition_loops(s);
    s = simplify(s);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after partitioning loops:\n", s)));

    DEBUG(3, tiramisu::str_dump("Trimming loops to the region over which they do something...\n"));
    s = trim_no_ops(s);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after loop trimming:\n", s)));

    DEBUG(3, tiramisu::str_dump("Injecting early frees...\n"));
    s = inject_early_frees(s);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after injecting early frees:\n", s)));

    if (t.has_feature(Target::FuzzFloatStores))
    {
        DEBUG(3, tiramisu::str_dump("Fuzzing floating point stores...\n"));
        s = fuzz_float_stores(s);
        DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after fuzzing floating point stores:\n", s)));
    }

    DEBUG(3, tiramisu::str_dump("Bounding small allocations...\n"));
    s = bound_small_allocations(s);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after bounding small allocations:\n", s)));
    DEBUG(3, tiramisu::str_dump("\n\n"));

    DEBUG(3, tiramisu::str_dump("Simplifying...\n"));
    s = common_subexpression_elimination(s);

    if (t.has_feature(Target::OpenGL))
    {
        DEBUG(3, tiramisu::str_dump("Detecting varying attributes...\n"));
        s = find_linear_expressions(s);
        DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after detecting varying attributes:\n", s)));

        DEBUG(3, tiramisu::str_dump("Moving varying attribute expressions out of the shader...\n"));
        s = setup_gpu_vertex_buffer(s);
        DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after removing varying attributes:\n", s)));
    }

    s = remove_dead_allocations(s);
    s = remove_trivial_for_loops(s);
    s = simplify(s);
    s = loop_invariant_code_motion(s);
    std::cout << "Lowering after final simplification:\n" << s << "\n";

    DEBUG(3, tiramisu::str_dump("Splitting off Hexagon offload...\n"));
    s = inject_hexagon_rpc(s, t, result_module);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after splitting off Hexagon offload:\n", s)));

    vector<Argument> public_args = args;

    // We're about to drop the environment and outputs vector, which
    // contain the only strong refs to Functions that may still be
    // pointed to by the IR. So make those refs strong.
    class StrengthenRefs : public IRMutator {
        using IRMutator::visit;
        void visit(const Call *c) {
            IRMutator::visit(c);
            c = expr.as<Call>();
            //internal_assert(c);
            if (c->func.defined()) {
                FunctionPtr ptr = c->func;
                ptr.strengthen();
                expr = Call::make(c->type, c->name, c->args, c->call_type,
                                  ptr, c->value_index,
                                  c->image, c->param);
            }
        }
    };
    s = StrengthenRefs().mutate(s);

    LoweredFunc main_func(pipeline_name, public_args, s, linkage_type);

    result_module.append(main_func);

    // Append a wrapper for this pipeline that accepts old buffer_ts
    // and upgrades them. It will use the same name, so it will
    // require C++ linkage. We don't need it when jitting.
    if (!t.has_feature(Target::JIT)) {
        add_legacy_wrapper(result_module, main_func);
    }

    // Also append any wrappers for extern stages that expect the old buffer_t
    wrap_legacy_extern_stages(result_module);

    return result_module;
}

}
<commit_msg>Add Halide optimizations<commit_after>#include <algorithm>
#include <iostream>

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

using namespace Halide;
using namespace Halide::Internal;

using std::string;
using std::map;
using std::vector;

namespace tiramisu
{

namespace
{

string stmt_to_string(const string &str, const Stmt &s)
{
    std::ostringstream stream;
    stream << str << s << "\n";
    return stream.str();
}

} // anonymous namespace

Module lower_halide_pipeline(const string &pipeline_name,
                             const Target &t,
                             const vector<Argument> &args,
                             const Internal::LoweredFunc::LinkageType linkage_type,
                             Stmt s)
{
    Module result_module(pipeline_name, t);

    // TODO(tiramisu): Compute the env (function DAG). This is needed for
    // the sliding window and storage folding passes.
    map<string, Function> env;

    std::cout << "Lower halide pipeline...\n" << s << "\n";

    DEBUG(3, tiramisu::str_dump("Performing sliding window optimization...\n"));
    s = sliding_window(s, env);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after sliding window:\n", s)));

    DEBUG(3, tiramisu::str_dump("Removing code that depends on undef values...\n"));
    s = remove_undef(s);
    DEBUG(4, tiramisu::str_dump(
              stmt_to_string("Lowering after removing code that depends on undef values:\n", s)));

    // This uniquifies the variable names, so we're good to simplify
    // after this point. This lets later passes assume syntactic
    // equivalence means semantic equivalence.
    DEBUG(3, tiramisu::str_dump("Uniquifying variable names...\n"));
    s = uniquify_variable_names(s);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after uniquifying variable names:\n", s)));

    DEBUG(3, tiramisu::str_dump("Simplifying...\n")); // without removing dead lets, because storage flattening needs the strides
    s = simplify(s, false);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after simplification:\n", s)));

    DEBUG(3, tiramisu::str_dump("Performing storage folding optimization...\n"));
    s = storage_folding(s, env);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after storage folding:\n", s)));

    DEBUG(3, tiramisu::str_dump("Simplifying...\n")); // without removing dead lets, because storage flattening needs the strides
    s = simplify(s, false);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after simplification:\n", s)));

/*    DEBUG(3, tiramisu::str_dump("Injecting prefetches...\n"));
    s = inject_prefetch(s, env);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after injecting prefetches:\n", s)));
*/
    DEBUG(3, tiramisu::str_dump("Destructuring tuple-valued realizations...\n"));
    s = split_tuples(s, env);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after destructuring tuple-valued realizations:\n", s)));
    DEBUG(3, tiramisu::str_dump("\n\n"));

    // TODO(tiramisu): This pass is important to figure out all the buffer symbols.
    // Maybe we should put it somewhere else instead of here.
    DEBUG(3, tiramisu::str_dump("Unpacking buffer arguments...\n"));
    s = unpack_buffers(s);
    DEBUG(0, tiramisu::str_dump(stmt_to_string("Lowering after unpacking buffer arguments:\n", s)));

    if (t.has_gpu_feature() ||
        t.has_feature(Target::OpenGLCompute) ||
        t.has_feature(Target::OpenGL) ||
        (t.arch != Target::Hexagon && (t.features_any_of({Target::HVX_64, Target::HVX_128})))) {
        DEBUG(3, tiramisu::str_dump("Selecting a GPU API for GPU loops...\n"));
        s = select_gpu_api(s, t);
        DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after selecting a GPU API:\n", s)));

        DEBUG(3, tiramisu::str_dump("Injecting host <-> dev buffer copies...\n"));
        s = inject_host_dev_buffer_copies(s, t);
        DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after injecting host <-> dev buffer copies:\n",
                                    s)));
    }

    if (t.has_feature(Target::OpenGL))
    {
        DEBUG(3, tiramisu::str_dump("Injecting OpenGL texture intrinsics...\n"));
        s = inject_opengl_intrinsics(s);
        DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after OpenGL intrinsics:\n", s)));
    }

    if (t.has_gpu_feature() ||
            t.has_feature(Target::OpenGLCompute))
    {
        DEBUG(3, tiramisu::str_dump("Injecting per-block gpu synchronization...\n"));
        s = fuse_gpu_thread_loops(s);
        DEBUG(4, tiramisu::str_dump(
                  stmt_to_string("Lowering after injecting per-block gpu synchronization:\n", s)));
    }

    DEBUG(3, tiramisu::str_dump("Simplifying...\n"));
    s = simplify(s);
    s = unify_duplicate_lets(s);
    s = remove_trivial_for_loops(s);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after second simplifcation:\n", s)));

    DEBUG(3, tiramisu::str_dump("Reduce prefetch dimension...\n"));
    s = reduce_prefetch_dimension(s, t);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after reduce prefetch dimension:\n", s)));

    DEBUG(3, tiramisu::str_dump("Unrolling...\n"));
    s = unroll_loops(s);
    s = simplify(s);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after unrolling:\n", s)));

    DEBUG(3, tiramisu::str_dump("Vectorizing...\n"));
    s = vectorize_loops(s, t);
    s = simplify(s);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after vectorizing:\n", s)));

    DEBUG(3, tiramisu::str_dump("Detecting vector interleavings...\n"));
    s = rewrite_interleavings(s);
    s = simplify(s);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after rewriting vector interleavings:\n", s)));

    DEBUG(3, tiramisu::str_dump("Partitioning loops to simplify boundary conditions...\n"));
    s = partition_loops(s);
    s = simplify(s);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after partitioning loops:\n", s)));

    DEBUG(3, tiramisu::str_dump("Trimming loops to the region over which they do something...\n"));
    s = trim_no_ops(s);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after loop trimming:\n", s)));

    DEBUG(3, tiramisu::str_dump("Injecting early frees...\n"));
    s = inject_early_frees(s);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after injecting early frees:\n", s)));

    if (t.has_feature(Target::FuzzFloatStores))
    {
        DEBUG(3, tiramisu::str_dump("Fuzzing floating point stores...\n"));
        s = fuzz_float_stores(s);
        DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after fuzzing floating point stores:\n", s)));
    }

    DEBUG(3, tiramisu::str_dump("Simplifying...\n"));
    s = common_subexpression_elimination(s);

    if (t.has_feature(Target::OpenGL))
    {
        DEBUG(3, tiramisu::str_dump("Detecting varying attributes...\n"));
        s = find_linear_expressions(s);
        DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after detecting varying attributes:\n", s)));

        DEBUG(3, tiramisu::str_dump("Moving varying attribute expressions out of the shader...\n"));
        s = setup_gpu_vertex_buffer(s);
        DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after removing varying attributes:\n", s)));
    }

    s = remove_dead_allocations(s);
    s = remove_trivial_for_loops(s);
    s = simplify(s);
    s = loop_invariant_code_motion(s);
    std::cout << "Lowering after final simplification:\n" << s << "\n";

    DEBUG(3, tiramisu::str_dump("Splitting off Hexagon offload...\n"));
    s = inject_hexagon_rpc(s, t, result_module);
    DEBUG(4, tiramisu::str_dump(stmt_to_string("Lowering after splitting off Hexagon offload:\n", s)));

    vector<Argument> public_args = args;

    // We're about to drop the environment and outputs vector, which
    // contain the only strong refs to Functions that may still be
    // pointed to by the IR. So make those refs strong.
    class StrengthenRefs : public IRMutator {
        using IRMutator::visit;
        void visit(const Call *c) {
            IRMutator::visit(c);
            c = expr.as<Call>();
            //internal_assert(c);
            if (c->func.defined()) {
                FunctionPtr ptr = c->func;
                ptr.strengthen();
                expr = Call::make(c->type, c->name, c->args, c->call_type,
                                  ptr, c->value_index,
                                  c->image, c->param);
            }
        }
    };
    s = StrengthenRefs().mutate(s);

    LoweredFunc main_func(pipeline_name, public_args, s, linkage_type);

    result_module.append(main_func);

    // Append a wrapper for this pipeline that accepts old buffer_ts
    // and upgrades them. It will use the same name, so it will
    // require C++ linkage. We don't need it when jitting.
    if (!t.has_feature(Target::JIT)) {
        add_legacy_wrapper(result_module, main_func);
    }

    // Also append any wrappers for extern stages that expect the old buffer_t
    wrap_legacy_extern_stages(result_module);

    return result_module;
}

}
<|endoftext|>


<commit_before>//*****************************************************************************
// Copyright 2017-2019 Intel Corporation
//
// 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 <condition_variable>
#include <mutex>
#include <thread>

#include "benchmark.hpp"
#include "benchmark_utils.hpp"
#include "ngraph/file_util.hpp"
#include "ngraph/runtime/backend.hpp"
#include "ngraph/runtime/host_tensor.hpp"
#include "ngraph/runtime/tensor.hpp"
#include "ngraph/serializer.hpp"
#include "ngraph/util.hpp"

using namespace std;
using namespace ngraph;

class TensorCollection
{
public:
    vector<shared_ptr<runtime::HostTensor>> parameter_data;

    vector<shared_ptr<runtime::Tensor>> input_tensors;
    vector<shared_ptr<runtime::Tensor>> output_tensors;

private:
};

static mutex s_mutex;
static condition_variable s_condition;
static size_t current_iteration = 0;
static size_t s_iterations;
static size_t s_warmup_iterations;

static void do_iteration(runtime::Executable* exec, const TensorCollection& tensors)
{
}

static void
    thread_entry(runtime::Executable* exec, const TensorCollection& tensors, size_t pipeline_stage)
// static void thread_entry(size_t pipeline_stage)
{
    while (current_iteration < s_iterations + s_warmup_iterations)
    {
        NGRAPH_INFO;
        unique_lock<mutex> lock(s_mutex);
        if ((current_iteration & 1) != pipeline_stage)
        {
            s_condition.wait(lock);
        }
        else
        {
            // our turn to run
            NGRAPH_INFO << "stage " << pipeline_stage << " for iteration " << current_iteration;
            do_iteration(exec, tensors);
            current_iteration++;
            s_condition.notify_all();
        }
    }
}

vector<runtime::PerformanceCounter> run_benchmark_pipelined(shared_ptr<Function> f,
                                                            const string& backend_name,
                                                            size_t iterations,
                                                            bool timing_detail,
                                                            int warmup_iterations,
                                                            bool copy_data)
{
    NGRAPH_INFO;
    constexpr size_t pipeline_depth = 2;
    s_iterations = iterations;
    s_warmup_iterations = warmup_iterations;
    array<TensorCollection, pipeline_depth> tensor_collections;
    stopwatch timer;
    timer.start();
    auto backend = runtime::Backend::create(backend_name);
    auto exec = backend->compile(f, timing_detail);
    timer.stop();
    cout.imbue(locale(""));
    cout << "compile time: " << timer.get_milliseconds() << "ms" << endl;
    set_denormals_flush_to_zero();

    // Create random input data for all input tensors
    array<vector<shared_ptr<runtime::HostTensor>>, pipeline_depth> parameters_data_set;
    for (size_t i = 0; i < pipeline_depth; i++)
    {
        for (shared_ptr<op::Parameter> param : f->get_parameters())
        {
            auto tensor_data =
                make_shared<runtime::HostTensor>(param->get_element_type(), param->get_shape());
            random_init(tensor_data);
            tensor_collections[i].parameter_data.push_back(tensor_data);
        }
    }

    // Create input tensors for all Parameters
    array<vector<shared_ptr<runtime::Tensor>>, pipeline_depth> input_tensors_array;
    size_t input_index = 0;
    for (shared_ptr<op::Parameter> param : f->get_parameters())
    {
        auto input_tensors = exec->create_input_tensor(input_index++, pipeline_depth);
        for (size_t i = 0; i < pipeline_depth; i++)
        {
            tensor_collections[i].input_tensors.push_back(input_tensors[i]);
        }
    }

    // Create output tensors for all Results
    array<vector<shared_ptr<runtime::Tensor>>, pipeline_depth> output_tensors_array;
    size_t output_index = 0;
    for (shared_ptr<Node> result : f->get_results())
    {
        auto output_tensors = exec->create_output_tensor(output_index++, pipeline_depth);
        for (size_t i = 0; i < pipeline_depth; i++)
        {
            tensor_collections[i].output_tensors.push_back(output_tensors[i]);
        }
    }

    stopwatch t1;

    size_t current_iteration = 0;
    thread threads[pipeline_depth];
    for (size_t i = 0; i < pipeline_depth; i++)
    {
        threads[i] = thread(thread_entry, exec.get(), tensor_collections[i], i);
        // threads[i] = thread(thread_entry, i);
    }

    for (size_t i = 0; i < pipeline_depth; i++)
    {
        threads[i].join();
    }

    // // Before we start we write the first iteration's data
    // size_t buffer_number = 0;
    // auto args = input_tensors_array[buffer_number];
    // auto args_data = parameters_data_set[buffer_number];
    // for (size_t arg_index = 0; arg_index < args.size(); arg_index++)
    // {
    //     const shared_ptr<runtime::Tensor>& arg = args[arg_index];
    //     const shared_ptr<runtime::HostTensor>& data = args_data[arg_index];
    //     arg->begin_write(data->get_data_ptr(),
    //                      data->get_element_count() * data->get_element_type().size(),
    //                      buffer_number);
    // }

    // const vector<shared_ptr<runtime::Tensor>>& results = output_tensors[buffer_number];
    // const vector<shared_ptr<runtime::HostTensor>>& results_data = results_data_set[buffer_number];
    // for (size_t i = 0; i < iterations + warmup_iterations; i++)
    // {
    //     if (i == warmup_iterations)
    //     {
    //         t1.start();
    //     }
    //     future<void> exec_future = exec->begin_execute(results, args);
    //     if (i > 0)
    //     {
    //         for (size_t result_index = 0; result_index < results.size(); result_index++)
    //         {
    //             const shared_ptr<runtime::HostTensor>& data = results_data[result_index];
    //             const shared_ptr<runtime::Tensor>& result = results[result_index];
    //             result->begin_read(data->get_data_ptr(),
    //                                data->get_element_count() * data->get_element_type().size(),
    //                                (buffer_number - 1) & 1);
    //         }
    //     }
    //     buffer_number = (buffer_number + 1) & 1;
    //     for (size_t arg_index = 0; arg_index < args.size(); arg_index++)
    //     {
    //         const shared_ptr<runtime::Tensor>& arg = args[arg_index];
    //         const shared_ptr<runtime::HostTensor>& data = args_data[arg_index];
    //         arg->begin_write(data->get_data_ptr(),
    //                          data->get_element_count() * data->get_element_type().size(),
    //                          buffer_number);
    //     }
    //     exec_future.get();
    // }
    // for (size_t result_index = 0; result_index < results.size(); result_index++)
    // {
    //     const shared_ptr<runtime::HostTensor>& data = results_data[result_index];
    //     const shared_ptr<runtime::Tensor>& result = results[result_index];
    //     result->begin_read(data->get_data_ptr(),
    //                        data->get_element_count() * data->get_element_type().size(),
    //                        (buffer_number - 1) & 1);
    // }
    // t1.stop();
    // float time = t1.get_milliseconds();
    // cout << time / iterations << "ms per iteration" << endl;

    vector<runtime::PerformanceCounter> perf_data = exec->get_performance_data();
    return perf_data;
}
<commit_msg>running?<commit_after>//*****************************************************************************
// Copyright 2017-2019 Intel Corporation
//
// 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 <condition_variable>
#include <mutex>
#include <thread>

#include "benchmark.hpp"
#include "benchmark_utils.hpp"
#include "ngraph/file_util.hpp"
#include "ngraph/runtime/backend.hpp"
#include "ngraph/runtime/host_tensor.hpp"
#include "ngraph/runtime/tensor.hpp"
#include "ngraph/serializer.hpp"
#include "ngraph/util.hpp"

using namespace std;
using namespace ngraph;

class TensorCollection
{
public:
    vector<shared_ptr<runtime::HostTensor>> parameter_data;
    vector<shared_ptr<runtime::HostTensor>> result_data;

    vector<shared_ptr<runtime::Tensor>> input_tensors;
    vector<shared_ptr<runtime::Tensor>> output_tensors;

private:
};

static mutex s_mutex;
static condition_variable s_condition;
static size_t current_iteration = 0;
static size_t s_iterations;
static size_t s_warmup_iterations;

static void do_iteration(runtime::Executable* exec, const TensorCollection& tensors)
{
    const vector<shared_ptr<runtime::Tensor>>& args = tensors.input_tensors;
    const vector<shared_ptr<runtime::Tensor>>& results = tensors.output_tensors;
    for (size_t arg_index = 0; arg_index < args.size(); arg_index++)
    {
        const shared_ptr<runtime::Tensor>& arg = args[arg_index];
        if (arg->get_stale())
        {
            const shared_ptr<runtime::HostTensor>& data = tensors.parameter_data[arg_index];
            arg->write(data->get_data_ptr(),
                       data->get_element_count() * data->get_element_type().size());
        }
    }
    exec->call(results, args);
    for (size_t result_index = 0; result_index < results.size(); result_index++)
    {
        const shared_ptr<runtime::HostTensor>& data = tensors.result_data[result_index];
        const shared_ptr<runtime::Tensor>& result = results[result_index];
        result->read(data->get_data_ptr(),
                     data->get_element_count() * data->get_element_type().size());
    }
}

static void
    thread_entry(runtime::Executable* exec, const TensorCollection& tensors, size_t pipeline_stage)
// static void thread_entry(size_t pipeline_stage)
{
    while (current_iteration < s_iterations + s_warmup_iterations)
    {
        NGRAPH_INFO;
        unique_lock<mutex> lock(s_mutex);
        if ((current_iteration & 1) != pipeline_stage)
        {
            s_condition.wait(lock);
        }
        else
        {
            // our turn to run
            NGRAPH_INFO << "stage " << pipeline_stage << " for iteration " << current_iteration;
            do_iteration(exec, tensors);
            current_iteration++;
            s_condition.notify_all();
        }
    }
}

vector<runtime::PerformanceCounter> run_benchmark_pipelined(shared_ptr<Function> f,
                                                            const string& backend_name,
                                                            size_t iterations,
                                                            bool timing_detail,
                                                            int warmup_iterations,
                                                            bool copy_data)
{
    NGRAPH_INFO;
    constexpr size_t pipeline_depth = 2;
    s_iterations = iterations;
    s_warmup_iterations = warmup_iterations;
    array<TensorCollection, pipeline_depth> tensor_collections;
    stopwatch timer;
    timer.start();
    auto backend = runtime::Backend::create(backend_name);
    auto exec = backend->compile(f, timing_detail);
    timer.stop();
    cout.imbue(locale(""));
    cout << "compile time: " << timer.get_milliseconds() << "ms" << endl;
    set_denormals_flush_to_zero();

    // Create random input data for all input tensors
    for (size_t i = 0; i < pipeline_depth; i++)
    {
        for (shared_ptr<op::Parameter> param : f->get_parameters())
        {
            auto tensor_data =
                make_shared<runtime::HostTensor>(param->get_element_type(), param->get_shape());
            random_init(tensor_data);
            tensor_collections[i].parameter_data.push_back(tensor_data);
        }
    }

    // Create output tensors for all outputs
    for (size_t i = 0; i < pipeline_depth; i++)
    {
        for (shared_ptr<Node> result : f->get_results())
        {
            auto tensor_data =
                make_shared<runtime::HostTensor>(result->get_element_type(), result->get_shape());
            tensor_collections[i].result_data.push_back(tensor_data);
        }
    }

    // Create input tensors for all Parameters
    array<vector<shared_ptr<runtime::Tensor>>, pipeline_depth> input_tensors_array;
    size_t input_index = 0;
    for (shared_ptr<op::Parameter> param : f->get_parameters())
    {
        auto input_tensors = exec->create_input_tensor(input_index++, pipeline_depth);
        for (size_t i = 0; i < pipeline_depth; i++)
        {
            tensor_collections[i].input_tensors.push_back(input_tensors[i]);
        }
    }

    // Create output tensors for all Results
    array<vector<shared_ptr<runtime::Tensor>>, pipeline_depth> output_tensors_array;
    size_t output_index = 0;
    for (shared_ptr<Node> result : f->get_results())
    {
        auto output_tensors = exec->create_output_tensor(output_index++, pipeline_depth);
        for (size_t i = 0; i < pipeline_depth; i++)
        {
            tensor_collections[i].output_tensors.push_back(output_tensors[i]);
        }
    }

    stopwatch t1;

    size_t current_iteration = 0;
    thread threads[pipeline_depth];
    for (size_t i = 0; i < pipeline_depth; i++)
    {
        threads[i] = thread(thread_entry, exec.get(), tensor_collections[i], i);
        // threads[i] = thread(thread_entry, i);
    }

    for (size_t i = 0; i < pipeline_depth; i++)
    {
        threads[i].join();
    }

    // // Before we start we write the first iteration's data
    // size_t buffer_number = 0;
    // auto args = input_tensors_array[buffer_number];
    // auto args_data = parameters_data_set[buffer_number];
    // for (size_t arg_index = 0; arg_index < args.size(); arg_index++)
    // {
    //     const shared_ptr<runtime::Tensor>& arg = args[arg_index];
    //     const shared_ptr<runtime::HostTensor>& data = args_data[arg_index];
    //     arg->begin_write(data->get_data_ptr(),
    //                      data->get_element_count() * data->get_element_type().size(),
    //                      buffer_number);
    // }

    // const vector<shared_ptr<runtime::Tensor>>& results = output_tensors[buffer_number];
    // const vector<shared_ptr<runtime::HostTensor>>& results_data = results_data_set[buffer_number];
    // for (size_t i = 0; i < iterations + warmup_iterations; i++)
    // {
    //     if (i == warmup_iterations)
    //     {
    //         t1.start();
    //     }
    //     future<void> exec_future = exec->begin_execute(results, args);
    //     if (i > 0)
    //     {
    //         for (size_t result_index = 0; result_index < results.size(); result_index++)
    //         {
    //             const shared_ptr<runtime::HostTensor>& data = results_data[result_index];
    //             const shared_ptr<runtime::Tensor>& result = results[result_index];
    //             result->begin_read(data->get_data_ptr(),
    //                                data->get_element_count() * data->get_element_type().size(),
    //                                (buffer_number - 1) & 1);
    //         }
    //     }
    //     buffer_number = (buffer_number + 1) & 1;
    //     for (size_t arg_index = 0; arg_index < args.size(); arg_index++)
    //     {
    //         const shared_ptr<runtime::Tensor>& arg = args[arg_index];
    //         const shared_ptr<runtime::HostTensor>& data = args_data[arg_index];
    //         arg->begin_write(data->get_data_ptr(),
    //                          data->get_element_count() * data->get_element_type().size(),
    //                          buffer_number);
    //     }
    //     exec_future.get();
    // }
    // for (size_t result_index = 0; result_index < results.size(); result_index++)
    // {
    //     const shared_ptr<runtime::HostTensor>& data = results_data[result_index];
    //     const shared_ptr<runtime::Tensor>& result = results[result_index];
    //     result->begin_read(data->get_data_ptr(),
    //                        data->get_element_count() * data->get_element_type().size(),
    //                        (buffer_number - 1) & 1);
    // }
    // t1.stop();
    // float time = t1.get_milliseconds();
    // cout << time / iterations << "ms per iteration" << endl;

    vector<runtime::PerformanceCounter> perf_data = exec->get_performance_data();
    return perf_data;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * 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 "src/trace_processor/gzip_trace_parser.h"

#include <zlib.h>

#include "src/trace_processor/systrace_trace_parser.h"

namespace perfetto {
namespace trace_processor {

GzipTraceParser::GzipTraceParser(TraceProcessorContext* context)
    : context_(context), z_stream_(new z_stream()) {
  z_stream_->zalloc = Z_NULL;
  z_stream_->zfree = Z_NULL;
  z_stream_->opaque = Z_NULL;
  inflateInit(z_stream_.get());
}

GzipTraceParser::~GzipTraceParser() = default;

util::Status GzipTraceParser::Parse(std::unique_ptr<uint8_t[]> data,
                                    size_t size) {
  uint8_t* start = data.get();
  size_t len = size;

  static const char kSystraceFilerHeader[] = "TRACE:\n";
  if (!inner_) {
    inner_.reset(new SystraceTraceParser(context_));

    // Strip the header by ignoring the associated bytes.
    start += strlen(kSystraceFilerHeader);
    len -= strlen(kSystraceFilerHeader);
  }

  z_stream_->next_in = start;
  z_stream_->avail_in = static_cast<uInt>(len);

  // Our default uncompressed buffer size is 32MB as it allows for good
  // throughput.
  constexpr size_t kUncompressedBufferSize = 32 * 1024 * 1024;
  int ret = Z_OK;
  for (; ret != Z_STREAM_END && z_stream_->avail_in != 0;) {
    std::unique_ptr<uint8_t[]> buffer(new uint8_t[kUncompressedBufferSize]);
    z_stream_->next_out = buffer.get();
    z_stream_->avail_out = static_cast<uInt>(kUncompressedBufferSize);

    ret = inflate(z_stream_.get(), Z_NO_FLUSH);
    switch (ret) {
      case Z_NEED_DICT:
      case Z_DATA_ERROR:
      case Z_MEM_ERROR:
        // Ignore inflateEnd error as we will error out anyway.
        inflateEnd(z_stream_.get());
        return util::ErrStatus("Error decompressing ctrace file");
    }

    size_t read = size * 64 - z_stream_->avail_out;
    util::Status status = inner_->Parse(std::move(buffer), read);
    if (!status.ok())
      return status;
  }
  if (ret == Z_STREAM_END) {
    ret = inflateEnd(z_stream_.get());
    if (ret == Z_STREAM_ERROR)
      return util::ErrStatus("Error finishing decompression");
  }
  return util::OkStatus();
}

}  // namespace trace_processor
}  // namespace perfetto
<commit_msg>trace_processor: fix asan leak in gzip decoding<commit_after>/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * 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 "src/trace_processor/gzip_trace_parser.h"

#include <zlib.h>

#include "src/trace_processor/systrace_trace_parser.h"

namespace perfetto {
namespace trace_processor {

GzipTraceParser::GzipTraceParser(TraceProcessorContext* context)
    : context_(context), z_stream_(new z_stream()) {
  z_stream_->zalloc = Z_NULL;
  z_stream_->zfree = Z_NULL;
  z_stream_->opaque = Z_NULL;
  inflateInit(z_stream_.get());
}

GzipTraceParser::~GzipTraceParser() {
  // Ensure the call to inflateEnd to prevent leaks of internal state.
  inflateEnd(z_stream_.get());
}

util::Status GzipTraceParser::Parse(std::unique_ptr<uint8_t[]> data,
                                    size_t size) {
  uint8_t* start = data.get();
  size_t len = size;

  static const char kSystraceFilerHeader[] = "TRACE:\n";
  if (!inner_) {
    inner_.reset(new SystraceTraceParser(context_));

    // Strip the header by ignoring the associated bytes.
    start += strlen(kSystraceFilerHeader);
    len -= strlen(kSystraceFilerHeader);
  }

  z_stream_->next_in = start;
  z_stream_->avail_in = static_cast<uInt>(len);

  // Our default uncompressed buffer size is 32MB as it allows for good
  // throughput.
  constexpr size_t kUncompressedBufferSize = 32 * 1024 * 1024;
  int ret = Z_OK;
  for (; ret != Z_STREAM_END && z_stream_->avail_in != 0;) {
    std::unique_ptr<uint8_t[]> buffer(new uint8_t[kUncompressedBufferSize]);
    z_stream_->next_out = buffer.get();
    z_stream_->avail_out = static_cast<uInt>(kUncompressedBufferSize);

    ret = inflate(z_stream_.get(), Z_NO_FLUSH);
    switch (ret) {
      case Z_NEED_DICT:
      case Z_DATA_ERROR:
      case Z_MEM_ERROR:
        // Ignore inflateEnd error as we will error out anyway.
        inflateEnd(z_stream_.get());
        return util::ErrStatus("Error decompressing ctrace file");
    }

    size_t read = size * 64 - z_stream_->avail_out;
    util::Status status = inner_->Parse(std::move(buffer), read);
    if (!status.ok())
      return status;
  }
  if (ret == Z_STREAM_END) {
    ret = inflateEnd(z_stream_.get());
    if (ret == Z_STREAM_ERROR)
      return util::ErrStatus("Error finishing decompression");
  }
  return util::OkStatus();
}

}  // namespace trace_processor
}  // namespace perfetto
<|endoftext|>


<commit_before>/** @DBAPile
 *
 * @ingroup dspSpatLib
 *
 * @brieDBAP TODO
 *
 * @details TODO @n
 *
 * @authors Trond Lossius, Nils Peters, Timothy Place
 *
 * @copyright Copyright © 2011 by Trond Lossius, Nils Peters, and Timothy Place @n
 * This code is licensed under the terms oDBAP the "New BSD License" @n
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTSpatDBAPRenderer.h"
#include "TTSpatDBAPSource.h"

/// Methods DBAPor TTSpatDBAPRenderer: //////////////////////

TTSpatDBAPRenderer::TTSpatDBAPRenderer():
	mRolloff(6.0)
{
	;
}

TTSpatDBAPRenderer::~TTSpatDBAPRenderer()
{
	;
}

// A little helper method to get pointer to a DBAP source from the vector of standard spat sources
TTSpatDBAPSource* getDBAPSource(TTSpatSourceVector& aVector, int aSourceNumber)
{
	return (TTSpatDBAPSource*)&aVector[aSourceNumber];
}

void TTSpatDBAPRenderer::recalculateMatrixCoefficients(TTSpatSourceVector& aSources, TTSpatSinkVector& aSinks)
{
	TTInt32 nearestSink;
	TTFloat64 sqrDistance, smallestDist;
	TTFloat64 sourceX, sourceY, sourceZ;
	TTFloat64 sinkX, sinkY, sinkZ;

	mMixerMatrixCoefficients->setRowCount(TTUInt32(aSources.size()));
	mMixerMatrixCoefficients->setColumnCount(TTUInt32(aSinks.size()));

	for (TTInt32 source=0; source < (TTInt32) aSources.size(); source++) {
		TTSpatDBAPSource* dbapSource = getDBAPSource(aSources, source);

		// The source that we want to locate the nearest sink DBAPor:
		dbapSource->getPosition(sourceX, sourceY, sourceZ);

		// In order to DBAPind the nearest sink DBAPor a source, we'll start by assuming that sink 0 is the nearest
		aSinks[0].getPosition(sinkX, sinkY, sinkZ);

		// It is more eDBAPDBAPicient to do comparement on square oDBAP the distance
		sqrDistance = (sourceX-sinkX)*(sourceX-sinkX) + (sourceY-sinkY)*(sourceY-sinkY) + (sourceZ-sinkZ)*(sourceZ-sinkZ);
		smallestDist = sqrDistance;
		nearestSink = 0;

		// We also ensures that the matrix coeDBAPDBAPicient is set to 0 DBAPor the DBAPirst sink
		mMixerMatrixCoefficients->set2d(source, 0., 0.);

		// Now we iterate over the remaining sinks to see iDBAP any oDBAP them are closer
		for (TTInt32 sink=1; sink < (TTInt32) aSinks.size(); sink++) {

			aSinks[sink].getPosition(sinkX, sinkY, sinkZ);

			sqrDistance = (sourceX-sinkX)*(sourceX-sinkX) + (sourceY-sinkY)*(sourceY-sinkY) + (sourceZ-sinkZ)*(sourceZ-sinkZ);

			// Check iDBAP sinks[sink] is closer
			if ((smallestDist>sqrDistance)){
				smallestDist = sqrDistance;
				nearestSink = sink;

			}
			// In the process we also set all matrix coeDBAPDBAPicients to 0
			mMixerMatrixCoefficients->set2d(source, sink, 0.);
		}

		// We have now DBAPound the nearest sink, and all coeDBAPDBAPicients have been reset to 0.
		// The only thing leDBAPt to do is to send the coeDBAPDBAPicient oDBAP the nearest sink to 1
		mMixerMatrixCoefficients->set2d(source, nearestSink, 1.);
	}
}

void TTSpatDBAPRenderer::setRolloff(TTFloat64 aRolloff)
{
	mRolloff = aRolloff;
}
<commit_msg>DBAP unit is semiworking, still more work to do, but I wanted to save this<commit_after>/** @DBAPile
 *
 * @ingroup dspSpatLib
 *
 * @brieDBAP TODO
 *
 * @details TODO @n
 *
 * @authors Trond Lossius, Nils Peters, Timothy Place
 *
 * @copyright Copyright © 2011 by Trond Lossius, Nils Peters, and Timothy Place @n
 * This code is licensed under the terms oDBAP the "New BSD License" @n
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTSpatDBAPRenderer.h"
#include "TTSpatDBAPSource.h"

/// Methods DBAPor TTSpatDBAPRenderer: //////////////////////

TTSpatDBAPRenderer::TTSpatDBAPRenderer():
	mRolloff(6.0)
{
	;
}

TTSpatDBAPRenderer::~TTSpatDBAPRenderer()
{
	;
}

// A little helper method to get pointer to a DBAP source from the vector of standard spat sources
TTSpatDBAPSource* getDBAPSource(TTSpatSourceVector& aVector, int aSourceNumber)
{
	return (TTSpatDBAPSource*)&aVector[aSourceNumber];
}

void TTSpatDBAPRenderer::recalculateMatrixCoefficients(TTSpatSourceVector& aSources, TTSpatSinkVector& aSinks)
{
	/*
	 double k;											// Scaling coefficient
	 double k2inv;										// Inverse square of the scaling constant k
	 double dx, dy, dz;									// Distance vector
	 double r2;											// Bluriness ratio
	 double dia[MAX_NUM_DESTINATIONS];					// Distance to ith speaker to the power of x->a.
	 t_atom a[3];										// Output array of atoms

	 long i;

	 r2 = x->blur[n] * x->variance;
	 r2 = r2*r2;
	 k2inv = 0;
	 for (i=0; i<x->attr_num_destinations; i++) {
		dx = x->src_position[n].x - x->dst_position[i].x;
		dy = x->src_position[n].y - x->dst_position[i].y;
		dz = x->src_position[n].z - x->dst_position[i].z;
		dia[i] = pow(double(dx*dx + dy*dy + dz*dz + r2), double(0.5*x->a));
		k2inv = k2inv + (x->src_weight[n][i]*x->src_weight[n][i])/(dia[i]*dia[i]);
	 }
	 k = sqrt(1./k2inv);
	 k = k*x->master_gain*x->src_gain[n]*x->src_not_muted[n];

	 atom_setlong(&a[0], n);

	 for (i=0; i<x->attr_num_destinations; i++) {
		atom_setlong(&a[1], i);
		atom_setfloat(&a[2], x->src_weight[n][i]*k/dia[i]);
		outlet_anything(x->outlet[0], _sym_list, 3, a);
	 }
	 */

	TTFloat64 sourceX, sourceY, sourceZ;
	TTFloat64 sourceWidth;
	TTFloat64 sinkX, sinkY, sinkZ;
	TTFloat64 dx, dy, dz;

	TTFloat64 sqrDistance;
	TTFloat64 r2;										// Bluriness ratio

	TTFloat64 k;										// Scaling coefficient
	TTFloat64 k2inv;									// Inverse square of the scaling constant k

	mMixerMatrixCoefficients->setRowCount(TTUInt32(aSources.size()));
	mMixerMatrixCoefficients->setColumnCount(TTUInt32(aSinks.size()));

	std::vector<TTFloat64> dia;
	dia.resize(aSinks.size());

	TTFloat64 rolloffPowerFactor = log(pow(10., (mRolloff / 20.)))/log(2.);

	for (TTInt32 source=0; source < (TTInt32) aSources.size(); source++) {

		TTSpatDBAPSource* dbapSource = getDBAPSource(aSources, source);
		aSources[source].getPosition(sourceX, sourceY, sourceZ);

		dbapSource->getWidth(sourceWidth);
		r2 = sourceWidth * sourceWidth;		// TODO:  should be normalised with respect to x->variance

		// Iterate over sinks to calculate non-normalised gains for this source
		k2inv = 0;
		for (TTInt32 sink=0; sink < (TTInt32) aSinks.size(); sink++) {

			aSinks[sink].getPosition(sinkX, sinkY, sinkZ);
			dx = sourceX-sinkX;
			dy = sourceY-sinkY;
			dz = sourceZ-sinkZ;
			sqrDistance = (dx*dx + dy*dy + dz*dz + r2);
			dia[sink] = pow((dx*dx + dy*dy + dz*dz + r2), double(0.5*rolloffPowerFactor));
			// TODO: Introduce weight in equation below
			k2inv = k2inv + 1/(dia[sink]*dia[sink]);
		}

		// Calculate normalising factor
		k = sqrt(1./k2inv); // TODO: This should also cater for gain and muting of source

		// Iterate over sinks again and normalise gains
		for (TTInt32 sink=0; sink < (TTInt32) aSinks.size(); sink++) {
			mMixerMatrixCoefficients->set2d(source, sink, k/dia[sink]);
		}
	}
}

void TTSpatDBAPRenderer::setRolloff(TTFloat64 aRolloff)
{
	mRolloff = aRolloff;
}
<|endoftext|>


<commit_before>#ifndef MJOLNIR_READ_FORCEFIELD
#define MJOLNIR_READ_FORCEFIELD
#include <extlib/toml/toml.hpp>
#include <mjolnir/core/ForceField.hpp>
#include <mjolnir/util/get_toml_value.hpp>
#include <mjolnir/util/logger.hpp>
#include <mjolnir/input/read_interaction.hpp>

namespace mjolnir
{

template<typename traitsT>
LocalForceField<traitsT>
read_local_forcefield(std::vector<toml::Table> interactions,
                      const std::string& input_path)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_SCOPE(read_local_forcefield(), 0);
    MJOLNIR_LOG_INFO(interactions.size(),
                     " kinds of local interactions are found.");

    LocalForceField<traitsT> lff;
    for(const auto& interaction : interactions)
    {
        if(interaction.count("file_name") == 1)
        {
            MJOLNIR_SCOPE(interaction.count("file_name") == 1, 1);

            const std::string file_name = get_toml_value<std::string>(
                    interaction, "file_name", "[[local]]");
            MJOLNIR_LOG_INFO("file_name = ", file_name);

            if(interaction.size() != 1)
            {
                MJOLNIR_LOG_WARN(
                    "[[forcefields.local]] has `file_name` and other keys.");
                MJOLNIR_LOG_WARN(
                    "When `file_name` is provided, other values are ignored "
                    "because those are read from the specified file (",
                    file_name, ").");
            }

            const auto forcefield_file = toml::parse(input_path + file_name);
            if(forcefield_file.count("forcefields") == 1)
            {
                MJOLNIR_LOG_ERROR(
                    "[local] should be provided as a root object of file ",
                    file_name, ". but [[forcefields]] table found");
                std::exit(1);
            }
            if(forcefield_file.count("local") == 1)
            {
                MJOLNIR_LOG_ERROR(
                    "[local] should be provided as a root object of file ",
                    file_name, ". but [local] table found");

                if(forcefield_file.at("local").type() != toml::value_t::Table)
                {
                    MJOLNIR_LOG_ERROR("type of `local` is different from toml::"
                                      "Table in file (", file_name, ").");
                    MJOLNIR_LOG_ERROR("note: [[...]] means Array-of-Tables. "
                                      "please take care.");
                    std::exit(1);
                }
                lff.emplace(read_local_interaction<traitsT>(
                    get_toml_value<toml::Table>(
                        forcefield_file, "local", file_name)));
            }
            else
            {
                lff.emplace(read_local_interaction<traitsT>(forcefield_file));
            }
        }
        else
        {
            lff.emplace(read_local_interaction<traitsT>(interaction));
        }
    }
    return lff;
}

template<typename traitsT>
GlobalForceField<traitsT>
read_global_forcefield(std::vector<toml::Table> interactions,
                       const std::string& input_path)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_SCOPE(read_global_forcefield(), 0);
    MJOLNIR_LOG_INFO(interactions.size(),
                     " kinds of local interactions are found.");

    GlobalForceField<traitsT> gff;
    for(const auto& interaction : interactions)
    {
        if(interaction.count("file_name") == 1)
        {
            MJOLNIR_SCOPE(interaction.count("file_name") == 1, 1);

            const std::string file_name = get_toml_value<std::string>(
                    interaction, "file_name", "[[global]]");
            MJOLNIR_LOG_INFO("file_name = ", file_name);

            if(interaction.size() != 1)
            {
                MJOLNIR_LOG_WARN(
                    "[[forcefields.global]] has `file_name` and other keys.");
                MJOLNIR_LOG_WARN(
                    "When `file_name` is provided, other values are ignored "
                    "because those are read from the specified file (",
                    file_name, ").");
            }

            const auto forcefield_file = toml::parse(input_path + file_name);
            if(forcefield_file.count("forcefields") == 1)
            {
                MJOLNIR_LOG_ERROR(
                    "[global] should be provided as a root object of file ",
                    file_name, ". but [[forcefields]] table found");
                std::exit(1);
            }
            if(forcefield_file.count("global") == 1)
            {
                MJOLNIR_LOG_ERROR(
                    "[global] should be provided as a root object of file ",
                    file_name, ". but [global] key found");

                if(forcefield_file.at("global").type() != toml::value_t::Table)
                {
                    MJOLNIR_LOG_ERROR("type of `global` is different from "
                                      "toml::Table in file (", file_name, ").");
                    MJOLNIR_LOG_ERROR("note: [[...]] means Array-of-Tables. "
                                      "please take care.");
                    std::exit(1);
                }
                gff.emplace(read_global_interaction<traitsT>(
                    get_toml_value<toml::Table>(
                        forcefield_file, "global", file_name)));
            }
            else
            {
                gff.emplace(read_global_interaction<traitsT>(forcefield_file));
            }
        }
        else
        {
            gff.emplace(read_global_interaction<traitsT>(interaction));
        }
    }
    return gff;
}

template<typename traitsT>
ExternalForceField<traitsT>
read_external_forcefield(std::vector<toml::Table> interactions,
                         const std::string& input_path)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_SCOPE(read_external_forcefield(), 0);
    MJOLNIR_LOG_INFO(interactions.size(),
                     " kinds of external interactions are found.");

    ExternalForceField<traitsT> eff;
    for(const auto& interaction : interactions)
    {
        if(interaction.count("file_name") == 1)
        {
            MJOLNIR_SCOPE(interaction.count("file_name") == 1, 1);

            const auto file_name = get_toml_value<std::string>(
                        interaction, "file_name", "[[external]]");
            MJOLNIR_LOG_INFO("file_name = ", file_name);

            if(interaction.size() != 1)
            {
                MJOLNIR_LOG_WARN(
                    "[[forcefields.external]] has `file_name` and other keys.");
                MJOLNIR_LOG_WARN(
                    "When `file_name` is provided, other values are ignored "
                    "because those are read from the specified file (",
                    file_name, ").");
            }

            const auto forcefield_file = toml::parse(input_path + file_name);
            if(forcefield_file.count("forcefields") == 1)
            {
                MJOLNIR_LOG_ERROR(
                    "[external] should be provided as a root object of file ",
                    file_name, ". but [[forcefields]] table found");
                std::exit(1);
            }
            if(forcefield_file.count("external") == 1)
            {
                MJOLNIR_LOG_ERROR(
                    "[external] should be provided as a root object of file ",
                    file_name, ". but [external] key found");

                if(forcefield_file.at("external").type() != toml::value_t::Table)
                {
                    MJOLNIR_LOG_ERROR("type of `external` is different from "
                                      "toml::Table in file (", file_name, ").");
                    MJOLNIR_LOG_ERROR("note: [[...]] means Array-of-Tables. "
                                      "please take care.");
                    std::exit(1);
                }

                eff.emplace(read_external_interaction<traitsT>(
                    get_toml_value<toml::Table>(
                        forcefield_file, "external", file_name)));
            }
            else
            {
                eff.emplace(read_external_interaction<traitsT>(forcefield_file));
            }
        }
        else
        {
            eff.emplace(read_external_interaction<traitsT>(interaction));
        }
    }
    return eff;
}

template<typename traitsT>
ForceField<traitsT>
read_forcefield_from_table(const toml::Table& ff, const std::string& input_path)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_SCOPE(read_forcefield_from_table(), 0);

    std::vector<toml::Table> fflocal, ffglobal, ffexternal;
    if(ff.count("local") == 1)
    {
        MJOLNIR_LOG_INFO("LocalForceField found");
        fflocal = get_toml_value<std::vector<toml::Table>>(
                ff, "local", "[[forcefields]]");
    }
    if(ff.count("global") == 1)
    {
        MJOLNIR_LOG_INFO("GlobalForceField found");
        ffglobal = get_toml_value<std::vector<toml::Table>>(
                ff, "global", "[[forcefields]]");
    }
    if(ff.count("external") == 1)
    {
        MJOLNIR_LOG_INFO("ExternalForceField found");
        ffexternal = get_toml_value<std::vector<toml::Table>>(
                ff, "external", "[[forcefields]]");
    }

    for(const auto kv: ff)
    {
        if(kv.first != "local" && kv.first != "global" && kv.first != "external")
        {
            MJOLNIR_LOG_WARN("unknown key `", kv.first, "` appeared in "
                             "[[forcefields]] table. It will be ignored.");
        }
    }
    return ForceField<traitsT>(
        read_local_forcefield<traitsT>(std::move(fflocal), input_path),
        read_global_forcefield<traitsT>(std::move(ffglobal), input_path),
        read_external_forcefield<traitsT>(std::move(ffexternal), input_path));
}

template<typename traitsT>
ForceField<traitsT>
read_forcefield(const toml::Table& data, std::size_t N)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_SCOPE(read_forcefield(), 0);

    const auto& files = get_toml_value<toml::Table>(data, "files", "<root>");
    std::string input_path_("./");
    if(files.count("input_path") == 1)
    {
        input_path_ = get_toml_value<std::string>(files, "input_path", "[files]");
    }
    const auto input_path(input_path_); // add constness
    MJOLNIR_LOG_INFO("input path is -> ", input_path);

    const auto& ffs = get_toml_value<toml::Array>(data, "forcefields", "<root>");
    if(ffs.size() <= N)
    {
        throw std::out_of_range("no enough forcefields: " + std::to_string(N));
    }
    MJOLNIR_LOG_INFO(ffs.size(), " forcefields are provided");
    MJOLNIR_LOG_INFO("using ", N, "-th forcefield");

    const auto& ff = ffs.at(N).cast<toml::value_t::Table>();
    if(ff.count("file_name") == 1)
    {
        MJOLNIR_SCOPE(ff.count("file_name") == 1, 1);

        const std::string file_name =
            get_toml_value<std::string>(ff, "file_name", "[[forcefields]]");
        MJOLNIR_LOG_INFO("file_name = ", file_name);

        if(ff.size() != 1)
        {
            MJOLNIR_LOG_WARN("[[forcefields]] has `file_name` and other keys.");
            MJOLNIR_LOG_WARN("When `file_name` is provided, other values are "
                             "ignored because those are read from the specified"
                             " file (", file_name, ").");
        }

        const auto forcefield_file = toml::parse(input_path + file_name);
        if(forcefield_file.count("forcefields") == 1)
        {
            MJOLNIR_LOG_WARN("in `forcefield` file, root object is treated as "
                             "one of the [[forcefields]] tables.");
            MJOLNIR_LOG_WARN("define just [[local]], [[global]] and "
                             "[[external]] forcefields in ", file_name);
            MJOLNIR_LOG_WARN("in ", file_name, ", [forcefields] key found."
                             "trying to read it as a forcefield setup.");

            if(forcefield_file.at("forcefields").type() != toml::value_t::Table)
            {
                MJOLNIR_LOG_ERROR("type of `forcefields` is different from "
                                  "toml::Table in file (", file_name, ").");
                MJOLNIR_LOG_ERROR("note: [[...]] means Array-of-Tables. "
                                  "please take care.");
                std::exit(1);
            }
            return read_forcefield_from_table<traitsT>(forcefield_file.at(
                    "forcefields").template cast<toml::value_t::Table>(),
                    input_path);
        }
        return read_forcefield_from_table<traitsT>(forcefield_file, input_path);
    }

    // all-in-one file
    return read_forcefield_from_table<traitsT>(ff, input_path);
}

} // mjolnir
#endif// MJOLNIR_READ_FORCEFIELD
<commit_msg>add LOG_NOTICE to read_forcefield<commit_after>#ifndef MJOLNIR_READ_FORCEFIELD
#define MJOLNIR_READ_FORCEFIELD
#include <extlib/toml/toml.hpp>
#include <mjolnir/core/ForceField.hpp>
#include <mjolnir/util/get_toml_value.hpp>
#include <mjolnir/util/logger.hpp>
#include <mjolnir/input/read_interaction.hpp>

namespace mjolnir
{

template<typename traitsT>
LocalForceField<traitsT>
read_local_forcefield(std::vector<toml::Table> interactions,
                      const std::string& input_path)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_SCOPE(read_local_forcefield(), 0);
    MJOLNIR_LOG_INFO(interactions.size(),
                     " kinds of local interactions are found.");

    LocalForceField<traitsT> lff;
    for(const auto& interaction : interactions)
    {
        if(interaction.count("file_name") == 1)
        {
            MJOLNIR_SCOPE(interaction.count("file_name") == 1, 1);

            const std::string file_name = get_toml_value<std::string>(
                    interaction, "file_name", "[[local]]");
            MJOLNIR_LOG_INFO("file_name = ", file_name);

            if(interaction.size() != 1)
            {
                MJOLNIR_LOG_WARN(
                    "[[forcefields.local]] has `file_name` and other keys.");
                MJOLNIR_LOG_WARN(
                    "When `file_name` is provided, other values are ignored "
                    "because those are read from the specified file (",
                    file_name, ").");
            }

            MJOLNIR_LOG_NOTICE("local forcefield is defined in `",
                               input_path, file_name, "`.");
            const auto forcefield_file = toml::parse(input_path + file_name);
            if(forcefield_file.count("forcefields") == 1)
            {
                MJOLNIR_LOG_ERROR(
                    "[local] should be provided as a root object of file ",
                    file_name, ". but [[forcefields]] table found");
                std::exit(1);
            }
            if(forcefield_file.count("local") == 1)
            {
                MJOLNIR_LOG_ERROR(
                    "[local] should be provided as a root object of file ",
                    file_name, ". but [local] table found");

                if(forcefield_file.at("local").type() != toml::value_t::Table)
                {
                    MJOLNIR_LOG_ERROR("type of `local` is different from toml::"
                                      "Table in file (", file_name, ").");
                    MJOLNIR_LOG_ERROR("note: [[...]] means Array-of-Tables. "
                                      "please take care.");
                    std::exit(1);
                }
                lff.emplace(read_local_interaction<traitsT>(
                    get_toml_value<toml::Table>(
                        forcefield_file, "local", file_name)));
            }
            else
            {
                lff.emplace(read_local_interaction<traitsT>(forcefield_file));
            }
        }
        else
        {
            lff.emplace(read_local_interaction<traitsT>(interaction));
        }
    }
    return lff;
}

template<typename traitsT>
GlobalForceField<traitsT>
read_global_forcefield(std::vector<toml::Table> interactions,
                       const std::string& input_path)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_SCOPE(read_global_forcefield(), 0);
    MJOLNIR_LOG_INFO(interactions.size(),
                     " kinds of local interactions are found.");

    GlobalForceField<traitsT> gff;
    for(const auto& interaction : interactions)
    {
        if(interaction.count("file_name") == 1)
        {
            MJOLNIR_SCOPE(interaction.count("file_name") == 1, 1);

            const std::string file_name = get_toml_value<std::string>(
                    interaction, "file_name", "[[global]]");
            MJOLNIR_LOG_INFO("file_name = ", file_name);

            if(interaction.size() != 1)
            {
                MJOLNIR_LOG_WARN(
                    "[[forcefields.global]] has `file_name` and other keys.");
                MJOLNIR_LOG_WARN(
                    "When `file_name` is provided, other values are ignored "
                    "because those are read from the specified file (",
                    file_name, ").");
            }

            MJOLNIR_LOG_NOTICE("global forcefield is defined in `",
                               input_path, file_name, "`.");
            const auto forcefield_file = toml::parse(input_path + file_name);
            if(forcefield_file.count("forcefields") == 1)
            {
                MJOLNIR_LOG_ERROR(
                    "[global] should be provided as a root object of file ",
                    file_name, ". but [[forcefields]] table found");
                std::exit(1);
            }
            if(forcefield_file.count("global") == 1)
            {
                MJOLNIR_LOG_ERROR(
                    "[global] should be provided as a root object of file ",
                    file_name, ". but [global] key found");

                if(forcefield_file.at("global").type() != toml::value_t::Table)
                {
                    MJOLNIR_LOG_ERROR("type of `global` is different from "
                                      "toml::Table in file (", file_name, ").");
                    MJOLNIR_LOG_ERROR("note: [[...]] means Array-of-Tables. "
                                      "please take care.");
                    std::exit(1);
                }
                gff.emplace(read_global_interaction<traitsT>(
                    get_toml_value<toml::Table>(
                        forcefield_file, "global", file_name)));
            }
            else
            {
                gff.emplace(read_global_interaction<traitsT>(forcefield_file));
            }
        }
        else
        {
            gff.emplace(read_global_interaction<traitsT>(interaction));
        }
    }
    return gff;
}

template<typename traitsT>
ExternalForceField<traitsT>
read_external_forcefield(std::vector<toml::Table> interactions,
                         const std::string& input_path)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_SCOPE(read_external_forcefield(), 0);
    MJOLNIR_LOG_INFO(interactions.size(),
                     " kinds of external interactions are found.");

    ExternalForceField<traitsT> eff;
    for(const auto& interaction : interactions)
    {
        if(interaction.count("file_name") == 1)
        {
            MJOLNIR_SCOPE(interaction.count("file_name") == 1, 1);

            const auto file_name = get_toml_value<std::string>(
                        interaction, "file_name", "[[external]]");
            MJOLNIR_LOG_INFO("file_name = ", file_name);

            if(interaction.size() != 1)
            {
                MJOLNIR_LOG_WARN(
                    "[[forcefields.external]] has `file_name` and other keys.");
                MJOLNIR_LOG_WARN(
                    "When `file_name` is provided, other values are ignored "
                    "because those are read from the specified file (",
                    file_name, ").");
            }

            MJOLNIR_LOG_NOTICE("external forcefield is defined in `",
                               input_path, file_name, "`.");
            const auto forcefield_file = toml::parse(input_path + file_name);
            if(forcefield_file.count("forcefields") == 1)
            {
                MJOLNIR_LOG_ERROR(
                    "[external] should be provided as a root object of file ",
                    file_name, ". but [[forcefields]] table found");
                std::exit(1);
            }
            if(forcefield_file.count("external") == 1)
            {
                MJOLNIR_LOG_ERROR(
                    "[external] should be provided as a root object of file ",
                    file_name, ". but [external] key found");

                if(forcefield_file.at("external").type() != toml::value_t::Table)
                {
                    MJOLNIR_LOG_ERROR("type of `external` is different from "
                                      "toml::Table in file (", file_name, ").");
                    MJOLNIR_LOG_ERROR("note: [[...]] means Array-of-Tables. "
                                      "please take care.");
                    std::exit(1);
                }

                eff.emplace(read_external_interaction<traitsT>(
                    get_toml_value<toml::Table>(
                        forcefield_file, "external", file_name)));
            }
            else
            {
                eff.emplace(read_external_interaction<traitsT>(forcefield_file));
            }
        }
        else
        {
            eff.emplace(read_external_interaction<traitsT>(interaction));
        }
    }
    return eff;
}

template<typename traitsT>
ForceField<traitsT>
read_forcefield_from_table(const toml::Table& ff, const std::string& input_path)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_SCOPE(read_forcefield_from_table(), 0);

    std::vector<toml::Table> fflocal, ffglobal, ffexternal;
    if(ff.count("local") == 1)
    {
        MJOLNIR_LOG_INFO("LocalForceField found");
        fflocal = get_toml_value<std::vector<toml::Table>>(
                ff, "local", "[[forcefields]]");
    }
    if(ff.count("global") == 1)
    {
        MJOLNIR_LOG_INFO("GlobalForceField found");
        ffglobal = get_toml_value<std::vector<toml::Table>>(
                ff, "global", "[[forcefields]]");
    }
    if(ff.count("external") == 1)
    {
        MJOLNIR_LOG_INFO("ExternalForceField found");
        ffexternal = get_toml_value<std::vector<toml::Table>>(
                ff, "external", "[[forcefields]]");
    }

    for(const auto kv: ff)
    {
        if(kv.first != "local" && kv.first != "global" && kv.first != "external")
        {
            MJOLNIR_LOG_WARN("unknown key `", kv.first, "` appeared in "
                             "[[forcefields]] table. It will be ignored.");
        }
    }
    return ForceField<traitsT>(
        read_local_forcefield<traitsT>(std::move(fflocal), input_path),
        read_global_forcefield<traitsT>(std::move(ffglobal), input_path),
        read_external_forcefield<traitsT>(std::move(ffexternal), input_path));
}

template<typename traitsT>
ForceField<traitsT>
read_forcefield(const toml::Table& data, std::size_t N)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_SCOPE(read_forcefield(), 0);
    MJOLNIR_LOG_NOTICE("reading ", N, "-th [[forcefield]].");

    const auto& files = get_toml_value<toml::Table>(data, "files", "<root>");
    std::string input_path_("./");
    if(files.count("input_path") == 1)
    {
        input_path_ = get_toml_value<std::string>(files, "input_path", "[files]");
    }
    const auto input_path(input_path_); // add constness
    MJOLNIR_LOG_INFO("input path is -> ", input_path);

    const auto& ffs = get_toml_value<toml::Array>(data, "forcefields", "<root>");
    if(ffs.size() <= N)
    {
        throw std::out_of_range("no enough forcefields: " + std::to_string(N));
    }
    MJOLNIR_LOG_INFO(ffs.size(), " forcefields are provided");
    MJOLNIR_LOG_INFO("using ", N, "-th forcefield");

    const auto& ff = ffs.at(N).cast<toml::value_t::Table>();
    if(ff.count("file_name") == 1)
    {
        MJOLNIR_SCOPE(ff.count("file_name") == 1, 1);

        const std::string file_name =
            get_toml_value<std::string>(ff, "file_name", "[[forcefields]]");
        MJOLNIR_LOG_INFO("file_name = ", file_name);

        if(ff.size() != 1)
        {
            MJOLNIR_LOG_WARN("[[forcefields]] has `file_name` and other keys.");
            MJOLNIR_LOG_WARN("When `file_name` is provided, other values are "
                             "ignored because those are read from the specified"
                             " file (", file_name, ").");
        }

        MJOLNIR_LOG_NOTICE("forcefield is defined in `", input_path, file_name, "`.");
        const auto forcefield_file = toml::parse(input_path + file_name);
        if(forcefield_file.count("forcefields") == 1)
        {
            MJOLNIR_LOG_WARN("in `forcefield` file, root object is treated as "
                             "one of the [[forcefields]] tables.");
            MJOLNIR_LOG_WARN("define just [[local]], [[global]] and "
                             "[[external]] forcefields in ", file_name);
            MJOLNIR_LOG_WARN("in ", file_name, ", [forcefields] key found."
                             "trying to read it as a forcefield setup.");

            if(forcefield_file.at("forcefields").type() != toml::value_t::Table)
            {
                MJOLNIR_LOG_ERROR("type of `forcefields` is different from "
                                  "toml::Table in file (", file_name, ").");
                MJOLNIR_LOG_ERROR("note: [[...]] means Array-of-Tables. "
                                  "please take care.");
                std::exit(1);
            }
            return read_forcefield_from_table<traitsT>(forcefield_file.at(
                    "forcefields").template cast<toml::value_t::Table>(),
                    input_path);
        }
        return read_forcefield_from_table<traitsT>(forcefield_file, input_path);
    }

    // all-in-one file
    return read_forcefield_from_table<traitsT>(ff, input_path);
}

} // mjolnir
#endif// MJOLNIR_READ_FORCEFIELD
<|endoftext|>