<commit_before>/* Author: Wolfgang Bangerth, Texas A&M University, 2008 */

/*    $Id$       */
/*                                                                */
/*    Copyright (C) 2013 by the deal.II authors */
/*                                                                */
/*    This file is subject to QPL and may not be  distributed     */
/*    without copyright and license information. Please refer     */
/*    to the file deal.II/doc/license.html for the  text  and     */
/*    further information on this license.                        */

#include <deal.II/base/utilities.h>
#include <deal.II/base/quadrature_lib.h>
#include <deal.II/base/function.h>
#include <deal.II/base/logstream.h>
#include <deal.II/lac/vector.h>
#include <deal.II/lac/full_matrix.h>
#include <deal.II/lac/sparse_matrix.h>
#include <deal.II/lac/solver_cg.h>
#include <deal.II/lac/precondition.h>
#include <deal.II/lac/constraint_matrix.h>
#include <deal.II/grid/tria.h>
#include <deal.II/grid/grid_generator.h>
#include <deal.II/grid/grid_out.h>
#include <deal.II/grid/tria_accessor.h>
#include <deal.II/grid/tria_iterator.h>
#include <deal.II/dofs/dof_handler.h>
#include <deal.II/dofs/dof_accessor.h>
#include <deal.II/dofs/dof_tools.h>
#include <deal.II/fe/fe_q.h>
#include <deal.II/fe/fe_values.h>
#include <deal.II/numerics/data_out.h>
#include <deal.II/numerics/vector_tools.h>
#include <deal.II/numerics/matrix_tools.h>

#include <fstream>
#include <iostream>

namespace Step26
{
  using namespace dealii;

  template<int dim>
  class HeatEquation
  {
  public:
    HeatEquation();
    void run();

  private:
    void setup_system();
    void solve_u();
    void output_results() const;

    Triangulation<dim> triangulation;
    FE_Q<dim> fe;
    DoFHandler<dim> dof_handler;

    ConstraintMatrix constraints;

    SparsityPattern sparsity_pattern;
    SparseMatrix<double> mass_matrix;
    SparseMatrix<double> laplace_matrix;
    SparseMatrix<double> system_matrix;

    Vector<double> solution;
    Vector<double> old_solution;
    Vector<double> system_rhs;

    double time, time_step;
    unsigned int timestep_number;
    const double theta;
  };

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

  template<int dim>
  class RightHandSide: public Function<dim>
  {
  public:
    RightHandSide() :
    Function<dim>(),
    period (0.2)
    {}

    virtual double value(const Point<dim> &p,
                         const unsigned int component = 0) const;

  private:
    const double period;
  };

  template<int dim>
  double RightHandSide<dim>::value(const Point<dim> &p,
                                   const unsigned int component) const
  {
    Assert (component == 0, ExcInternalError());
    Assert (dim == 2, ExcNotImplemented());

    const double time = this->get_time();
    const double point_within_period = (time/period - std::floor(time/period));

    if ((point_within_period >= 0.0) && (point_within_period <= 0.2))
      {
	if ((p[0] > 0.5) && (p[1] > -0.5))
	  return 1;
	else
	  return 0;
      }
    else if ((point_within_period >= 0.5) && (point_within_period <= 0.7))
      {
	if ((p[0] > -0.5) && (p[1] > 0.5))
	  return 1;
	else
	  return 0;
      }
    else
      return 0;
  }

  template<int dim>
  class BoundaryValues: public Function<dim>
  {
  public:
    BoundaryValues() :
      Function<dim>()
    {
    }
    virtual ~BoundaryValues()
    {
    }
    virtual double value(const Point<dim> &p,
                         const unsigned int component = 0) const;
  };

  template<int dim>
  double BoundaryValues<dim>::value(const Point<dim> &/*p*/,
                                     const unsigned int component) const
  {
    Assert(component == 0, ExcInternalError());
    return 0; // Zero-Dirichlet Boundary
  }

  template<int dim>
  HeatEquation<dim>::HeatEquation() :
    fe(1), dof_handler(triangulation), time_step(1. / 500), theta(0.5)
  {
  }

  template<int dim>
  void HeatEquation<dim>::setup_system()
  {
    GridGenerator::hyper_L (triangulation);
    triangulation.refine_global (5);

    std::cout << "Number of active cells: " << triangulation.n_active_cells()
              << std::endl;

    dof_handler.distribute_dofs(fe);

    std::cout << "Number of degrees of freedom: " << dof_handler.n_dofs()
              << std::endl << std::endl;

    sparsity_pattern.reinit(dof_handler.n_dofs(), dof_handler.n_dofs(),
                            dof_handler.max_couplings_between_dofs());
    DoFTools::make_sparsity_pattern(dof_handler, sparsity_pattern);
    sparsity_pattern.compress();

    mass_matrix.reinit(sparsity_pattern);
    laplace_matrix.reinit(sparsity_pattern);
    system_matrix.reinit(sparsity_pattern);

    MatrixCreator::create_mass_matrix(dof_handler, QGauss<dim>(3), mass_matrix);
    MatrixCreator::create_laplace_matrix(dof_handler, QGauss<dim>(3),
                                         laplace_matrix);

    solution.reinit(dof_handler.n_dofs());
    old_solution.reinit(dof_handler.n_dofs());
    system_rhs.reinit(dof_handler.n_dofs());

    constraints.close();
  }

  template<int dim>
  void HeatEquation<dim>::solve_u()
  {
    SolverControl solver_control(1000, 1e-8 * system_rhs.l2_norm());
    SolverCG<> cg(solver_control);

    PreconditionSSOR<> preconditioner;
    preconditioner.initialize(system_matrix, 1.0);

    cg.solve(system_matrix, solution, system_rhs, preconditioner);

    std::cout << "   u-equation: " << solver_control.last_step()
              << " CG iterations." << std::endl;
  }

  template<int dim>
  void HeatEquation<dim>::output_results() const
  {
    DataOut<dim> data_out;

    data_out.attach_dof_handler(dof_handler);
    data_out.add_data_vector(solution, "U");

    data_out.build_patches();

    const std::string filename = "solution-"
                                 + Utilities::int_to_string(timestep_number, 3) + ".vtk";
    std::ofstream output(filename.c_str());
    data_out.write_vtk(output);

    std::cout << "    max= " << time << ' ' << solution.linfty_norm() << std::endl;
  }

  template<int dim>
  void HeatEquation<dim>::run()
  {
    setup_system();

    VectorTools::interpolate(dof_handler, ZeroFunction<dim>(), solution);

    timestep_number = 0;
    output_results();

    VectorTools::interpolate(dof_handler, ZeroFunction<dim>(),
                             old_solution);

    Vector<double> tmp(solution.size());
    Vector<double> forcing_terms(solution.size());

    while (time <= 0.5)
      {
	time += time_step;
	++timestep_number;

        std::cout << "Time step " << timestep_number << " at t=" << time
                  << std::endl;

        mass_matrix.vmult(system_rhs, old_solution);

        laplace_matrix.vmult(tmp, old_solution);
        system_rhs.add(-(1 - theta) * time_step, tmp);

        RightHandSide<dim> rhs_function;
        rhs_function.set_time(time);
        VectorTools::create_right_hand_side(dof_handler, QGauss<dim>(2),
                                            rhs_function, tmp);
        forcing_terms = tmp;
        forcing_terms *= time_step * theta;

        rhs_function.set_time(time - time_step);
        VectorTools::create_right_hand_side(dof_handler, QGauss<dim>(2),
                                            rhs_function, tmp);

        forcing_terms.add(time_step * (1 - theta), tmp);

        system_rhs += forcing_terms;

        {
          BoundaryValues<dim> boundary_values_function;
          boundary_values_function.set_time(time);

          std::map<unsigned int, double> boundary_values;
          VectorTools::interpolate_boundary_values(dof_handler,
						   0,
                                                   boundary_values_function,
						   boundary_values);

          system_matrix.copy_from(mass_matrix);
          system_matrix.add(theta * time_step, laplace_matrix);
          MatrixTools::apply_boundary_values(boundary_values,
					     system_matrix,
                                             solution,
					     system_rhs);
        }
        solve_u();

        output_results();

        old_solution = solution;
      }
  }
}

int main()
{
  try
    {
      using namespace dealii;
      using namespace Step26;

      deallog.depth_console(0);

      HeatEquation<2> heat_equation_solver;
      heat_equation_solver.run();

    }
  catch (std::exception &exc)
    {
      std::cerr << std::endl << std::endl
                << "----------------------------------------------------"
                << std::endl;
      std::cerr << "Exception on processing: " << std::endl << exc.what()
                << std::endl << "Aborting!" << std::endl
                << "----------------------------------------------------"
                << std::endl;

      return 1;
    }
  catch (...)
    {
      std::cerr << std::endl << std::endl
                << "----------------------------------------------------"
                << std::endl;
      std::cerr << "Unknown exception!" << std::endl << "Aborting!"
                << std::endl
                << "----------------------------------------------------"
                << std::endl;
      return 1;
    }

  return 0;
}
<commit_msg>More cleanups.<commit_after>/* Author: Wolfgang Bangerth, Texas A&M University, 2008 */

/*    $Id$       */
/*                                                                */
/*    Copyright (C) 2013 by the deal.II authors */
/*                                                                */
/*    This file is subject to QPL and may not be  distributed     */
/*    without copyright and license information. Please refer     */
/*    to the file deal.II/doc/license.html for the  text  and     */
/*    further information on this license.                        */

#include <deal.II/base/utilities.h>
#include <deal.II/base/quadrature_lib.h>
#include <deal.II/base/function.h>
#include <deal.II/base/logstream.h>
#include <deal.II/lac/vector.h>
#include <deal.II/lac/full_matrix.h>
#include <deal.II/lac/sparse_matrix.h>
#include <deal.II/lac/solver_cg.h>
#include <deal.II/lac/precondition.h>
#include <deal.II/lac/constraint_matrix.h>
#include <deal.II/grid/tria.h>
#include <deal.II/grid/grid_generator.h>
#include <deal.II/grid/grid_out.h>
#include <deal.II/grid/tria_accessor.h>
#include <deal.II/grid/tria_iterator.h>
#include <deal.II/dofs/dof_handler.h>
#include <deal.II/dofs/dof_accessor.h>
#include <deal.II/dofs/dof_tools.h>
#include <deal.II/fe/fe_q.h>
#include <deal.II/fe/fe_values.h>
#include <deal.II/numerics/data_out.h>
#include <deal.II/numerics/vector_tools.h>
#include <deal.II/numerics/matrix_tools.h>

#include <fstream>
#include <iostream>

namespace Step26
{
  using namespace dealii;

  template<int dim>
  class HeatEquation
  {
  public:
    HeatEquation();
    void run();

  private:
    void setup_system();
    void solve_time_step();
    void output_results() const;

    Triangulation<dim>   triangulation;
    FE_Q<dim>            fe;
    DoFHandler<dim>      dof_handler;

    ConstraintMatrix     constraints;

    SparsityPattern      sparsity_pattern;
    SparseMatrix<double> mass_matrix;
    SparseMatrix<double> laplace_matrix;
    SparseMatrix<double> system_matrix;

    Vector<double>       solution;
    Vector<double>       old_solution;
    Vector<double>       system_rhs;

    double               time;
    double               time_step;
    unsigned int         timestep_number;

    const double         theta;
  };

  template<int dim>
  class RightHandSide: public Function<dim>
  {
  public:
    RightHandSide()
      :
      Function<dim>(),
      period (0.2)
    {}

    virtual double value(const Point<dim> &p,
                         const unsigned int component = 0) const;

  private:
    const double period;
  };

  template<int dim>
  double RightHandSide<dim>::value(const Point<dim> &p,
                                   const unsigned int component) const
  {
    Assert (component == 0, ExcInternalError());
    Assert (dim == 2, ExcNotImplemented());

    const double time = this->get_time();
    const double point_within_period = (time/period - std::floor(time/period));

    if ((point_within_period >= 0.0) && (point_within_period <= 0.2))
      {
        if ((p[0] > 0.5) && (p[1] > -0.5))
          return 1;
        else
          return 0;
      }
    else if ((point_within_period >= 0.5) && (point_within_period <= 0.7))
      {
        if ((p[0] > -0.5) && (p[1] > 0.5))
          return 1;
        else
          return 0;
      }
    else
      return 0;
  }

  template<int dim>
  class BoundaryValues: public Function<dim>
  {
  public:
    BoundaryValues()
      :
      Function<dim>()
    {
    }

    virtual double value(const Point<dim> &p,
                         const unsigned int component = 0) const;
  };

  template<int dim>
  double BoundaryValues<dim>::value(const Point<dim> &/*p*/,
                                    const unsigned int component) const
  {
    Assert(component == 0, ExcInternalError());
    return 0;
  }

  template<int dim>
  HeatEquation<dim>::HeatEquation()
    :
    fe(1),
    dof_handler(triangulation),
    time_step(1. / 500),
    theta(0.5)
  {
  }

  template<int dim>
  void HeatEquation<dim>::setup_system()
  {
    GridGenerator::hyper_L (triangulation);
    triangulation.refine_global (5);

    std::cout << "Number of active cells: " << triangulation.n_active_cells()
              << std::endl;

    dof_handler.distribute_dofs(fe);

    std::cout << "Number of degrees of freedom: " << dof_handler.n_dofs()
              << std::endl << std::endl;

    sparsity_pattern.reinit(dof_handler.n_dofs(),
                            dof_handler.n_dofs(),
                            dof_handler.max_couplings_between_dofs());
    DoFTools::make_sparsity_pattern(dof_handler,
                                    sparsity_pattern);
    sparsity_pattern.compress();

    mass_matrix.reinit(sparsity_pattern);
    laplace_matrix.reinit(sparsity_pattern);
    system_matrix.reinit(sparsity_pattern);

    MatrixCreator::create_mass_matrix(dof_handler,
                                      QGauss<dim>(fe.degree+1),
                                      mass_matrix);
    MatrixCreator::create_laplace_matrix(dof_handler,
                                         QGauss<dim>(fe.degree+1),
                                         laplace_matrix);

    solution.reinit(dof_handler.n_dofs());
    old_solution.reinit(dof_handler.n_dofs());
    system_rhs.reinit(dof_handler.n_dofs());

    constraints.close();
  }

  template<int dim>
  void HeatEquation<dim>::solve_time_step()
  {
    SolverControl solver_control(1000, 1e-8 * system_rhs.l2_norm());
    SolverCG<> cg(solver_control);

    PreconditionSSOR<> preconditioner;
    preconditioner.initialize(system_matrix, 1.0);

    cg.solve(system_matrix, solution, system_rhs, preconditioner);

    std::cout << "     " << solver_control.last_step()
              << " CG iterations." << std::endl;
  }

  template<int dim>
  void HeatEquation<dim>::output_results() const
  {
    DataOut<dim> data_out;

    data_out.attach_dof_handler(dof_handler);
    data_out.add_data_vector(solution, "U");

    data_out.build_patches();

    const std::string filename = "solution-"
                                 + Utilities::int_to_string(timestep_number, 3) +
                                 ".vtk";
    std::ofstream output(filename.c_str());
    data_out.write_vtk(output);
  }

  template<int dim>
  void HeatEquation<dim>::run()
  {
    setup_system();

    VectorTools::interpolate(dof_handler,
                             ZeroFunction<dim>(),
                             old_solution);
    solution = old_solution;

    timestep_number = 0;
    output_results();

    Vector<double> tmp(solution.size());
    Vector<double> forcing_terms(solution.size());

    while (time <= 0.5)
      {
        time += time_step;
        ++timestep_number;

        std::cout << "Time step " << timestep_number << " at t=" << time
                  << std::endl;

        mass_matrix.vmult(system_rhs, old_solution);

        laplace_matrix.vmult(tmp, old_solution);
        system_rhs.add(-(1 - theta) * time_step, tmp);

        RightHandSide<dim> rhs_function;
        rhs_function.set_time(time);
        VectorTools::create_right_hand_side(dof_handler,
                                            QGauss<dim>(fe.degree+1),
                                            rhs_function,
                                            tmp);
        forcing_terms = tmp;
        forcing_terms *= time_step * theta;

        rhs_function.set_time(time - time_step);
        VectorTools::create_right_hand_side(dof_handler,
                                            QGauss<dim>(fe.degree+1),
                                            rhs_function,
                                            tmp);

        forcing_terms.add(time_step * (1 - theta), tmp);

        system_rhs += forcing_terms;

        {
          BoundaryValues<dim> boundary_values_function;
          boundary_values_function.set_time(time);

          std::map<unsigned int, double> boundary_values;
          VectorTools::interpolate_boundary_values(dof_handler,
                                                   0,
                                                   boundary_values_function,
                                                   boundary_values);

          system_matrix.copy_from(mass_matrix);
          system_matrix.add(theta * time_step, laplace_matrix);
          MatrixTools::apply_boundary_values(boundary_values,
                                             system_matrix,
                                             solution,
                                             system_rhs);
        }

        solve_time_step();

        output_results();

        old_solution = solution;
      }
  }
}

int main()
{
  try
    {
      using namespace dealii;
      using namespace Step26;

      deallog.depth_console(0);

      HeatEquation<2> heat_equation_solver;
      heat_equation_solver.run();

    }
  catch (std::exception &exc)
    {
      std::cerr << std::endl << std::endl
                << "----------------------------------------------------"
                << std::endl;
      std::cerr << "Exception on processing: " << std::endl << exc.what()
                << std::endl << "Aborting!" << std::endl
                << "----------------------------------------------------"
                << std::endl;

      return 1;
    }
  catch (...)
    {
      std::cerr << std::endl << std::endl
                << "----------------------------------------------------"
                << std::endl;
      std::cerr << "Unknown exception!" << std::endl << "Aborting!"
                << std::endl
                << "----------------------------------------------------"
                << std::endl;
      return 1;
    }

  return 0;
}
<|endoftext|>


<commit_before>//===- TpiStream.cpp - PDB Type Info (TPI) Stream 2 Access ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"

#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/StreamReader.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/PDB/Raw/Hash.h"
#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"

#include "llvm/Support/Endian.h"

using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::support;
using namespace llvm::pdb;

namespace {
const uint32_t MinHashBuckets = 0x1000;
const uint32_t MaxHashBuckets = 0x40000;
}

// This corresponds to `HDR` in PDB/dbi/tpi.h.
struct TpiStream::HeaderInfo {
  struct EmbeddedBuf {
    little32_t Off;
    ulittle32_t Length;
  };

  ulittle32_t Version;
  ulittle32_t HeaderSize;
  ulittle32_t TypeIndexBegin;
  ulittle32_t TypeIndexEnd;
  ulittle32_t TypeRecordBytes;

  // The following members correspond to `TpiHash` in PDB/dbi/tpi.h.
  ulittle16_t HashStreamIndex;
  ulittle16_t HashAuxStreamIndex;
  ulittle32_t HashKeySize;
  ulittle32_t NumHashBuckets;

  EmbeddedBuf HashValueBuffer;
  EmbeddedBuf IndexOffsetBuffer;
  EmbeddedBuf HashAdjBuffer;
};

TpiStream::TpiStream(const PDBFile &File,
                     std::unique_ptr<MappedBlockStream> Stream)
    : Pdb(File), Stream(std::move(Stream)) {}

TpiStream::~TpiStream() {}

// Corresponds to `fUDTAnon`.
template <typename T> static bool isAnonymous(T &Rec) {
  StringRef Name = Rec.getUniqueName();
  return Name == "<unnamed-tag>" || Name == "__unnamed" ||
      Name.endswith("::<unnamed-tag>") || Name.endswith("::__unnamed");
}

// Computes a hash for a given TPI record.
template <typename T>
static uint32_t getTpiHash(T &Rec, const CVRecord<TypeLeafKind> &RawRec) {
  auto Opts = static_cast<uint16_t>(Rec.getOptions());

  bool ForwardRef =
      Opts & static_cast<uint16_t>(ClassOptions::ForwardReference);
  bool Scoped = Opts & static_cast<uint16_t>(ClassOptions::Scoped);
  bool UniqueName = Opts & static_cast<uint16_t>(ClassOptions::HasUniqueName);
  bool IsAnon = UniqueName && isAnonymous(Rec);

  if (!ForwardRef && !Scoped && !IsAnon)
    return hashStringV1(Rec.getName());
  if (!ForwardRef && UniqueName && !IsAnon)
    return hashStringV1(Rec.getUniqueName());
  return hashBufferV8(RawRec.RawData);
}

namespace {
class TpiHashVerifier : public TypeVisitorCallbacks {
public:
  TpiHashVerifier(FixedStreamArray<support::ulittle32_t> &HashValues,
                  uint32_t NumHashBuckets)
      : HashValues(HashValues), NumHashBuckets(NumHashBuckets) {}

  Error visitUdtSourceLine(UdtSourceLineRecord &Rec) override {
    return verifySourceLine(Rec);
  }

  Error visitUdtModSourceLine(UdtModSourceLineRecord &Rec) override {
    return verifySourceLine(Rec);
  }

  Error visitClass(ClassRecord &Rec) override { return verify(Rec); }
  Error visitEnum(EnumRecord &Rec) override { return verify(Rec); }
  Error visitUnion(UnionRecord &Rec) override { return verify(Rec); }

  Error visitTypeBegin(const CVRecord<TypeLeafKind> &Rec) override {
    ++Index;
    RawRecord = &Rec;
    return Error::success();
  }

private:
  template <typename T> Error verify(T &Rec) {
    uint32_t Hash = getTpiHash(Rec, *RawRecord);
    if (Hash % NumHashBuckets != HashValues[Index])
      return make_error<RawError>(raw_error_code::invalid_tpi_hash);
    return Error::success();
  }

  template <typename T> Error verifySourceLine(T &Rec) {
    char Buf[4];
    support::endian::write32le(Buf, Rec.getUDT().getIndex());
    uint32_t Hash = hashStringV1(StringRef(Buf, 4));
    if (Hash % NumHashBuckets != HashValues[Index])
      return make_error<RawError>(raw_error_code::invalid_tpi_hash);
    return Error::success();
  }

  FixedStreamArray<support::ulittle32_t> HashValues;
  const CVRecord<TypeLeafKind> *RawRecord;
  uint32_t NumHashBuckets;
  uint32_t Index = -1;
};
}

// Verifies that a given type record matches with a given hash value.
// Currently we only verify SRC_LINE records.
Error TpiStream::verifyHashValues() {
  TpiHashVerifier Verifier(HashValues, Header->NumHashBuckets);
  CVTypeVisitor Visitor(Verifier);
  return Visitor.visitTypeStream(TypeRecords);
}

Error TpiStream::reload() {
  StreamReader Reader(*Stream);

  if (Reader.bytesRemaining() < sizeof(HeaderInfo))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "TPI Stream does not contain a header.");

  if (Reader.readObject(Header))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "TPI Stream does not contain a header.");

  if (Header->Version != PdbTpiV80)
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Unsupported TPI Version.");

  if (Header->HeaderSize != sizeof(HeaderInfo))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Corrupt TPI Header size.");

  if (Header->HashKeySize != sizeof(ulittle32_t))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "TPI Stream expected 4 byte hash key size.");

  if (Header->NumHashBuckets < MinHashBuckets ||
      Header->NumHashBuckets > MaxHashBuckets)
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "TPI Stream Invalid number of hash buckets.");

  // The actual type records themselves come from this stream
  if (auto EC = Reader.readArray(TypeRecords, Header->TypeRecordBytes))
    return EC;

  // Hash indices, hash values, etc come from the hash stream.
  if (Header->HashStreamIndex >= Pdb.getNumStreams())
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Invalid TPI hash stream index.");

  auto HS =
      MappedBlockStream::createIndexedStream(Header->HashStreamIndex, Pdb);
  if (!HS)
    return HS.takeError();
  StreamReader HSR(**HS);

  uint32_t NumHashValues = Header->HashValueBuffer.Length / sizeof(ulittle32_t);
  if (NumHashValues != NumTypeRecords())
    return make_error<RawError>(
        raw_error_code::corrupt_file,
        "TPI hash count does not match with the number of type records.");
  HSR.setOffset(Header->HashValueBuffer.Off);
  if (auto EC = HSR.readArray(HashValues, NumHashValues))
    return EC;

  HSR.setOffset(Header->IndexOffsetBuffer.Off);
  uint32_t NumTypeIndexOffsets =
      Header->IndexOffsetBuffer.Length / sizeof(TypeIndexOffset);
  if (auto EC = HSR.readArray(TypeIndexOffsets, NumTypeIndexOffsets))
    return EC;

  HSR.setOffset(Header->HashAdjBuffer.Off);
  uint32_t NumHashAdjustments =
      Header->HashAdjBuffer.Length / sizeof(TypeIndexOffset);
  if (auto EC = HSR.readArray(HashAdjustments, NumHashAdjustments))
    return EC;

  HashStream = std::move(*HS);

  // TPI hash table is a parallel array for the type records.
  // Verify that the hash values match with type records.
  if (auto EC = verifyHashValues())
    return EC;

  return Error::success();
}

PdbRaw_TpiVer TpiStream::getTpiVersion() const {
  uint32_t Value = Header->Version;
  return static_cast<PdbRaw_TpiVer>(Value);
}

uint32_t TpiStream::TypeIndexBegin() const { return Header->TypeIndexBegin; }

uint32_t TpiStream::TypeIndexEnd() const { return Header->TypeIndexEnd; }

uint32_t TpiStream::NumTypeRecords() const {
  return TypeIndexEnd() - TypeIndexBegin();
}

uint16_t TpiStream::getTypeHashStreamIndex() const {
  return Header->HashStreamIndex;
}

uint16_t TpiStream::getTypeHashStreamAuxIndex() const {
  return Header->HashAuxStreamIndex;
}

uint32_t TpiStream::NumHashBuckets() const { return Header->NumHashBuckets; }
uint32_t TpiStream::getHashKeySize() const { return Header->HashKeySize; }

FixedStreamArray<support::ulittle32_t>
TpiStream::getHashValues() const {
  return HashValues;
}

FixedStreamArray<TypeIndexOffset>
TpiStream::getTypeIndexOffsets() const {
  return TypeIndexOffsets;
}

FixedStreamArray<TypeIndexOffset>
TpiStream::getHashAdjustments() const {
  return HashAdjustments;
}

iterator_range<CVTypeArray::Iterator>
TpiStream::types(bool *HadError) const {
  return llvm::make_range(TypeRecords.begin(HadError), TypeRecords.end());
}
<commit_msg>[PDB] Indicate which type record failed hash validation<commit_after>//===- TpiStream.cpp - PDB Type Info (TPI) Stream 2 Access ----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "llvm/DebugInfo/PDB/Raw/TpiStream.h"

#include "llvm/DebugInfo/CodeView/CVTypeVisitor.h"
#include "llvm/DebugInfo/CodeView/CodeView.h"
#include "llvm/DebugInfo/CodeView/StreamReader.h"
#include "llvm/DebugInfo/CodeView/TypeIndex.h"
#include "llvm/DebugInfo/CodeView/TypeRecord.h"
#include "llvm/DebugInfo/PDB/Raw/Hash.h"
#include "llvm/DebugInfo/PDB/Raw/IndexedStreamData.h"
#include "llvm/DebugInfo/PDB/Raw/MappedBlockStream.h"
#include "llvm/DebugInfo/PDB/Raw/PDBFile.h"
#include "llvm/DebugInfo/PDB/Raw/RawConstants.h"
#include "llvm/DebugInfo/PDB/Raw/RawError.h"
#include "llvm/DebugInfo/PDB/Raw/RawTypes.h"

#include "llvm/Support/Endian.h"

using namespace llvm;
using namespace llvm::codeview;
using namespace llvm::support;
using namespace llvm::pdb;

namespace {
const uint32_t MinHashBuckets = 0x1000;
const uint32_t MaxHashBuckets = 0x40000;
}

// This corresponds to `HDR` in PDB/dbi/tpi.h.
struct TpiStream::HeaderInfo {
  struct EmbeddedBuf {
    little32_t Off;
    ulittle32_t Length;
  };

  ulittle32_t Version;
  ulittle32_t HeaderSize;
  ulittle32_t TypeIndexBegin;
  ulittle32_t TypeIndexEnd;
  ulittle32_t TypeRecordBytes;

  // The following members correspond to `TpiHash` in PDB/dbi/tpi.h.
  ulittle16_t HashStreamIndex;
  ulittle16_t HashAuxStreamIndex;
  ulittle32_t HashKeySize;
  ulittle32_t NumHashBuckets;

  EmbeddedBuf HashValueBuffer;
  EmbeddedBuf IndexOffsetBuffer;
  EmbeddedBuf HashAdjBuffer;
};

TpiStream::TpiStream(const PDBFile &File,
                     std::unique_ptr<MappedBlockStream> Stream)
    : Pdb(File), Stream(std::move(Stream)) {}

TpiStream::~TpiStream() {}

// Corresponds to `fUDTAnon`.
template <typename T> static bool isAnonymous(T &Rec) {
  StringRef Name = Rec.getUniqueName();
  return Name == "<unnamed-tag>" || Name == "__unnamed" ||
      Name.endswith("::<unnamed-tag>") || Name.endswith("::__unnamed");
}

// Computes a hash for a given TPI record.
template <typename T>
static uint32_t getTpiHash(T &Rec, const CVRecord<TypeLeafKind> &RawRec) {
  auto Opts = static_cast<uint16_t>(Rec.getOptions());

  bool ForwardRef =
      Opts & static_cast<uint16_t>(ClassOptions::ForwardReference);
  bool Scoped = Opts & static_cast<uint16_t>(ClassOptions::Scoped);
  bool UniqueName = Opts & static_cast<uint16_t>(ClassOptions::HasUniqueName);
  bool IsAnon = UniqueName && isAnonymous(Rec);

  if (!ForwardRef && !Scoped && !IsAnon)
    return hashStringV1(Rec.getName());
  if (!ForwardRef && UniqueName && !IsAnon)
    return hashStringV1(Rec.getUniqueName());
  return hashBufferV8(RawRec.RawData);
}

namespace {
class TpiHashVerifier : public TypeVisitorCallbacks {
public:
  TpiHashVerifier(FixedStreamArray<support::ulittle32_t> &HashValues,
                  uint32_t NumHashBuckets)
      : HashValues(HashValues), NumHashBuckets(NumHashBuckets) {}

  Error visitUdtSourceLine(UdtSourceLineRecord &Rec) override {
    return verifySourceLine(Rec);
  }

  Error visitUdtModSourceLine(UdtModSourceLineRecord &Rec) override {
    return verifySourceLine(Rec);
  }

  Error visitClass(ClassRecord &Rec) override { return verify(Rec); }
  Error visitEnum(EnumRecord &Rec) override { return verify(Rec); }
  Error visitUnion(UnionRecord &Rec) override { return verify(Rec); }

  Error visitTypeBegin(const CVRecord<TypeLeafKind> &Rec) override {
    ++Index;
    RawRecord = &Rec;
    return Error::success();
  }

private:
  template <typename T> Error verify(T &Rec) {
    uint32_t Hash = getTpiHash(Rec, *RawRecord);
    if (Hash % NumHashBuckets != HashValues[Index])
      return errorInvalidHash();
    return Error::success();
  }

  template <typename T> Error verifySourceLine(T &Rec) {
    char Buf[4];
    support::endian::write32le(Buf, Rec.getUDT().getIndex());
    uint32_t Hash = hashStringV1(StringRef(Buf, 4));
    if (Hash % NumHashBuckets != HashValues[Index])
      return errorInvalidHash();
    return Error::success();
  }

  Error errorInvalidHash() {
    return make_error<RawError>(
        raw_error_code::invalid_tpi_hash,
        "Type index is 0x" + utohexstr(TypeIndex::FirstNonSimpleIndex + Index));
  }

  FixedStreamArray<support::ulittle32_t> HashValues;
  const CVRecord<TypeLeafKind> *RawRecord;
  uint32_t NumHashBuckets;
  uint32_t Index = -1;
};
}

// Verifies that a given type record matches with a given hash value.
// Currently we only verify SRC_LINE records.
Error TpiStream::verifyHashValues() {
  TpiHashVerifier Verifier(HashValues, Header->NumHashBuckets);
  CVTypeVisitor Visitor(Verifier);
  return Visitor.visitTypeStream(TypeRecords);
}

Error TpiStream::reload() {
  StreamReader Reader(*Stream);

  if (Reader.bytesRemaining() < sizeof(HeaderInfo))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "TPI Stream does not contain a header.");

  if (Reader.readObject(Header))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "TPI Stream does not contain a header.");

  if (Header->Version != PdbTpiV80)
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Unsupported TPI Version.");

  if (Header->HeaderSize != sizeof(HeaderInfo))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Corrupt TPI Header size.");

  if (Header->HashKeySize != sizeof(ulittle32_t))
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "TPI Stream expected 4 byte hash key size.");

  if (Header->NumHashBuckets < MinHashBuckets ||
      Header->NumHashBuckets > MaxHashBuckets)
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "TPI Stream Invalid number of hash buckets.");

  // The actual type records themselves come from this stream
  if (auto EC = Reader.readArray(TypeRecords, Header->TypeRecordBytes))
    return EC;

  // Hash indices, hash values, etc come from the hash stream.
  if (Header->HashStreamIndex >= Pdb.getNumStreams())
    return make_error<RawError>(raw_error_code::corrupt_file,
                                "Invalid TPI hash stream index.");

  auto HS =
      MappedBlockStream::createIndexedStream(Header->HashStreamIndex, Pdb);
  if (!HS)
    return HS.takeError();
  StreamReader HSR(**HS);

  uint32_t NumHashValues = Header->HashValueBuffer.Length / sizeof(ulittle32_t);
  if (NumHashValues != NumTypeRecords())
    return make_error<RawError>(
        raw_error_code::corrupt_file,
        "TPI hash count does not match with the number of type records.");
  HSR.setOffset(Header->HashValueBuffer.Off);
  if (auto EC = HSR.readArray(HashValues, NumHashValues))
    return EC;

  HSR.setOffset(Header->IndexOffsetBuffer.Off);
  uint32_t NumTypeIndexOffsets =
      Header->IndexOffsetBuffer.Length / sizeof(TypeIndexOffset);
  if (auto EC = HSR.readArray(TypeIndexOffsets, NumTypeIndexOffsets))
    return EC;

  HSR.setOffset(Header->HashAdjBuffer.Off);
  uint32_t NumHashAdjustments =
      Header->HashAdjBuffer.Length / sizeof(TypeIndexOffset);
  if (auto EC = HSR.readArray(HashAdjustments, NumHashAdjustments))
    return EC;

  HashStream = std::move(*HS);

  // TPI hash table is a parallel array for the type records.
  // Verify that the hash values match with type records.
  if (auto EC = verifyHashValues())
    return EC;

  return Error::success();
}

PdbRaw_TpiVer TpiStream::getTpiVersion() const {
  uint32_t Value = Header->Version;
  return static_cast<PdbRaw_TpiVer>(Value);
}

uint32_t TpiStream::TypeIndexBegin() const { return Header->TypeIndexBegin; }

uint32_t TpiStream::TypeIndexEnd() const { return Header->TypeIndexEnd; }

uint32_t TpiStream::NumTypeRecords() const {
  return TypeIndexEnd() - TypeIndexBegin();
}

uint16_t TpiStream::getTypeHashStreamIndex() const {
  return Header->HashStreamIndex;
}

uint16_t TpiStream::getTypeHashStreamAuxIndex() const {
  return Header->HashAuxStreamIndex;
}

uint32_t TpiStream::NumHashBuckets() const { return Header->NumHashBuckets; }
uint32_t TpiStream::getHashKeySize() const { return Header->HashKeySize; }

FixedStreamArray<support::ulittle32_t>
TpiStream::getHashValues() const {
  return HashValues;
}

FixedStreamArray<TypeIndexOffset>
TpiStream::getTypeIndexOffsets() const {
  return TypeIndexOffsets;
}

FixedStreamArray<TypeIndexOffset>
TpiStream::getHashAdjustments() const {
  return HashAdjustments;
}

iterator_range<CVTypeArray::Iterator>
TpiStream::types(bool *HadError) const {
  return llvm::make_range(TypeRecords.begin(HadError), TypeRecords.end());
}
<|endoftext|>


<commit_before>/* $Id$ */
/* Author: Toby Young, Polish Academy of Sciences,                */
/*         Wolfgang Bangerth, Texas A&M University                */
/*    $Id$        */
/*                                                                */
/*    Copyright (C) 2009 by the deal.II authors */
/*                                                                */
/*    This file is subject to QPL and may not be  distributed     */
/*    without copyright and license information. Please refer     */
/*    to the file deal.II/doc/license.html for the  text  and     */
/*    further information on this license.                        */

                                 // @sect3{Include files}

#include <base/logstream.h>
#include <base/quadrature_lib.h>
#include <base/function.h>
#include <base/function_parser.h>
#include <base/parameter_handler.h>
#include <base/utilities.h>
#include <lac/full_matrix.h>
#include <lac/petsc_sparse_matrix.h>
#include <lac/petsc_vector.h>
#include <lac/solver_cg.h>
#include <lac/precondition.h>
#include <lac/compressed_simple_sparsity_pattern.h>
#include <grid/tria.h>
#include <grid/grid_generator.h>
#include <grid/tria_accessor.h>
#include <grid/tria_iterator.h>
#include <dofs/dof_handler.h>
#include <dofs/dof_accessor.h>
#include <dofs/dof_tools.h>
#include <fe/fe_q.h>
#include <fe/fe_values.h>
#include <numerics/vectors.h>
#include <numerics/matrices.h>
#include <numerics/data_out.h>

#include <fstream>
#include <iostream>

				 // The final step, as in previous
				 // programs, is to import all the
				 // deal.II class and function names
				 // into the global namespace:
using namespace dealii;

                                 // @sect3{The EigenvalueProblem class template}

template <int dim>
class EigenvalueProblem
{
  public:
    EigenvalueProblem ();
    void run ();

  private:
    void make_grid_and_dofs ();
    void assemble_system ();
    void solve ();
    void output_results () const;

    Triangulation<dim>   triangulation;
    FE_Q<dim>            fe;
    DoFHandler<dim>      dof_handler;

    PETScWrappers::SparseMatrix        stiffness_matrix, mass_matrix;
    std::vector<PETScWrappers::Vector> eigenfunctions;

    ParameterHandler parameters;
};

                                 // @sect3{Implementation of the EigenvalueProblem class}

                                 // @sect4{EigenvalueProblem::EigenvalueProblem}

template <int dim>
EigenvalueProblem<dim>::EigenvalueProblem ()
		:
                fe (1),
		dof_handler (triangulation)
{
  parameters.declare_entry ("Number of eigenvalues/eigenfunctions", "10",
			    Patterns::Integer (0, 100),
			    "The number of eigenvalues/eigenfunctions "
			    "to be computed.");
  parameters.declare_entry ("Potential", "0",
			    Patterns::Anything(),
			    "A functional description of the potential.");
}

                                 // @sect4{EigenvalueProblem::make_grid_and_dofs}
template <int dim>
void EigenvalueProblem<dim>::make_grid_and_dofs ()
{
  GridGenerator::hyper_cube (triangulation, -1, 1);
  triangulation.refine_global (4);
  dof_handler.distribute_dofs (fe);

  CompressedSimpleSparsityPattern csp (dof_handler.n_dofs(),
				       dof_handler.n_dofs());
  DoFTools::make_sparsity_pattern (dof_handler, csp);
  stiffness_matrix.reinit (csp);
  mass_matrix.reinit (csp);

  eigenfunctions
    .resize (parameters.get_integer ("Number of eigenvalues/eigenfunctions"));
  for (unsigned int i=0; i<eigenfunctions.size(); ++i)
    eigenfunctions[i].reinit (dof_handler.n_dofs());
}

                                 // @sect4{EigenvalueProblem::assemble_system}
template <int dim>
void EigenvalueProblem<dim>::assemble_system ()
{
  QGauss<dim>  quadrature_formula(2);

  FEValues<dim> fe_values (fe, quadrature_formula,
			   update_values   | update_gradients |
                           update_JxW_values);

  const unsigned int dofs_per_cell = fe.dofs_per_cell;
  const unsigned int n_q_points    = quadrature_formula.size();

  FullMatrix<double> cell_stiffness_matrix (dofs_per_cell, dofs_per_cell);
  FullMatrix<double> cell_mass_matrix (dofs_per_cell, dofs_per_cell);

  std::vector<unsigned int> local_dof_indices (dofs_per_cell);

  FunctionParser<dim> potential;
  potential.initialize ((dim == 2 ?
			 "x,y" :
			 "x,y,z"),
			parameters.get ("Potential"),
			typename FunctionParser<dim>::ConstMap());

  ConstraintMatrix constraints;
  VectorTools::interpolate_boundary_values (dof_handler,
					    0,
					    ZeroFunction<dim>(),
					    constraints);
  constraints.close ();

  typename DoFHandler<dim>::active_cell_iterator
    cell = dof_handler.begin_active(),
    endc = dof_handler.end();
  for (; cell!=endc; ++cell)
    {
      fe_values.reinit (cell);
      cell_stiffness_matrix = 0;
      cell_mass_matrix = 0;

      for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
	for (unsigned int i=0; i<dofs_per_cell; ++i)
	  for (unsigned int j=0; j<dofs_per_cell; ++j)
	    {
	      cell_stiffness_matrix(i,j)
		+= (fe_values.shape_grad (i, q_point) *
		    fe_values.shape_grad (j, q_point) *
		    fe_values.JxW (q_point));
	      cell_mass_matrix(i,j)
		+= (fe_values.shape_value (i, q_point) *
		    fe_values.shape_value (j, q_point) *
		    fe_values.JxW (q_point));
	    }

      cell->get_dof_indices (local_dof_indices);

      constraints.distribute_local_to_global (cell_stiffness_matrix,
					      local_dof_indices,
					      stiffness_matrix);
      constraints.distribute_local_to_global (cell_mass_matrix,
					      local_dof_indices,
					      mass_matrix);
    }
}

                                 // @sect4{EigenvalueProblem::solve}
template <int dim>
void EigenvalueProblem<dim>::solve ()
{
// do whatever is necessary here
}

                                 // @sect4{EigenvalueProblem::output_results}

template <int dim>
void EigenvalueProblem<dim>::output_results () const
{
  DataOut<dim> data_out;

  data_out.attach_dof_handler (dof_handler);

  for (unsigned int i=0; i<eigenfunctions.size(); ++i)
    data_out.add_data_vector (eigenfunctions[i],
			      std::string("solution") +
			      Utilities::int_to_string(i));

  data_out.build_patches ();

  std::ofstream output ("eigenvectors.vtk");
  data_out.write_vtk (output);
}

                                 // @sect4{EigenvalueProblem::run}

                                 // This is the function which has the
				 // top-level control over everything. It is
				 // the same as for the previous example.
template <int dim>
void EigenvalueProblem<dim>::run ()
{
  std::cout << "Solving problem in " << dim << " space dimensions." << std::endl;

  make_grid_and_dofs();
  assemble_system ();
  solve ();
  output_results ();
}

                                 // @sect3{The main function}

int main (int argc, char **argv)
{
  try
    {
      PetscInitialize(&argc,&argv,0,0);
      deallog.depth_console (0);

      EigenvalueProblem<2> laplace_problem_2d;
      laplace_problem_2d.run ();
    }
  catch (std::exception &exc)
    {
      std::cerr << std::endl << std::endl
		<< "----------------------------------------------------"
		<< std::endl;
      std::cerr << "Exception on processing: " << std::endl
		<< exc.what() << std::endl
		<< "Aborting!" << std::endl
		<< "----------------------------------------------------"
		<< std::endl;

      return 1;
    }
  catch (...)
    {
      std::cerr << std::endl << std::endl
		<< "----------------------------------------------------"
		<< std::endl;
      std::cerr << "Unknown exception!" << std::endl
		<< "Aborting!" << std::endl
		<< "----------------------------------------------------"
		<< std::endl;
      return 1;
    }

  return 0;
}
<commit_msg>Deal with the potential. Read parameters from file.<commit_after>/* $Id$ */
/* Author: Toby Young, Polish Academy of Sciences,                */
/*         Wolfgang Bangerth, Texas A&M University                */
/*    $Id$        */
/*                                                                */
/*    Copyright (C) 2009 by the deal.II authors */
/*                                                                */
/*    This file is subject to QPL and may not be  distributed     */
/*    without copyright and license information. Please refer     */
/*    to the file deal.II/doc/license.html for the  text  and     */
/*    further information on this license.                        */

                                 // @sect3{Include files}

#include <base/logstream.h>
#include <base/quadrature_lib.h>
#include <base/function.h>
#include <base/function_parser.h>
#include <base/parameter_handler.h>
#include <base/utilities.h>
#include <lac/full_matrix.h>
#include <lac/petsc_sparse_matrix.h>
#include <lac/petsc_vector.h>
#include <lac/solver_cg.h>
#include <lac/precondition.h>
#include <lac/compressed_simple_sparsity_pattern.h>
#include <grid/tria.h>
#include <grid/grid_generator.h>
#include <grid/tria_accessor.h>
#include <grid/tria_iterator.h>
#include <dofs/dof_handler.h>
#include <dofs/dof_accessor.h>
#include <dofs/dof_tools.h>
#include <fe/fe_q.h>
#include <fe/fe_values.h>
#include <numerics/vectors.h>
#include <numerics/matrices.h>
#include <numerics/data_out.h>

#include <fstream>
#include <iostream>

				 // The final step, as in previous
				 // programs, is to import all the
				 // deal.II class and function names
				 // into the global namespace:
using namespace dealii;

                                 // @sect3{The EigenvalueProblem class template}

template <int dim>
class EigenvalueProblem
{
  public:
    EigenvalueProblem (const std::string &prm_file);
    void run ();

  private:
    void make_grid_and_dofs ();
    void assemble_system ();
    void solve ();
    void output_results () const;

    Triangulation<dim>   triangulation;
    FE_Q<dim>            fe;
    DoFHandler<dim>      dof_handler;

    PETScWrappers::SparseMatrix        stiffness_matrix, mass_matrix;
    std::vector<PETScWrappers::Vector> eigenfunctions;

    ParameterHandler parameters;
};

                                 // @sect3{Implementation of the EigenvalueProblem class}

                                 // @sect4{EigenvalueProblem::EigenvalueProblem}

template <int dim>
EigenvalueProblem<dim>::EigenvalueProblem (const std::string &prm_file)
		:
                fe (1),
		dof_handler (triangulation)
{
  parameters.declare_entry ("Number of eigenvalues/eigenfunctions", "10",
			    Patterns::Integer (0, 100),
			    "The number of eigenvalues/eigenfunctions "
			    "to be computed.");
  parameters.declare_entry ("Potential", "0",
			    Patterns::Anything(),
			    "A functional description of the potential.");

  parameters.read_input (prm_file);
}

                                 // @sect4{EigenvalueProblem::make_grid_and_dofs}
template <int dim>
void EigenvalueProblem<dim>::make_grid_and_dofs ()
{
  GridGenerator::hyper_cube (triangulation, -1, 1);
  triangulation.refine_global (4);
  dof_handler.distribute_dofs (fe);

  CompressedSimpleSparsityPattern csp (dof_handler.n_dofs(),
				       dof_handler.n_dofs());
  DoFTools::make_sparsity_pattern (dof_handler, csp);
  stiffness_matrix.reinit (csp);
  mass_matrix.reinit (csp);

  eigenfunctions
    .resize (parameters.get_integer ("Number of eigenvalues/eigenfunctions"));
  for (unsigned int i=0; i<eigenfunctions.size(); ++i)
    eigenfunctions[i].reinit (dof_handler.n_dofs());
}

                                 // @sect4{EigenvalueProblem::assemble_system}
template <int dim>
void EigenvalueProblem<dim>::assemble_system ()
{
  QGauss<dim>  quadrature_formula(2);

  FEValues<dim> fe_values (fe, quadrature_formula,
			   update_values   | update_gradients |
                           update_quadrature_points | update_JxW_values);

  const unsigned int dofs_per_cell = fe.dofs_per_cell;
  const unsigned int n_q_points    = quadrature_formula.size();

  FullMatrix<double> cell_stiffness_matrix (dofs_per_cell, dofs_per_cell);
  FullMatrix<double> cell_mass_matrix (dofs_per_cell, dofs_per_cell);

  std::vector<unsigned int> local_dof_indices (dofs_per_cell);

  FunctionParser<dim> potential;
  potential.initialize ((dim == 2 ?
			 "x,y" :
			 "x,y,z"),
			parameters.get ("Potential"),
			typename FunctionParser<dim>::ConstMap());
  std::vector<double> potential_values (n_q_points);

  ConstraintMatrix constraints;
  VectorTools::interpolate_boundary_values (dof_handler,
					    0,
					    ZeroFunction<dim>(),
					    constraints);
  constraints.close ();

  typename DoFHandler<dim>::active_cell_iterator
    cell = dof_handler.begin_active(),
    endc = dof_handler.end();
  for (; cell!=endc; ++cell)
    {
      fe_values.reinit (cell);
      cell_stiffness_matrix = 0;
      cell_mass_matrix = 0;

      potential.value_list (fe_values.get_quadrature_points(),
			    potential_values);

      for (unsigned int q_point=0; q_point<n_q_points; ++q_point)
	for (unsigned int i=0; i<dofs_per_cell; ++i)
	  for (unsigned int j=0; j<dofs_per_cell; ++j)
	    {
	      cell_stiffness_matrix(i,j)
		+= ((fe_values.shape_grad (i, q_point) *
		     fe_values.shape_grad (j, q_point)
		     +
		     potential_values[q_point] *
		     fe_values.shape_value (i, q_point) *
		     fe_values.shape_value (j, q_point)) *
		    fe_values.JxW (q_point));
	      cell_mass_matrix(i,j)
		+= (fe_values.shape_value (i, q_point) *
		    fe_values.shape_value (j, q_point) *
		    fe_values.JxW (q_point));
	    }

      cell->get_dof_indices (local_dof_indices);

      constraints.distribute_local_to_global (cell_stiffness_matrix,
					      local_dof_indices,
					      stiffness_matrix);
      constraints.distribute_local_to_global (cell_mass_matrix,
					      local_dof_indices,
					      mass_matrix);
    }
}

                                 // @sect4{EigenvalueProblem::solve}
template <int dim>
void EigenvalueProblem<dim>::solve ()
{
// do whatever is necessary here
}

                                 // @sect4{EigenvalueProblem::output_results}

template <int dim>
void EigenvalueProblem<dim>::output_results () const
{
  DataOut<dim> data_out;

  data_out.attach_dof_handler (dof_handler);

  for (unsigned int i=0; i<eigenfunctions.size(); ++i)
    data_out.add_data_vector (eigenfunctions[i],
			      std::string("solution") +
			      Utilities::int_to_string(i));

  data_out.build_patches ();

  std::ofstream output ("eigenvectors.vtk");
  data_out.write_vtk (output);
}

                                 // @sect4{EigenvalueProblem::run}

                                 // This is the function which has the
				 // top-level control over everything. It is
				 // the same as for the previous example.
template <int dim>
void EigenvalueProblem<dim>::run ()
{
  std::cout << "Solving problem in " << dim << " space dimensions." << std::endl;

  make_grid_and_dofs();
  assemble_system ();
  solve ();
  output_results ();
}

                                 // @sect3{The main function}

int main (int argc, char **argv)
{
  try
    {
      PetscInitialize(&argc,&argv,0,0);
      deallog.depth_console (0);

      EigenvalueProblem<2> problem ("step-36.prm");
      problem.run ();
    }
  catch (std::exception &exc)
    {
      std::cerr << std::endl << std::endl
		<< "----------------------------------------------------"
		<< std::endl;
      std::cerr << "Exception on processing: " << std::endl
		<< exc.what() << std::endl
		<< "Aborting!" << std::endl
		<< "----------------------------------------------------"
		<< std::endl;

      return 1;
    }
  catch (...)
    {
      std::cerr << std::endl << std::endl
		<< "----------------------------------------------------"
		<< std::endl;
      std::cerr << "Unknown exception!" << std::endl
		<< "Aborting!" << std::endl
		<< "----------------------------------------------------"
		<< std::endl;
      return 1;
    }

  return 0;
}
<|endoftext|>


<commit_before>#include <FAST/Testing.hpp>
#include <FAST/Algorithms/NeuralNetwork/SegmentationNetwork.hpp>
#include <FAST/Importers/ImageFileImporter.hpp>
#include <FAST/Visualization/SimpleWindow.hpp>
#include <FAST/Streamers/ImageFileStreamer.hpp>
#include <FAST/Algorithms/NeuralNetwork/InferenceEngineManager.hpp>
#include <fstream>
#include <FAST/Algorithms/ImagePatch/PatchGenerator.hpp>
#include <FAST/Algorithms/ImagePatch/PatchStitcher.hpp>
#include <FAST/Importers/WholeSlideImageImporter.hpp>
#include <FAST/Algorithms/TissueSegmentation/TissueSegmentation.hpp>
#include <FAST/Tools/CommandLineParser.hpp>

using namespace fast;

int main(int argc, char** argv) {
    Reporter::setGlobalReportMethod(Reporter::INFO, Reporter::NONE);

    CommandLineParser parser("Measure neural network performance script");
    parser.addOption("disable-case-1");
    parser.addOption("disable-case-2");
    parser.addOption("disable-case-3");
    parser.addOption("disable-warmup");
    parser.parse(argc, argv);
    const int iterations = 10;
    const bool warmupIteration = !parser.getOption("disable-warmup");
    const bool case1 = !parser.getOption("disable-case-1");
    const bool case2 = !parser.getOption("disable-case-2");
    const bool case3 = !parser.getOption("disable-case-3");

    if(case1) {
        // CASE 1 - ULTRASOUND
        const std::string resultFilename = "neural-network-runtimes-case-1.csv";
        std::ofstream file(resultFilename.c_str());

        // Write header
        file << "Engine;Device Type;Iteration;NN input AVG;NN input STD;NN inference AVG;NN inference STD;NN output AVG;NN output STD;Total\n";

        for(auto &engine : InferenceEngineManager::getEngineList()) {
            std::map<std::string, InferenceDeviceType> deviceTypes = {{"ANY", InferenceDeviceType::ANY}};
            if(engine == "OpenVINO") {
                // On OpenVINO, try all device types
                deviceTypes = std::map<std::string, InferenceDeviceType>{
                        {"CPU", InferenceDeviceType::CPU},
                        {"GPU", InferenceDeviceType::GPU},
                        {"VPU", InferenceDeviceType::VPU},
                };
            }
            for(auto &&deviceType : deviceTypes) {
                std::cout << engine << " for device type " << deviceType.first << std::endl;
                std::cout << "====================================" << std::endl;

                for(int iteration = 0; iteration <= iterations; ++iteration) {
                    auto streamer = ImageFileStreamer::New();
                    streamer->setFilenameFormat(Config::getTestDataPath() + "US/JugularVein/US-2D_#.mhd");

                    auto segmentation = SegmentationNetwork::New();
                    segmentation->setInferenceEngine(engine);
                    segmentation->getInferenceEngine()->setDeviceType(deviceType.second);
                    if(engine.substr(0, 10) == "TensorFlow") {
                        segmentation->setOutputNode(0, "conv2d_23/truediv");
                    } else if(engine == "TensorRT") {
                        segmentation->setInputNode(0, "input_image", NodeType::IMAGE, TensorShape({-1, 1, 256, 256}));
                        segmentation->setOutputNode(0, "permute_2/transpose", NodeType::TENSOR,
                                                    TensorShape({-1, 3, 256, 256}));
                    }
                    try {
                        segmentation->load(join(Config::getTestDataPath(),
                                                "NeuralNetworkModels/jugular_vein_segmentation." +
                                                segmentation->getInferenceEngine()->getDefaultFileExtension()));
                    } catch(Exception &e) {
                        // If a device type is not present, it will fail in load
                        Reporter::warning() << e.what() << Reporter::end();
                        continue;
                    }
                    segmentation->setScaleFactor(1.0f / 255.0f);
                    //segmentation->setInputConnection(importer->getOutputPort());
                    segmentation->setInputConnection(streamer->getOutputPort());
                    segmentation->enableRuntimeMeasurements();

                    auto start = std::chrono::high_resolution_clock::now();
                    DataObject::pointer data;
                    do {
                        data = segmentation->updateAndGetOutputData<DataObject>();
                    } while(!data->isLastFrame());
                    std::chrono::duration<float, std::milli> timeUsed =
                            std::chrono::high_resolution_clock::now() - start;
                    std::cout << "RUNTIME Ultrasound " << engine << std::endl;
                    std::cout << "=========================================" << std::endl;
                    std::cout << "Total runtime: " << timeUsed.count() << std::endl;
                    std::cout << "NN runtime: " << std::endl;
                    segmentation->getRuntime("input_processing")->print();
                    segmentation->getRuntime("inference")->print();
                    segmentation->getRuntime("output_processing")->print();

                    if(iteration == 0 && warmupIteration)
                        continue;

                    file <<
                         engine + ";" +
                         deviceType.first + ";" +
                         std::to_string(iteration) + ";" +
                         std::to_string(segmentation->getRuntime("input_processing")->getAverage()) + ";" +
                         std::to_string(segmentation->getRuntime("input_processing")->getStdDeviation()) + ";" +
                         std::to_string(segmentation->getRuntime("inference")->getAverage()) + ";" +
                         std::to_string(segmentation->getRuntime("inference")->getStdDeviation()) + ";" +
                         std::to_string(segmentation->getRuntime("output_processing")->getAverage()) + ";" +
                         std::to_string(segmentation->getRuntime("output_processing")->getStdDeviation()) + ";" +
                         std::to_string(timeUsed.count())
                         << std::endl;
                }
            }
        }
    }

    if(case2) {
        // CASE 2 - VOLUME SEGMENTATION
        const std::string resultFilename = "neural-network-runtimes-case-2.csv";
        std::ofstream file(resultFilename.c_str());

        // Write header
        file << "Engine;Device Type;Iteration;Patch generator AVG;Patch generator STD;NN input AVG;NN input STD;NN inference AVG;NN inference STD;NN output AVG;NN output STD;Patch stitcher AVG;Patch stitcher STD;Total\n";

        //Reporter::setGlobalReportMethod(Reporter::NONE);
        for(std::string engine : {"TensorFlowCUDA", "TensorFlowCPU"}) {
            std::map<std::string, InferenceDeviceType> deviceTypes = {{"ANY", InferenceDeviceType::ANY}};
            if(engine == "OpenVINO") {
                // On OpenVINO, try all device types
                deviceTypes = std::map<std::string, InferenceDeviceType>{
                        {"CPU", InferenceDeviceType::CPU},
                        {"GPU", InferenceDeviceType::GPU},
                        {"VPU", InferenceDeviceType::VPU},
                };
            }
            for(auto &&deviceType : deviceTypes) {
                std::cout << engine << " for device type " << deviceType.first << std::endl;
                std::cout << "====================================" << std::endl;

                for(int iteration = 0; iteration <= iterations; ++iteration) {
                   auto importer = ImageFileImporter::New();
                    importer->setFilename(Config::getTestDataPath() + "/CT/LIDC-IDRI-0072/01-01-2000-CT CHEST W CONT-45499/4-Recon 3-88650/000001.dcm");

                    auto generator = PatchGenerator::New();
                    generator->setPatchSize(512, 512, 64);
                    generator->setInputConnection(importer->getOutputPort());
                    generator->enableRuntimeMeasurements();

                    auto network = SegmentationNetwork::New();
                    network->setInferenceEngine(engine);
                    network->getInferenceEngine()->setDeviceType(deviceType.second);
                    network->setInferenceEngine(engine);
                    network->load(Config::getTestDataPath() + "/NeuralNetworkModels/lung_nodule_model.pb");
                    network->setMinAndMaxIntensity(-1200.0f, 400.0f);
                    network->setScaleFactor(1.0f/(400+1200));
                    network->setMeanAndStandardDeviation(-1200.0f, 1.0f);
                    network->setOutputNode(0, "conv3d_18/truediv");
                    network->setInputConnection(generator->getOutputPort());
                    network->setResizeBackToOriginalSize(true);
                    network->setThreshold(0.3);
                    network->enableRuntimeMeasurements();

                    auto stitcher = PatchStitcher::New();
                    stitcher->setInputConnection(network->getOutputPort());
                    stitcher->enableRuntimeMeasurements();

                    auto start = std::chrono::high_resolution_clock::now();
                    DataObject::pointer data;
                    do {
                        data = stitcher->updateAndGetOutputData<DataObject>();
                    } while(!data->isLastFrame());
                    std::chrono::duration<float, std::milli> timeUsed = std::chrono::high_resolution_clock::now() - start;
                    std::cout << "Total runtime: " << timeUsed.count() << std::endl;
                    std::cout << "Patch generator runtime: " << std::endl;
                    generator->getRuntime("create patch")->print();
                    std::cout << "NN runtime: " << std::endl;
                    network->getRuntime()->print();
                    std::cout << "Patch stitcher runtime: " << std::endl;
                    stitcher->getRuntime()->print();

                    if(iteration == 0 && warmupIteration)
                        continue;

                    file <<
                         engine + ";" +
                         deviceType.first + ";" +
                         std::to_string(iteration) + ";" +
                         std::to_string(generator->getRuntime("create patch")->getAverage()) + ";" +
                         std::to_string(generator->getRuntime("create patch")->getStdDeviation()) + ";" +
                         std::to_string(network->getRuntime("input_processing")->getAverage()) + ";" +
                         std::to_string(network->getRuntime("input_processing")->getStdDeviation()) + ";" +
                         std::to_string(network->getRuntime("inference")->getAverage()) + ";" +
                         std::to_string(network->getRuntime("inference")->getStdDeviation()) + ";" +
                         std::to_string(network->getRuntime("output_processing")->getAverage()) + ";" +
                         std::to_string(network->getRuntime("output_processing")->getStdDeviation()) + ";" +
                         std::to_string(stitcher->getRuntime()->getAverage()) + ";" +
                         std::to_string(stitcher->getRuntime()->getStdDeviation()) + ";" +
                         std::to_string(timeUsed.count())
                         << std::endl;
                }
            }
        }
    }

    if(case3) {
        // CASE 3 - WSI CLASSIFICATION
        const std::string resultFilename = "neural-network-runtimes-case-3.csv";
        std::ofstream file(resultFilename.c_str());

        // Write header
        file << "Engine;Device Type;Iteration;Patch generator AVG;Patch generator STD;NN input AVG;NN input STD;NN inference AVG;NN inference STD;NN output AVG;NN output STD;Patch stitcher AVG;Patch stitcher STD;Total\n";

        for(auto &engine : InferenceEngineManager::getEngineList()) {
            std::map<std::string, InferenceDeviceType> deviceTypes = {{"ANY", InferenceDeviceType::ANY}};
            if(engine == "OpenVINO") {
                // On OpenVINO, try all device types
                deviceTypes = std::map<std::string, InferenceDeviceType>{
                        {"CPU", InferenceDeviceType::CPU},
                        {"GPU", InferenceDeviceType::GPU},
                        {"VPU", InferenceDeviceType::VPU},
                };
            }
            for(auto &&deviceType : deviceTypes) {
                std::cout << engine << " for device type " << deviceType.first << std::endl;
                std::cout << "====================================" << std::endl;

                for(int iteration = 0; iteration <= iterations; ++iteration) {
                    auto importer = WholeSlideImageImporter::New();
                    importer->setFilename(Config::getTestDataPath() + "/CMU-1.tiff");

                    auto tissueSegmentation = TissueSegmentation::New();
                    tissueSegmentation->setInputConnection(importer->getOutputPort());

                    auto generator = PatchGenerator::New();
                    generator->setPatchSize(512, 512);
                    generator->setPatchLevel(0);
                    generator->setInputConnection(importer->getOutputPort());
                    generator->setInputConnection(1, tissueSegmentation->getOutputPort());
                    generator->enableRuntimeMeasurements();

                    auto network = NeuralNetwork::New();
                    network->setInferenceEngine(engine);
                    std::string postfix;
                    if(engine.substr(0, 10) == "TensorFlow") {
                        network->setOutputNode(0, "dense_1/Softmax", NodeType::TENSOR);
                    } else if(engine == "TensorRT") {
                        network->setInputNode(0, "input_1", NodeType::IMAGE, TensorShape{-1, 3, 512, 512});
                        network->setOutputNode(0, "dense_1/Softmax", NodeType::TENSOR, TensorShape{-1, 3});
                    } else if(engine == "OpenVINO") {
                        network->getInferenceEngine()->setDeviceType(deviceType.second);
                        if(deviceType.first == "VPU") {
                            postfix = "_fp16";
                        }
                    }
                    network->load(Config::getTestDataPath() + "NeuralNetworkModels/bc_grade_model_3_grades_10x_512_heavy_HSV" + postfix + "." +
                                  network->getInferenceEngine()->getDefaultFileExtension());
                    network->setInputConnection(generator->getOutputPort());
                    network->setScaleFactor(1.0f / 255.0f);
                    network->enableRuntimeMeasurements();

                    auto stitcher = PatchStitcher::New();
                    stitcher->setInputConnection(network->getOutputPort());
                    stitcher->enableRuntimeMeasurements();

                    auto start = std::chrono::high_resolution_clock::now();
                    DataObject::pointer data;
                    do {
                        data = stitcher->updateAndGetOutputData<DataObject>();
                    } while(!data->isLastFrame());
                    std::chrono::duration<float, std::milli> timeUsed = std::chrono::high_resolution_clock::now() - start;
                    std::cout << "Total runtime: " << timeUsed.count() << std::endl;
                    std::cout << "Patch generator runtime: " << std::endl;
                    generator->getRuntime("create patch")->print();
                    std::cout << "NN runtime: " << std::endl;
                    network->getRuntime()->print();
                    std::cout << "Patch stitcher runtime: " << std::endl;
                    stitcher->getRuntime()->print();

                    if(iteration == 0 && warmupIteration)
                        continue;

                    file <<
                         engine + ";" +
                         deviceType.first + ";" +
                         std::to_string(iteration) + ";" +
                         std::to_string(generator->getRuntime("create patch")->getAverage()) + ";" +
                         std::to_string(generator->getRuntime("create patch")->getStdDeviation()) + ";" +
                         std::to_string(network->getRuntime("input_processing")->getAverage()) + ";" +
                         std::to_string(network->getRuntime("input_processing")->getStdDeviation()) + ";" +
                         std::to_string(network->getRuntime("inference")->getAverage()) + ";" +
                         std::to_string(network->getRuntime("inference")->getStdDeviation()) + ";" +
                         std::to_string(network->getRuntime("output_processing")->getAverage()) + ";" +
                         std::to_string(network->getRuntime("output_processing")->getStdDeviation()) + ";" +
                         std::to_string(stitcher->getRuntime()->getAverage()) + ";" +
                         std::to_string(stitcher->getRuntime()->getStdDeviation()) + ";" +
                         std::to_string(timeUsed.count())
                         << std::endl;
                }
            }
        }
    }
}
<commit_msg>fp 16 postfix for NN case 1<commit_after>#include <FAST/Testing.hpp>
#include <FAST/Algorithms/NeuralNetwork/SegmentationNetwork.hpp>
#include <FAST/Importers/ImageFileImporter.hpp>
#include <FAST/Visualization/SimpleWindow.hpp>
#include <FAST/Streamers/ImageFileStreamer.hpp>
#include <FAST/Algorithms/NeuralNetwork/InferenceEngineManager.hpp>
#include <fstream>
#include <FAST/Algorithms/ImagePatch/PatchGenerator.hpp>
#include <FAST/Algorithms/ImagePatch/PatchStitcher.hpp>
#include <FAST/Importers/WholeSlideImageImporter.hpp>
#include <FAST/Algorithms/TissueSegmentation/TissueSegmentation.hpp>
#include <FAST/Tools/CommandLineParser.hpp>

using namespace fast;

int main(int argc, char** argv) {
    Reporter::setGlobalReportMethod(Reporter::INFO, Reporter::NONE);

    CommandLineParser parser("Measure neural network performance script");
    parser.addOption("disable-case-1");
    parser.addOption("disable-case-2");
    parser.addOption("disable-case-3");
    parser.addOption("disable-warmup");
    parser.parse(argc, argv);
    const int iterations = 10;
    const bool warmupIteration = !parser.getOption("disable-warmup");
    const bool case1 = !parser.getOption("disable-case-1");
    const bool case2 = !parser.getOption("disable-case-2");
    const bool case3 = !parser.getOption("disable-case-3");

    if(case1) {
        // CASE 1 - ULTRASOUND
        const std::string resultFilename = "neural-network-runtimes-case-1.csv";
        std::ofstream file(resultFilename.c_str());

        // Write header
        file << "Engine;Device Type;Iteration;NN input AVG;NN input STD;NN inference AVG;NN inference STD;NN output AVG;NN output STD;Total\n";

        for(auto &engine : InferenceEngineManager::getEngineList()) {
            std::map<std::string, InferenceDeviceType> deviceTypes = {{"ANY", InferenceDeviceType::ANY}};
            if(engine == "OpenVINO") {
                // On OpenVINO, try all device types
                deviceTypes = std::map<std::string, InferenceDeviceType>{
                        {"CPU", InferenceDeviceType::CPU},
                        {"GPU", InferenceDeviceType::GPU},
                        {"VPU", InferenceDeviceType::VPU},
                };
            }
            for(auto &&deviceType : deviceTypes) {
                std::cout << engine << " for device type " << deviceType.first << std::endl;
                std::cout << "====================================" << std::endl;

                for(int iteration = 0; iteration <= iterations; ++iteration) {
                    auto streamer = ImageFileStreamer::New();
                    streamer->setFilenameFormat(Config::getTestDataPath() + "US/JugularVein/US-2D_#.mhd");

                    auto segmentation = SegmentationNetwork::New();
                    segmentation->setInferenceEngine(engine);
                    segmentation->getInferenceEngine()->setDeviceType(deviceType.second);
                    std::string postfix = "";
                    if(engine.substr(0, 10) == "TensorFlow") {
                        segmentation->setOutputNode(0, "conv2d_23/truediv");
                    } else if(engine == "TensorRT") {
                        segmentation->setInputNode(0, "input_image", NodeType::IMAGE, TensorShape({-1, 1, 256, 256}));
                        segmentation->setOutputNode(0, "permute_2/transpose", NodeType::TENSOR,
                                                    TensorShape({-1, 3, 256, 256}));
                    } else if(engine == "OpenVINO") {
                        if (deviceType.first == "VPU") {
                            postfix = "_fp16";
                        }
                    }

                    try {
                        segmentation->load(join(Config::getTestDataPath(),
                                                "NeuralNetworkModels/jugular_vein_segmentation"+postfix+"." +
                                                segmentation->getInferenceEngine()->getDefaultFileExtension()));
                    } catch(Exception &e) {
                        // If a device type is not present, it will fail in load
                        Reporter::warning() << e.what() << Reporter::end();
                        continue;
                    }
                    segmentation->setScaleFactor(1.0f / 255.0f);
                    //segmentation->setInputConnection(importer->getOutputPort());
                    segmentation->setInputConnection(streamer->getOutputPort());
                    segmentation->enableRuntimeMeasurements();

                    auto start = std::chrono::high_resolution_clock::now();
                    DataObject::pointer data;
                    do {
                        data = segmentation->updateAndGetOutputData<DataObject>();
                    } while(!data->isLastFrame());
                    std::chrono::duration<float, std::milli> timeUsed =
                            std::chrono::high_resolution_clock::now() - start;
                    std::cout << "RUNTIME Ultrasound " << engine << std::endl;
                    std::cout << "=========================================" << std::endl;
                    std::cout << "Total runtime: " << timeUsed.count() << std::endl;
                    std::cout << "NN runtime: " << std::endl;
                    segmentation->getRuntime("input_processing")->print();
                    segmentation->getRuntime("inference")->print();
                    segmentation->getRuntime("output_processing")->print();

                    if(iteration == 0 && warmupIteration)
                        continue;

                    file <<
                         engine + ";" +
                         deviceType.first + ";" +
                         std::to_string(iteration) + ";" +
                         std::to_string(segmentation->getRuntime("input_processing")->getAverage()) + ";" +
                         std::to_string(segmentation->getRuntime("input_processing")->getStdDeviation()) + ";" +
                         std::to_string(segmentation->getRuntime("inference")->getAverage()) + ";" +
                         std::to_string(segmentation->getRuntime("inference")->getStdDeviation()) + ";" +
                         std::to_string(segmentation->getRuntime("output_processing")->getAverage()) + ";" +
                         std::to_string(segmentation->getRuntime("output_processing")->getStdDeviation()) + ";" +
                         std::to_string(timeUsed.count())
                         << std::endl;
                }
            }
        }
    }

    if(case2) {
        // CASE 2 - VOLUME SEGMENTATION
        const std::string resultFilename = "neural-network-runtimes-case-2.csv";
        std::ofstream file(resultFilename.c_str());

        // Write header
        file << "Engine;Device Type;Iteration;Patch generator AVG;Patch generator STD;NN input AVG;NN input STD;NN inference AVG;NN inference STD;NN output AVG;NN output STD;Patch stitcher AVG;Patch stitcher STD;Total\n";

        //Reporter::setGlobalReportMethod(Reporter::NONE);
        for(std::string engine : {"TensorFlowCUDA", "TensorFlowCPU"}) {
            std::map<std::string, InferenceDeviceType> deviceTypes = {{"ANY", InferenceDeviceType::ANY}};
            if(engine == "OpenVINO") {
                // On OpenVINO, try all device types
                deviceTypes = std::map<std::string, InferenceDeviceType>{
                        {"CPU", InferenceDeviceType::CPU},
                        {"GPU", InferenceDeviceType::GPU},
                        {"VPU", InferenceDeviceType::VPU},
                };
            }
            for(auto &&deviceType : deviceTypes) {
                std::cout << engine << " for device type " << deviceType.first << std::endl;
                std::cout << "====================================" << std::endl;

                for(int iteration = 0; iteration <= iterations; ++iteration) {
                   auto importer = ImageFileImporter::New();
                    importer->setFilename(Config::getTestDataPath() + "/CT/LIDC-IDRI-0072/01-01-2000-CT CHEST W CONT-45499/4-Recon 3-88650/000001.dcm");

                    auto generator = PatchGenerator::New();
                    generator->setPatchSize(512, 512, 64);
                    generator->setInputConnection(importer->getOutputPort());
                    generator->enableRuntimeMeasurements();

                    auto network = SegmentationNetwork::New();
                    network->setInferenceEngine(engine);
                    network->getInferenceEngine()->setDeviceType(deviceType.second);
                    network->setInferenceEngine(engine);
                    network->load(Config::getTestDataPath() + "/NeuralNetworkModels/lung_nodule_model.pb");
                    network->setMinAndMaxIntensity(-1200.0f, 400.0f);
                    network->setScaleFactor(1.0f/(400+1200));
                    network->setMeanAndStandardDeviation(-1200.0f, 1.0f);
                    network->setOutputNode(0, "conv3d_18/truediv");
                    network->setInputConnection(generator->getOutputPort());
                    network->setResizeBackToOriginalSize(true);
                    network->setThreshold(0.3);
                    network->enableRuntimeMeasurements();

                    auto stitcher = PatchStitcher::New();
                    stitcher->setInputConnection(network->getOutputPort());
                    stitcher->enableRuntimeMeasurements();

                    auto start = std::chrono::high_resolution_clock::now();
                    DataObject::pointer data;
                    do {
                        data = stitcher->updateAndGetOutputData<DataObject>();
                    } while(!data->isLastFrame());
                    std::chrono::duration<float, std::milli> timeUsed = std::chrono::high_resolution_clock::now() - start;
                    std::cout << "Total runtime: " << timeUsed.count() << std::endl;
                    std::cout << "Patch generator runtime: " << std::endl;
                    generator->getRuntime("create patch")->print();
                    std::cout << "NN runtime: " << std::endl;
                    network->getRuntime()->print();
                    std::cout << "Patch stitcher runtime: " << std::endl;
                    stitcher->getRuntime()->print();

                    if(iteration == 0 && warmupIteration)
                        continue;

                    file <<
                         engine + ";" +
                         deviceType.first + ";" +
                         std::to_string(iteration) + ";" +
                         std::to_string(generator->getRuntime("create patch")->getAverage()) + ";" +
                         std::to_string(generator->getRuntime("create patch")->getStdDeviation()) + ";" +
                         std::to_string(network->getRuntime("input_processing")->getAverage()) + ";" +
                         std::to_string(network->getRuntime("input_processing")->getStdDeviation()) + ";" +
                         std::to_string(network->getRuntime("inference")->getAverage()) + ";" +
                         std::to_string(network->getRuntime("inference")->getStdDeviation()) + ";" +
                         std::to_string(network->getRuntime("output_processing")->getAverage()) + ";" +
                         std::to_string(network->getRuntime("output_processing")->getStdDeviation()) + ";" +
                         std::to_string(stitcher->getRuntime()->getAverage()) + ";" +
                         std::to_string(stitcher->getRuntime()->getStdDeviation()) + ";" +
                         std::to_string(timeUsed.count())
                         << std::endl;
                }
            }
        }
    }

    if(case3) {
        // CASE 3 - WSI CLASSIFICATION
        const std::string resultFilename = "neural-network-runtimes-case-3.csv";
        std::ofstream file(resultFilename.c_str());

        // Write header
        file << "Engine;Device Type;Iteration;Patch generator AVG;Patch generator STD;NN input AVG;NN input STD;NN inference AVG;NN inference STD;NN output AVG;NN output STD;Patch stitcher AVG;Patch stitcher STD;Total\n";

        for(auto &engine : InferenceEngineManager::getEngineList()) {
            std::map<std::string, InferenceDeviceType> deviceTypes = {{"ANY", InferenceDeviceType::ANY}};
            if(engine == "OpenVINO") {
                // On OpenVINO, try all device types
                deviceTypes = std::map<std::string, InferenceDeviceType>{
                        {"CPU", InferenceDeviceType::CPU},
                        {"GPU", InferenceDeviceType::GPU},
                        {"VPU", InferenceDeviceType::VPU},
                };
            }
            for(auto &&deviceType : deviceTypes) {
                std::cout << engine << " for device type " << deviceType.first << std::endl;
                std::cout << "====================================" << std::endl;

                for(int iteration = 0; iteration <= iterations; ++iteration) {
                    auto importer = WholeSlideImageImporter::New();
                    importer->setFilename(Config::getTestDataPath() + "/CMU-1.tiff");

                    auto tissueSegmentation = TissueSegmentation::New();
                    tissueSegmentation->setInputConnection(importer->getOutputPort());

                    auto generator = PatchGenerator::New();
                    generator->setPatchSize(512, 512);
                    generator->setPatchLevel(0);
                    generator->setInputConnection(importer->getOutputPort());
                    generator->setInputConnection(1, tissueSegmentation->getOutputPort());
                    generator->enableRuntimeMeasurements();

                    auto network = NeuralNetwork::New();
                    network->setInferenceEngine(engine);
                    std::string postfix;
                    if(engine.substr(0, 10) == "TensorFlow") {
                        network->setOutputNode(0, "dense_1/Softmax", NodeType::TENSOR);
                    } else if(engine == "TensorRT") {
                        network->setInputNode(0, "input_1", NodeType::IMAGE, TensorShape{-1, 3, 512, 512});
                        network->setOutputNode(0, "dense_1/Softmax", NodeType::TENSOR, TensorShape{-1, 3});
                    } else if(engine == "OpenVINO") {
                        network->getInferenceEngine()->setDeviceType(deviceType.second);
                        if(deviceType.first == "VPU") {
                            postfix = "_fp16";
                        }
                    }
                    network->load(Config::getTestDataPath() + "NeuralNetworkModels/bc_grade_model_3_grades_10x_512_heavy_HSV" + postfix + "." +
                                  network->getInferenceEngine()->getDefaultFileExtension());
                    network->setInputConnection(generator->getOutputPort());
                    network->setScaleFactor(1.0f / 255.0f);
                    network->enableRuntimeMeasurements();

                    auto stitcher = PatchStitcher::New();
                    stitcher->setInputConnection(network->getOutputPort());
                    stitcher->enableRuntimeMeasurements();

                    auto start = std::chrono::high_resolution_clock::now();
                    DataObject::pointer data;
                    do {
                        data = stitcher->updateAndGetOutputData<DataObject>();
                    } while(!data->isLastFrame());
                    std::chrono::duration<float, std::milli> timeUsed = std::chrono::high_resolution_clock::now() - start;
                    std::cout << "Total runtime: " << timeUsed.count() << std::endl;
                    std::cout << "Patch generator runtime: " << std::endl;
                    generator->getRuntime("create patch")->print();
                    std::cout << "NN runtime: " << std::endl;
                    network->getRuntime()->print();
                    std::cout << "Patch stitcher runtime: " << std::endl;
                    stitcher->getRuntime()->print();

                    if(iteration == 0 && warmupIteration)
                        continue;

                    file <<
                         engine + ";" +
                         deviceType.first + ";" +
                         std::to_string(iteration) + ";" +
                         std::to_string(generator->getRuntime("create patch")->getAverage()) + ";" +
                         std::to_string(generator->getRuntime("create patch")->getStdDeviation()) + ";" +
                         std::to_string(network->getRuntime("input_processing")->getAverage()) + ";" +
                         std::to_string(network->getRuntime("input_processing")->getStdDeviation()) + ";" +
                         std::to_string(network->getRuntime("inference")->getAverage()) + ";" +
                         std::to_string(network->getRuntime("inference")->getStdDeviation()) + ";" +
                         std::to_string(network->getRuntime("output_processing")->getAverage()) + ";" +
                         std::to_string(network->getRuntime("output_processing")->getStdDeviation()) + ";" +
                         std::to_string(stitcher->getRuntime()->getAverage()) + ";" +
                         std::to_string(stitcher->getRuntime()->getStdDeviation()) + ";" +
                         std::to_string(timeUsed.count())
                         << std::endl;
                }
            }
        }
    }
}
<|endoftext|>