<commit_before>
#pragma once

#include <data_model.hpp>

#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>
#include <map>
#include <sstream>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/copy.hpp>
#include <boost/property_map/property_map.hpp>

namespace verilog
{
  namespace bdd {

    enum class NegP {
      Positive, Negative
    };

    enum class Type {
      Zero, One, Input
    };

    struct Node {
      std::string input_name;
      Type t;
    };

    typedef boost::adjacency_list<
      boost::setS,
      boost::vecS,
      boost::bidirectionalS,
      Node, NegP> GD;

    typedef unsigned int hashcode;

    struct BDD {
      GD graph;

      /**
       * The node representing the sinks of the BDD
       */
      int zero,
          one,
          /**
           * The node representing the source of the bdd
           */
          source;

      std::map<hashcode, std::vector<int> > bdd_heap;

      BDD(const std::string name) {
        zero = boost::add_vertex(graph);
        one  = boost::add_vertex(graph);
        source = add_vertex(name);
        graph[zero].t = Type::Zero;
        graph[one].t  = Type::One;
      }

      /**
       * Creates a copy of a,
       * merges all nodes of b into the copy.
       * calls the conjunction_internal function for the copy.
       */
      BDD conjunction(const BDD & a, const BDD & b) {

        typedef std::map<GD::vertex_descriptor, GD::vertex_descriptor> node_map_t;
        node_map_t node_map;
        boost::associative_property_map<node_map_t> mapper(node_map);

        BDD c = a;
        copy_graph(b.graph, c.graph, boost::orig_to_copy(mapper));

        int old_zero = node_map[b.zero];
        int old_one  = node_map[b.one];

        // copies the old one edges into the new graph
        auto one_edges = in_edges(old_one, c.graph);
        for (auto e = one_edges.first; e != one_edges.second; ++e) {
            int s = boost::source(*e, c.graph);
            c.add_edge(s, c.one, c.graph[*e]);
        }

        // copies the old zero edges into the new graph
        auto zero_edges = in_edges(old_zero, c.graph);
        for (auto e = zero_edges.first; e != zero_edges.second; ++e) {
            int s = boost::source(*e, c.graph);
            c.add_edge(s, c.zero, c.graph[*e]);
        }

        c.source = c.conjunction_internal(c.source, node_map[c.source]);
        return c;

      }

      private:
      /**
       * Internal function that checks for all the cases
       * Accepts the nodes that must be conjoined
       * and returns the new source.
       */
      int conjunction_internal(int a, int b) {
        // TODO
        return 0;
      }

      int add_vertex(const std::string name) {
        int v = boost::add_vertex(graph);
        graph[v].input_name = name;
        graph[v].t          = Type::Input;
        return v;
      }

      void add_edge(int a, int b, NegP p) {
        boost::add_edge(a, b, p, graph);
      }

      /**
       * USE WITH CAUTION, as it changes the current BDD
       * - changes zero and one
       */
      void reverse() {
        int aux = one;
        one = zero;
        zero = aux;

        graph[zero].t = Type::Zero;
        graph[one].t  = Type::One;
      }

      // Criar um hash o mais unico possivel para um bdd
      hashcode hash(int v) {
        // TODO
      }

      // Compares BDDs
      friend bool operator<(const BDD & bdd1, const BDD & bdd2) {
        // TODO
      }

      /**
       * USE WITH CAUTION, as it changes the current BDD
       * - minimizes the BDD
       */
      void minimize() {
        // TODO
      }
    };
  }
}

<commit_msg>Improved bdd_model.hpp<commit_after>
#pragma once

#include <data_model.hpp>

#include <iostream>
#include <string>
#include <vector>
#include <stdexcept>
#include <map>
#include <sstream>
#include <boost/graph/graph_traits.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/copy.hpp>
#include <boost/property_map/property_map.hpp>

namespace verilog
{
  namespace bdd {

    enum class NegP {
      Positive, Negative
    };

    enum class Type {
      Zero, One, Input
    };

    struct Node {
      std::string input_name;
      Type t;
    };

    typedef boost::adjacency_list<
      boost::setS,
      boost::vecS,
      boost::bidirectionalS,
      Node, NegP> GD;

    typedef unsigned int hashcode;

    struct BDD {
      GD graph;

      /**
       * The node representing the sinks of the BDD
       */
      int zero,
          one,
          /**
           * The node representing the source of the bdd
           */
          source;

      std::map<hashcode, std::vector<int> > bdd_heap;

      BDD(const std::string name) {
        zero = boost::add_vertex(graph);
        one  = boost::add_vertex(graph);
        source = add_vertex(name);
        graph[zero].t = Type::Zero;
        graph[one].t  = Type::One;
      }

      /**
       * Creates a copy of a,
       * merges all nodes of b into the copy.
       * calls the conjunction_internal function for the copy.
       */
      BDD conjunction(const BDD & a, const BDD & b) {

        typedef std::map<GD::vertex_descriptor, GD::vertex_descriptor> node_map_t;
        node_map_t node_map;
        boost::associative_property_map<node_map_t> mapper(node_map);

        BDD c = a;
        copy_graph(b.graph, c.graph, boost::orig_to_copy(mapper));

        int old_zero = node_map[b.zero];
        int old_one  = node_map[b.one];

        // copies the old one edges into the new graph
        c.merge_input_edges(c.one, old_one);
        boost::remove_vertex(old_one, c.graph);

        // copies the old zero edges into the new graph
        c.merge_input_edges(c.zero, old_zero);
        boost::remove_vertex(old_zero, c.graph);

        c.source = c.conjunction_internal(c.source, node_map[c.source]);
        return c;

      }

      private:
      /**
       * Internal function that checks for all the cases
       * Accepts the nodes that must be conjoined
       * and returns the new source.
       */
      int conjunction_internal(int a, int b) {
        // TODO
        return 0;
      }

      int add_vertex(const std::string name) {
        int v = boost::add_vertex(graph);
        graph[v].input_name = name;
        graph[v].t          = Type::Input;
        return v;
      }

      void add_edge(int a, int b, NegP p) {
        boost::add_edge(a, b, p, graph);
      }

      /**
       * USE WITH CAUTION, as it changes the current BDD
       * - changes zero and one
       */
      void reverse() {
        int aux = one;
        one = zero;
        zero = aux;

        graph[zero].t = Type::Zero;
        graph[one].t  = Type::One;
      }

      /**
       * merges the input edges of the node b into node a.
       */
      void merge_input_edges(int a, int b) {
        auto one_edges = in_edges(b, graph);
        for (auto e = one_edges.first; e != one_edges.second; ++e) {
            int s = boost::source(*e, graph);
            add_edge(s, a, graph[*e]);
        }
      }

      std::map<int, std::vector<int> > find_layers() {
        // TODO
      }

      // Criar um hash o mais unico possivel para um bdd
      hashcode hash(int v) {
        // TODO
      }

      // Compares BDDs
      friend bool operator<(const BDD & bdd1, const BDD & bdd2) {
        // TODO
      }

      /**
       * USE WITH CAUTION, as it changes the current BDD
       * - minimizes the BDD
       */
      void minimize() {
        // TODO
      }
    };
  }
}

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    AMRDataTransferPipeline.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
// .SECTION Description
//  A simple utility to demonstrate & test the parallel AMR functionality
//  and inter-block data transfer.

#include <cassert>
#include <mpi.h>

#include "vtkUniformGrid.h"
#include "vtkDataArray.h"
#include "vtkDoubleArray.h"
#include "vtkCell.h"
#include "vtkPoints.h"
#include "vtkPointData.h"
#include "vtkCellData.h"
#include "vtkAMRBox.h"
#include "vtkAMRConnectivityFilter.h"
#include "vtkAMRDataTransferFilter.h"
#include "vtkHierarchicalBoxDataSet.h"
#include "vtkXMLPHierarchicalBoxDataWriter.h"
#include "vtkMultiProcessController.h"
#include "vtkMPIController.h"
#include "vtkAMRUtilities.h"

// Global Variables
vtkMultiProcessController *Controller;

// Function Prototypes
vtkHierarchicalBoxDataSet* GetSerialAMRDataSet();
vtkHierarchicalBoxDataSet* GetParallelAMRDataSet();
vtkUniformGrid* GetGrid( double* origin,double* h,int* ndim );

//
// Main
//
int main( int argc, char **argv )
{
  Controller = vtkMPIController::New();
  Controller->Initialize( &argc, &argv );
  assert("pre: Controller != NULL" && (Controller != NULL ) );

  // STEP 0: Read In AMR data
  std::cout << "Constructing Sample AMR data!" << std::endl;
  std::cout.flush( );

  vtkHierarchicalBoxDataSet *amrData = NULL;

  if( Controller->GetNumberOfProcesses( ) == 3 )
    amrData = GetParallelAMRDataSet( );
  else if( Controller->GetNumberOfProcesses() == 1 )
    amrData = GetSerialAMRDataSet( );
  else
    {
      std::cerr << "Can only run with 1 or 3 MPI processes!\n";
      std::cerr.flush();
      return( -1 );
    }

  assert("pre: AMRData != NULL" && (amrData != NULL) );
  assert("pre: numLevels == 2" && (amrData->GetNumberOfLevels()==2) );

  std::cout << "Done reading!" << std::endl;
  std::cout.flush( );
  Controller->Barrier( );

  // STEP 1: Compute inter-block and inter-process connectivity
  std::cout << "Computing inter-block & inter-process connectivity!\n";
  std::cout.flush( );

  vtkAMRConnectivityFilter* connectivityFilter= vtkAMRConnectivityFilter::New( );
  connectivityFilter->SetController( Controller );
  connectivityFilter->SetAMRDataSet( amrData );
  connectivityFilter->ComputeConnectivity();

  std::cout << "Done computing connectivity!\n";
  std::cout.flush( );
  Controller->Barrier();

  connectivityFilter->Print( std::cout );
  Controller->Barrier();

  // STEP 2: Data transfer
  std::cout << "Transfering solution\n";
  std::cout.flush();

  vtkAMRDataTransferFilter* transferFilter = vtkAMRDataTransferFilter::New();

  transferFilter->SetController( Controller );
  transferFilter->SetAMRDataSet( amrData );
  transferFilter->SetNumberOfGhostLayers( 2 );
  transferFilter->SetRemoteConnectivity(
   connectivityFilter->GetRemoteConnectivity() );
  transferFilter->SetLocalConnectivity(
   connectivityFilter->GetLocalConnectivity() );
  transferFilter->Transfer();

  std::cout << "[DONE]\n";
  std::cout.flush();
  Controller->Barrier();

  // STEP 3: CleanUp
  amrData->Delete();
  connectivityFilter->Delete();
  transferFilter->Delete();

  Controller->Finalize();
  Controller->Delete();
  return 0;
}

//=============================================================================
//                    Function Prototype Implementation
//=============================================================================

//------------------------------------------------------------------------------
vtkHierarchicalBoxDataSet* GetSerialAMRDataSet( )
{

  vtkHierarchicalBoxDataSet *data = vtkHierarchicalBoxDataSet::New( );
  data->Initialize();

  double origin[3];
  double h[3];
  int    ndim[3];
  int    dim      =  2;
  int    blockId  = -1;
  int    level    = -1;
  int    rank     = 0;

  // BLOCK 0
  ndim[0]               = 25;
  ndim[1]               = 25;
  ndim[2]               = 1;
  origin[0]             = 0.0;
  origin[1]             = 0.0;
  origin[2]             = 0.0;
  blockId               = 0;
  level                 = 0;
  h[0] = h[1] = h[2]    = 0.5;
  vtkUniformGrid *grid0 = GetGrid( origin,h,ndim );
  data->SetDataSet( level,blockId,grid0);
  grid0->Delete();

  // BLOCK 1
  ndim[0]            = 11;
  ndim[1]            = 7;
  ndim[2]            = 1;
  origin[0]          = 1.5;
  origin[1]          = 1.5;
  origin[2]          = 0.0;
  blockId            = 0;
  level              = 1;
  h[0] = h[1] = h[2] = 0.25;
  vtkUniformGrid *grid1 = GetGrid( origin,h,ndim );
  data->SetDataSet( level,blockId,grid1);
  grid1->Delete();

  // BLOCK 2
  ndim[0]               = 11;
  ndim[1]               = 7;
  ndim[2]               = 1;
  origin[0]             = 1.0;
  origin[1]             = 3.0;
  origin[2]             = 0.0;
  blockId               = 1;
  level                 = 1;
  h[0] = h[1] = h[2]    = 0.25;
  vtkUniformGrid *grid2 = GetGrid( origin,h,ndim );
  data->SetDataSet( level,blockId,grid2);
  grid2->Delete();

  vtkAMRUtilities::GenerateMetaData( data, NULL );
  data->GenerateVisibilityArrays();
  return( data );
}

//------------------------------------------------------------------------------
vtkHierarchicalBoxDataSet* GetParallelAMRDataSet( )
{
  vtkHierarchicalBoxDataSet *data = vtkHierarchicalBoxDataSet::New( );
  data->Initialize();

  // TODO: imlpement this

  return( data );

}

//----------------------------------------------------------------------------
vtkUniformGrid* GetGrid( double *origin, double *spacing, int *ndim )
{
  vtkUniformGrid *grd = vtkUniformGrid::New();
  grd->Initialize();
  grd->SetOrigin( origin );
  grd->SetSpacing( spacing );
  grd->SetDimensions( ndim );

  vtkDoubleArray* xyz = vtkDoubleArray::New( );
  xyz->SetName( "XYZ" );
  xyz->SetNumberOfComponents( 1 );
  xyz->SetNumberOfTuples( grd->GetNumberOfCells() );
  for( int cellIdx=0; cellIdx < grd->GetNumberOfCells(); ++cellIdx )
    {
      vtkCell* myCell = grd->GetCell( cellIdx);
      assert( "post: myCell != NULL" && (myCell != NULL) );

      vtkPoints *cellPoints = myCell->GetPoints();

      double xyzCenter[3];
      xyzCenter[0] = 0.0;
      xyzCenter[1] = 0.0;
      xyzCenter[2] = 0.0;

      for( int cp=0; cp < cellPoints->GetNumberOfPoints(); ++cp )
        {
          double pnt[3];
          cellPoints->GetPoint( cp, pnt );
          xyzCenter[0] += pnt[0];
          xyzCenter[1] += pnt[1];
          xyzCenter[2] += pnt[2];
        } // END for all cell points

      xyzCenter[0] = xyzCenter[0] / (cellPoints->GetNumberOfPoints());
      xyzCenter[1] = xyzCenter[1] / (cellPoints->GetNumberOfPoints());
      xyzCenter[2] = xyzCenter[2] / (cellPoints->GetNumberOfPoints());

      double f = xyzCenter[0]*xyzCenter[0] +
          xyzCenter[1]*xyzCenter[1] + xyzCenter[2]*xyzCenter[2];
      xyz->SetTuple1(cellIdx,f);
    } // END for all cells

  grd->GetCellData()->AddArray(xyz);
  xyz->Delete();
  return grd;
}
<commit_msg>ENH: Added gaussian pulse solution over the domain<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    AMRDataTransferPipeline.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
// .SECTION Description
//  A simple utility to demonstrate & test the parallel AMR functionality
//  and inter-block data transfer.

#include <cmath>
#include <cassert>
#include <mpi.h>

#include "vtkUniformGrid.h"
#include "vtkDataArray.h"
#include "vtkDoubleArray.h"
#include "vtkCell.h"
#include "vtkPoints.h"
#include "vtkPointData.h"
#include "vtkCellData.h"
#include "vtkAMRBox.h"
#include "vtkAMRConnectivityFilter.h"
#include "vtkAMRDataTransferFilter.h"
#include "vtkHierarchicalBoxDataSet.h"
#include "vtkXMLPHierarchicalBoxDataWriter.h"
#include "vtkMultiProcessController.h"
#include "vtkMPIController.h"
#include "vtkAMRUtilities.h"

// Global Variables
vtkMultiProcessController *Controller;

// Function Prototypes
vtkHierarchicalBoxDataSet* GetSerialAMRDataSet();
vtkHierarchicalBoxDataSet* GetParallelAMRDataSet();
vtkUniformGrid* GetGrid( double* origin,double* h,int* ndim );

//
// Main
//
int main( int argc, char **argv )
{
  Controller = vtkMPIController::New();
  Controller->Initialize( &argc, &argv );
  assert("pre: Controller != NULL" && (Controller != NULL ) );

  // STEP 0: Read In AMR data
  std::cout << "Constructing Sample AMR data!" << std::endl;
  std::cout.flush( );

  vtkHierarchicalBoxDataSet *amrData = NULL;

  if( Controller->GetNumberOfProcesses( ) == 3 )
    amrData = GetParallelAMRDataSet( );
  else if( Controller->GetNumberOfProcesses() == 1 )
    amrData = GetSerialAMRDataSet( );
  else
    {
      std::cerr << "Can only run with 1 or 3 MPI processes!\n";
      std::cerr.flush();
      return( -1 );
    }

  assert("pre: AMRData != NULL" && (amrData != NULL) );
  assert("pre: numLevels == 2" && (amrData->GetNumberOfLevels()==2) );

  std::cout << "Done reading!" << std::endl;
  std::cout.flush( );
  Controller->Barrier( );

  // STEP 1: Compute inter-block and inter-process connectivity
  std::cout << "Computing inter-block & inter-process connectivity!\n";
  std::cout.flush( );

  vtkAMRConnectivityFilter* connectivityFilter=vtkAMRConnectivityFilter::New( );
  connectivityFilter->SetController( Controller );
  connectivityFilter->SetAMRDataSet( amrData );
  connectivityFilter->ComputeConnectivity();

  std::cout << "Done computing connectivity!\n";
  std::cout.flush( );
  Controller->Barrier();

  connectivityFilter->Print( std::cout );
  Controller->Barrier();

  // STEP 2: Data transfer
  std::cout << "Transfering solution\n";
  std::cout.flush();

  vtkAMRDataTransferFilter* transferFilter = vtkAMRDataTransferFilter::New();

  transferFilter->SetController( Controller );
  transferFilter->SetAMRDataSet( amrData );
  transferFilter->SetNumberOfGhostLayers( 2 );
  transferFilter->SetRemoteConnectivity(
   connectivityFilter->GetRemoteConnectivity() );
  transferFilter->SetLocalConnectivity(
   connectivityFilter->GetLocalConnectivity() );
  transferFilter->Transfer();

  std::cout << "[DONE]\n";
  std::cout.flush();
  Controller->Barrier();

  // STEP 3: CleanUp
  amrData->Delete();
  connectivityFilter->Delete();
  transferFilter->Delete();

  Controller->Finalize();
  Controller->Delete();
  return 0;
}

//=============================================================================
//                    Function Prototype Implementation
//=============================================================================

//------------------------------------------------------------------------------
vtkHierarchicalBoxDataSet* GetSerialAMRDataSet( )
{

  vtkHierarchicalBoxDataSet *data = vtkHierarchicalBoxDataSet::New( );
  data->Initialize();

  double origin[3];
  double h[3];
  int    ndim[3];
  int    dim      =  2;
  int    blockId  = -1;
  int    level    = -1;
  int    rank     = 0;

  // BLOCK 0
  ndim[0]               = 25;
  ndim[1]               = 25;
  ndim[2]               = 1;
  origin[0]             = 0.0;
  origin[1]             = 0.0;
  origin[2]             = 0.0;
  blockId               = 0;
  level                 = 0;
  h[0] = h[1] = h[2]    = 0.5;
  vtkUniformGrid *grid0 = GetGrid( origin,h,ndim );
  data->SetDataSet( level,blockId,grid0);
  grid0->Delete();

  // BLOCK 1
  ndim[0]            = 11;
  ndim[1]            = 7;
  ndim[2]            = 1;
  origin[0]          = 1.5;
  origin[1]          = 1.5;
  origin[2]          = 0.0;
  blockId            = 0;
  level              = 1;
  h[0] = h[1] = h[2] = 0.25;
  vtkUniformGrid *grid1 = GetGrid( origin,h,ndim );
  data->SetDataSet( level,blockId,grid1);
  grid1->Delete();

  // BLOCK 2
  ndim[0]               = 11;
  ndim[1]               = 7;
  ndim[2]               = 1;
  origin[0]             = 1.0;
  origin[1]             = 3.0;
  origin[2]             = 0.0;
  blockId               = 1;
  level                 = 1;
  h[0] = h[1] = h[2]    = 0.25;
  vtkUniformGrid *grid2 = GetGrid( origin,h,ndim );
  data->SetDataSet( level,blockId,grid2);
  grid2->Delete();

  vtkAMRUtilities::GenerateMetaData( data, NULL );
  data->GenerateVisibilityArrays();
  return( data );
}

//------------------------------------------------------------------------------
vtkHierarchicalBoxDataSet* GetParallelAMRDataSet( )
{
  vtkHierarchicalBoxDataSet *data = vtkHierarchicalBoxDataSet::New( );
  data->Initialize();

  // TODO: imlpement this

  return( data );

}

//----------------------------------------------------------------------------
vtkUniformGrid* GetGrid( double *origin, double *spacing, int *ndim )
{
  vtkUniformGrid *grd = vtkUniformGrid::New();
  grd->Initialize();
  grd->SetOrigin( origin );
  grd->SetSpacing( spacing );
  grd->SetDimensions( ndim );

  // Apply Gaussian Pulse
  double x0 = 6.0;
  double y0 = 6.0;
  double lx = 12;
  double ly = 12;
  double a  = 0.1;

  vtkDoubleArray* xyz = vtkDoubleArray::New( );
  xyz->SetName( "GaussianPulse" );
  xyz->SetNumberOfComponents( 1 );
  xyz->SetNumberOfTuples( grd->GetNumberOfCells() );
  for( int cellIdx=0; cellIdx < grd->GetNumberOfCells(); ++cellIdx )
    {
      vtkCell* myCell = grd->GetCell( cellIdx);
      assert( "post: myCell != NULL" && (myCell != NULL) );

      vtkPoints *cellPoints = myCell->GetPoints();

      double xyzCenter[3];
      xyzCenter[0] = 0.0;
      xyzCenter[1] = 0.0;
      xyzCenter[2] = 0.0;

      for( int cp=0; cp < cellPoints->GetNumberOfPoints(); ++cp )
        {
          double pnt[3];
          cellPoints->GetPoint( cp, pnt );
          xyzCenter[0] += pnt[0];
          xyzCenter[1] += pnt[1];
          xyzCenter[2] += pnt[2];
        } // END for all cell points

      double x = xyzCenter[0] / (cellPoints->GetNumberOfPoints());
      double y = xyzCenter[1] / (cellPoints->GetNumberOfPoints());
      double z = xyzCenter[2] / (cellPoints->GetNumberOfPoints());

      double r = ( ( (x-x0)*(x-x0) ) / ( lx*lx ) ) +
                 ( ( (y-y0)*(y-y0) ) / ( ly*ly ) );
      double f = a*std::exp( -r );
      xyz->SetTuple1(cellIdx,f);
    } // END for all cells

  grd->GetCellData()->AddArray(xyz);
  xyz->Delete();
  return grd;
}
<|endoftext|>


<commit_before>// Copyright (C) 2015 - 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

/*
 * SpeciesInitialValueLostFocusCommand.cpp
 *
 *  Created on: 19 Sep 2014
 *      Author: dada
 */

#include "qtUtilities.h"

#include "model/CMetab.h"
#include "UI/CQSpeciesDetail.h"
#include "model/CCompartment.h"

#include "UndoSpeciesData.h"

#include "SpeciesInitialValueLostFocusCommand.h"

SpeciesInitialValueLostFocusCommand::SpeciesInitialValueLostFocusCommand(
  CQSpeciesDetail *pSpecieDetail)
  : CCopasiUndoCommand("Species", SPECIES_TYPE_CHANGE, "Change")
  , mpSpecieDetail(pSpecieDetail)
  , mpSpeciesData(new UndoSpeciesData(mpSpecieDetail->mpMetab))
  , mFirstTime(true)
{

  std::string sName = mpSpecieDetail->mpMetab->getObjectName();
  setText(QString(": Species Initial Value Change for %1").arg(FROM_UTF8(sName)));
  setName(mpSpeciesData->getName());

  {
    double newValue = mpSpecieDetail->mpEditInitialValue->text().toDouble();
    std::ostringstream strs;
    strs << newValue;
    std::string str = strs.str();
    setNewValue(str);
  }
  {
    std::ostringstream strs;
    strs << mpSpecieDetail->mInitialConcentration;
    std::string str = strs.str();
    setOldValue(str);
  }
  setProperty("Initial Value");
}
void SpeciesInitialValueLostFocusCommand::redo()
{
  if (mFirstTime)
    {
      mpSpecieDetail->speciesInitialValueLostFocus();
      mFirstTime = false;
    }
  else
    {
      mpSpecieDetail->speciesInitialValueLostFocus(mpSpeciesData);
    }

  setAction("Change");
}
void SpeciesInitialValueLostFocusCommand::undo()
{
  mpSpecieDetail->speciesInitialValueLostFocus(mpSpeciesData);
  setAction("Undone change");
}

SpeciesInitialValueLostFocusCommand::~SpeciesInitialValueLostFocusCommand()
{
  pdelete(mpSpeciesData);
}
<commit_msg>The default precision for ostringstream resulted in a truncation of the Initial Concentrations ending up in the undo and provenance, when that lost focus, in Species Detail widget (i.e. any time you edited, then left). It also seemed there was no gain for setNewValue use converted QString to double to ostringstream to std::string. QString::toDouble is still limited to whatever was in the QString, to try and convert.<commit_after>// Copyright (C) 2015 - 2016 by Pedro Mendes, Virginia Tech Intellectual
// Properties, Inc., University of Heidelberg, and The University
// of Manchester.
// All rights reserved.

/*
 * SpeciesInitialValueLostFocusCommand.cpp
 *
 *  Created on: 19 Sep 2014
 *      Author: dada
 */

#include "qtUtilities.h"

#include "model/CMetab.h"
#include "UI/CQSpeciesDetail.h"
#include "model/CCompartment.h"

#include "UndoSpeciesData.h"

#include "SpeciesInitialValueLostFocusCommand.h"

SpeciesInitialValueLostFocusCommand::SpeciesInitialValueLostFocusCommand(
  CQSpeciesDetail *pSpecieDetail)
  : CCopasiUndoCommand("Species", SPECIES_TYPE_CHANGE, "Change")
  , mpSpecieDetail(pSpecieDetail)
  , mpSpeciesData(new UndoSpeciesData(mpSpecieDetail->mpMetab))
  , mFirstTime(true)
{

  std::string sName = mpSpecieDetail->mpMetab->getObjectName();
  setText(QString(": Species Initial Value Change for %1").arg(FROM_UTF8(sName)));
  setName(mpSpeciesData->getName());

  {
    setNewValue(mpSpecieDetail->mpEditInitialValue->text().toStdString());
  }
  {
    std::ostringstream strs;
    strs.precision(std::numeric_limits<double>::max());
    strs << mpSpecieDetail->mInitialConcentration;
    std::string str = strs.str();
    setOldValue(str);
  }
  setProperty("Initial Value");
}
void SpeciesInitialValueLostFocusCommand::redo()
{
  if (mFirstTime)
    {
      mpSpecieDetail->speciesInitialValueLostFocus();
      mFirstTime = false;
    }
  else
    {
      mpSpecieDetail->speciesInitialValueLostFocus(mpSpeciesData);
    }

  setAction("Change");
}
void SpeciesInitialValueLostFocusCommand::undo()
{
  mpSpecieDetail->speciesInitialValueLostFocus(mpSpeciesData);
  setAction("Undone change");
}

SpeciesInitialValueLostFocusCommand::~SpeciesInitialValueLostFocusCommand()
{
  pdelete(mpSpeciesData);
}
<|endoftext|>


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

#include <miopen/errors.hpp>
#include <miopen/gcn_asm_utils.hpp>
#include <miopen/hip_build_utils.hpp>
#include <miopen/hipoc_program.hpp>
#include <miopen/kernel.hpp>
#include <miopen/kernel_warnings.hpp>
#include <miopen/logger.hpp>
#include <miopen/stringutils.hpp>
#include <miopen/tmp_dir.hpp>
#include <miopen/write_file.hpp>
#include <miopen/env.hpp>
#include <miopen/comgr.hpp>
#include <boost/optional.hpp>

#include <cstring>
#include <mutex>
#include <sstream>

#include <unistd.h>

MIOPEN_DECLARE_ENV_VAR(MIOPEN_DEBUG_OPENCL_ENFORCE_CODE_OBJECT_VERSION)
MIOPEN_DECLARE_ENV_VAR(MIOPEN_DEVICE_ARCH)

#define MIOPEN_WORKAROUND_SWDEV_225285 1

#if MIOPEN_USE_COMGR
#define MIOPEN_WORKAROUND_ROCM_COMPILER_SUPPORT_ISSUE_27 1
#endif

namespace miopen {

#if !MIOPEN_USE_COMGR
namespace {

inline std::string GetCodeObjectVersionOptionImpl()
{
    auto code_object_version = miopen::Value(MIOPEN_DEBUG_OPENCL_ENFORCE_CODE_OBJECT_VERSION{});
    // Very basic syntax check:
    if(code_object_version == 1 || code_object_version > 4)
    {
        MIOPEN_LOG_E("Bad MIOPEN_DEBUG_OPENCL_ENFORCE_CODE_OBJECT_VERSION, using default");
        code_object_version = 0;
    }

    if(HipCompilerVersion() >= external_tool_version_t{4, 0, -1})
    {
        if(code_object_version == 0) // Env.var is unset.
            return {};               // Rely on compiler's default.
        else
            return std::string("-mcode-object-version=") + std::to_string(code_object_version);
    }
    else
    {
        // By default, let's assume that OpenCL kernels shall be compiled to
        // CO v3 format since ROCm 3.0.
        if(code_object_version == 0)
            code_object_version = HipCompilerVersion() >= external_tool_version_t{3, 0, -1} ? 3 : 2;

        switch(code_object_version)
        {
        // These options are Ok for ROCm for a long time (since 2.5 or so):
        case 2: return {"-Xclang -target-feature -Xclang -code-object-v3"};
        default: // Fall through.
        case 3: return {"-Xclang -target-feature -Xclang +code-object-v3"};
        }
    }
}

inline std::string GetCodeObjectVersionOption()
{
    static const auto option = GetCodeObjectVersionOptionImpl();
    return option;
}

} // namespace
#endif

static hipModulePtr CreateModule(const boost::filesystem::path& hsaco_file)
{
    hipModule_t raw_m;
    auto status = hipModuleLoad(&raw_m, hsaco_file.string().c_str());
    hipModulePtr m{raw_m};
    if(status != hipSuccess)
        MIOPEN_THROW_HIP_STATUS(status, "Failed creating module");
    return m;
}

template <typename T> /// intended for std::string and std::vector<char>
hipModulePtr CreateModuleInMem(const T& blob)
{
#if !MIOPEN_WORKAROUND_SWDEV_225285
    hipModule_t raw_m;
    auto status = hipModuleLoadData(&raw_m, reinterpret_cast<const void*>(blob.data()));
    hipModulePtr m{raw_m};
    if(status != hipSuccess)
        MIOPEN_THROW_HIP_STATUS(status, "Failed loading module");
    return m;
#else
    TmpDir tmp_dir("miopen");
    auto file_path = tmp_dir.path / boost::filesystem::unique_path("miopen-%%%%-%%%%-%%%%-%%%%");
    WriteFile(blob, file_path);
    return CreateModule(file_path);
#endif
}

struct HIPOCProgramImpl
{
    HIPOCProgramImpl(const std::string& program_name, const boost::filesystem::path& filespec)
        : program(program_name), hsaco_file(filespec)
    {
        module = CreateModule(hsaco_file);
    }

    HIPOCProgramImpl(const std::string& program_name, const std::string& blob)
        : program(program_name)
    {
        TmpDir tmp_dir("miopen");
        auto file_path =
            tmp_dir.path / boost::filesystem::unique_path("miopen-%%%%-%%%%-%%%%-%%%%");
        WriteFile(blob, file_path);
        const char* const arch = miopen::GetStringEnv(MIOPEN_DEVICE_ARCH{});
        if(arch == nullptr)
        {
            this->module = CreateModule(file_path);
        }
    }

    HIPOCProgramImpl(const std::string& program_name,
                     std::string params,
                     bool is_kernel_str,
                     std::string dev_name,
                     const std::string& kernel_src)
        : program(program_name), device(dev_name)
    {
        BuildCodeObject(params, is_kernel_str, kernel_src);
        if(!binary.empty())
        {
            module = CreateModuleInMem(binary);
        }
        else
        {
            const char* const arch = miopen::GetStringEnv(MIOPEN_DEVICE_ARCH{});
            if(arch == nullptr)
            {
                module = CreateModule(hsaco_file);
            }
        }
    }

    std::string program;
    std::string device;
    boost::filesystem::path hsaco_file;
    hipModulePtr module;
    boost::optional<TmpDir> dir;
    std::vector<char> binary;

#if !MIOPEN_USE_COMGR
    void
    BuildCodeObjectInFile(std::string& params, const std::string& src, const std::string& filename)
    {
        dir.emplace(filename);
        hsaco_file = dir->path / (filename + ".o");

        if(miopen::EndsWith(filename, ".so"))
        {
            WriteFile(src, hsaco_file);
        }
        else if(miopen::EndsWith(filename, ".s"))
        {
            const auto assembled = AmdgcnAssemble(src, params);
            WriteFile(assembled, hsaco_file);
        }
        else if(miopen::EndsWith(filename, ".cpp"))
        {
            hsaco_file = HipBuild(dir, filename, src, params, device);
        }
        else
        {
            params += " " + GetCodeObjectVersionOption();
            WriteFile(src, dir->path / filename);
            dir->Execute(HIP_OC_COMPILER, params + " " + filename + " -o " + hsaco_file.string());
        }
        if(!boost::filesystem::exists(hsaco_file))
            MIOPEN_THROW("Cant find file: " + hsaco_file.string());
    }

#else // MIOPEN_USE_COMGR
    void BuildCodeObjectInMemory(const std::string& params,
                                 const std::string& src,
                                 const std::string& filename)
    {
        if(miopen::EndsWith(filename, ".so"))
        {
            std::size_t sz = src.length();
            binary.resize(sz);
            std::memcpy(&binary[0], src.c_str(), sz);
        }
        else
        {
#if MIOPEN_WORKAROUND_ROCM_COMPILER_SUPPORT_ISSUE_27
            static std::mutex mutex;
            std::lock_guard<std::mutex> lock(mutex);
#endif
            if(miopen::EndsWith(filename, ".cpp"))
                comgr::BuildHip(filename, src, params, device, binary);
            else if(miopen::EndsWith(filename, ".s"))
                comgr::BuildAsm(filename, src, params, device, binary);
            else
                comgr::BuildOcl(filename, src, params, device, binary);
        }
        if(binary.empty())
            MIOPEN_THROW("Code object build failed. Source: " + filename);
    }
#endif // MIOPEN_USE_COMGR

    void BuildCodeObject(std::string params, bool is_kernel_str, const std::string& kernel_src)
    {
        std::string filename = is_kernel_str ? "tinygemm.cl" // Fixed name for miopengemm.
                                             : program;
        const std::string src =
            !kernel_src.empty() ? kernel_src : is_kernel_str ? program : GetKernelSrc(program);

        if(miopen::EndsWith(filename, ".cpp"))
        {
#if MIOPEN_BUILD_DEV
            params += " -Werror" + HipKernelWarningsString();
#else
            params += " -Wno-everything";
#endif
        }
        else if(miopen::EndsWith(filename, ".cl"))
        {
#if MIOPEN_BUILD_DEV
            params += " -Werror" + OclKernelWarningsString();
#else
            params += " -Wno-everything";
#endif
        }

#if MIOPEN_USE_COMGR /// \todo Refactor when functionality stabilize.
        BuildCodeObjectInMemory(params, src, filename);
#else
        BuildCodeObjectInFile(params, src, filename);
#endif
    }
};

HIPOCProgram::HIPOCProgram() {}
HIPOCProgram::HIPOCProgram(const std::string& program_name,
                           std::string params,
                           bool is_kernel_str,
                           std::string dev_name,
                           const std::string& kernel_src)
    : impl(std::make_shared<HIPOCProgramImpl>(
          program_name, params, is_kernel_str, dev_name, kernel_src))
{
}

HIPOCProgram::HIPOCProgram(const std::string& program_name, const boost::filesystem::path& hsaco)
    : impl(std::make_shared<HIPOCProgramImpl>(program_name, hsaco))
{
}

HIPOCProgram::HIPOCProgram(const std::string& program_name, const std::string& hsaco)
    : impl(std::make_shared<HIPOCProgramImpl>(program_name, hsaco))
{
}

hipModule_t HIPOCProgram::GetModule() const { return impl->module.get(); }

boost::filesystem::path HIPOCProgram::GetCodeObjectPathname() const { return impl->hsaco_file; }

std::string HIPOCProgram::GetCodeObjectBlob() const
{
    return {impl->binary.data(), impl->binary.size()};
}

bool HIPOCProgram::IsCodeObjectInMemory() const { return !impl->binary.empty(); };

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

#include <miopen/errors.hpp>
#include <miopen/gcn_asm_utils.hpp>
#include <miopen/hip_build_utils.hpp>
#include <miopen/hipoc_program.hpp>
#include <miopen/kernel.hpp>
#include <miopen/kernel_warnings.hpp>
#include <miopen/logger.hpp>
#include <miopen/stringutils.hpp>
#include <miopen/tmp_dir.hpp>
#include <miopen/write_file.hpp>
#include <miopen/env.hpp>
#include <miopen/comgr.hpp>
#include <boost/optional.hpp>

#include <cstring>
#include <mutex>
#include <sstream>

#include <unistd.h>

/// 0 or undef or wrong - auto-detect
/// 1 - <blank> / "-Xclang -target-feature -Xclang +code-object-v3"
/// 2 - "-Xclang -target-feature -Xclang -code-object-v3" /
///     "-Xclang -target-feature -Xclang +code-object-v3"
/// 3 - "-mnocode-object-v3" / "-mcode-object-v3"
/// 4 - "-mcode-object-version=2/3/4"
MIOPEN_DECLARE_ENV_VAR(MIOPEN_DEBUG_OPENCL_ENFORCE_CODE_OBJECT_OPTION)
MIOPEN_DECLARE_ENV_VAR(MIOPEN_DEBUG_OPENCL_ENFORCE_CODE_OBJECT_VERSION)
MIOPEN_DECLARE_ENV_VAR(MIOPEN_DEVICE_ARCH)

#define MIOPEN_WORKAROUND_SWDEV_225285 1

#if MIOPEN_USE_COMGR
#define MIOPEN_WORKAROUND_ROCM_COMPILER_SUPPORT_ISSUE_27 1
#endif

namespace miopen {

#if !MIOPEN_USE_COMGR
namespace {

int DetectCodeObjectOptionSyntax()
{
    auto syntax = miopen::Value(MIOPEN_DEBUG_OPENCL_ENFORCE_CODE_OBJECT_OPTION{});
    if(syntax > 4)
    {
        MIOPEN_LOG_E("Bad MIOPEN_DEBUG_OPENCL_ENFORCE_CODE_OBJECT_OPTION, using default");
        syntax = 0;
    }

    if(syntax == 0)
    {
        if(HipCompilerVersion() >= external_tool_version_t{4, 0, 999999}) /// \ todo
            return 4;
        else
            return 1;
    }
    MIOPEN_LOG_I("MIOPEN_DEBUG_OPENCL_ENFORCE_CODE_OBJECT_OPTION=" << syntax);
    return syntax;
}

int DetectCodeObjectVersion()
{
    auto co_version = miopen::Value(MIOPEN_DEBUG_OPENCL_ENFORCE_CODE_OBJECT_VERSION{});
    // Very basic syntax check:
    if(co_version == 1 || co_version > 4)
    {
        MIOPEN_LOG_E("Bad MIOPEN_DEBUG_OPENCL_ENFORCE_CODE_OBJECT_VERSION, using default");
        co_version = 0;
    }

    if(co_version == 0)
    {
        if(HipCompilerVersion() >= external_tool_version_t{4, 0, 999999}) /// \ todo
            return 4;
        else if(HipCompilerVersion() >= external_tool_version_t{3, 0, -1})
            return 3;
        else
            return 2;
    }
    MIOPEN_LOG_I("MIOPEN_DEBUG_OPENCL_ENFORCE_CODE_OBJECT_VERSION=" << co_version);
    return co_version;
}

std::string GetCodeObjectVersionOptionImpl()
{
    const auto co_version = DetectCodeObjectVersion();
    const auto syntax     = DetectCodeObjectOptionSyntax();

    if(syntax == 4)
    {
        return std::string("-mcode-object-version=") + std::to_string(co_version);
    }
    else if(syntax == 3)
    {
        switch(co_version)
        {
        case 2: return {"-mnocode-object-v3"};
        default: // Fall through.
        case 3: return {"-mcode-object-v3"};
        }
    }
    else // syntax == 1 or 2
    {
        switch(co_version)
        {
        // These options are Ok for ROCm for a long time (since 2.5 or so):
        case 2: return {(syntax == 1) ? "" : "-Xclang -target-feature -Xclang -code-object-v3"};
        default: // Fall through.
        case 3: return {"-Xclang -target-feature -Xclang +code-object-v3"};
        }
    }
}

inline std::string GetCodeObjectVersionOption()
{
    static const auto option = GetCodeObjectVersionOptionImpl();
    return option;
}

} // namespace
#endif

static hipModulePtr CreateModule(const boost::filesystem::path& hsaco_file)
{
    hipModule_t raw_m;
    auto status = hipModuleLoad(&raw_m, hsaco_file.string().c_str());
    hipModulePtr m{raw_m};
    if(status != hipSuccess)
        MIOPEN_THROW_HIP_STATUS(status, "Failed creating module");
    return m;
}

template <typename T> /// intended for std::string and std::vector<char>
hipModulePtr CreateModuleInMem(const T& blob)
{
#if !MIOPEN_WORKAROUND_SWDEV_225285
    hipModule_t raw_m;
    auto status = hipModuleLoadData(&raw_m, reinterpret_cast<const void*>(blob.data()));
    hipModulePtr m{raw_m};
    if(status != hipSuccess)
        MIOPEN_THROW_HIP_STATUS(status, "Failed loading module");
    return m;
#else
    TmpDir tmp_dir("miopen");
    auto file_path = tmp_dir.path / boost::filesystem::unique_path("miopen-%%%%-%%%%-%%%%-%%%%");
    WriteFile(blob, file_path);
    return CreateModule(file_path);
#endif
}

struct HIPOCProgramImpl
{
    HIPOCProgramImpl(const std::string& program_name, const boost::filesystem::path& filespec)
        : program(program_name), hsaco_file(filespec)
    {
        module = CreateModule(hsaco_file);
    }

    HIPOCProgramImpl(const std::string& program_name, const std::string& blob)
        : program(program_name)
    {
        TmpDir tmp_dir("miopen");
        auto file_path =
            tmp_dir.path / boost::filesystem::unique_path("miopen-%%%%-%%%%-%%%%-%%%%");
        WriteFile(blob, file_path);
        const char* const arch = miopen::GetStringEnv(MIOPEN_DEVICE_ARCH{});
        if(arch == nullptr)
        {
            this->module = CreateModule(file_path);
        }
    }

    HIPOCProgramImpl(const std::string& program_name,
                     std::string params,
                     bool is_kernel_str,
                     std::string dev_name,
                     const std::string& kernel_src)
        : program(program_name), device(dev_name)
    {
        BuildCodeObject(params, is_kernel_str, kernel_src);
        if(!binary.empty())
        {
            module = CreateModuleInMem(binary);
        }
        else
        {
            const char* const arch = miopen::GetStringEnv(MIOPEN_DEVICE_ARCH{});
            if(arch == nullptr)
            {
                module = CreateModule(hsaco_file);
            }
        }
    }

    std::string program;
    std::string device;
    boost::filesystem::path hsaco_file;
    hipModulePtr module;
    boost::optional<TmpDir> dir;
    std::vector<char> binary;

#if !MIOPEN_USE_COMGR
    void
    BuildCodeObjectInFile(std::string& params, const std::string& src, const std::string& filename)
    {
        dir.emplace(filename);
        hsaco_file = dir->path / (filename + ".o");

        if(miopen::EndsWith(filename, ".so"))
        {
            WriteFile(src, hsaco_file);
        }
        else if(miopen::EndsWith(filename, ".s"))
        {
            const auto assembled = AmdgcnAssemble(src, params);
            WriteFile(assembled, hsaco_file);
        }
        else if(miopen::EndsWith(filename, ".cpp"))
        {
            hsaco_file = HipBuild(dir, filename, src, params, device);
        }
        else
        {
            params += " " + GetCodeObjectVersionOption();
            WriteFile(src, dir->path / filename);
            dir->Execute(HIP_OC_COMPILER, params + " " + filename + " -o " + hsaco_file.string());
        }
        if(!boost::filesystem::exists(hsaco_file))
            MIOPEN_THROW("Cant find file: " + hsaco_file.string());
    }

#else // MIOPEN_USE_COMGR
    void BuildCodeObjectInMemory(const std::string& params,
                                 const std::string& src,
                                 const std::string& filename)
    {
        if(miopen::EndsWith(filename, ".so"))
        {
            std::size_t sz = src.length();
            binary.resize(sz);
            std::memcpy(&binary[0], src.c_str(), sz);
        }
        else
        {
#if MIOPEN_WORKAROUND_ROCM_COMPILER_SUPPORT_ISSUE_27
            static std::mutex mutex;
            std::lock_guard<std::mutex> lock(mutex);
#endif
            if(miopen::EndsWith(filename, ".cpp"))
                comgr::BuildHip(filename, src, params, device, binary);
            else if(miopen::EndsWith(filename, ".s"))
                comgr::BuildAsm(filename, src, params, device, binary);
            else
                comgr::BuildOcl(filename, src, params, device, binary);
        }
        if(binary.empty())
            MIOPEN_THROW("Code object build failed. Source: " + filename);
    }
#endif // MIOPEN_USE_COMGR

    void BuildCodeObject(std::string params, bool is_kernel_str, const std::string& kernel_src)
    {
        std::string filename = is_kernel_str ? "tinygemm.cl" // Fixed name for miopengemm.
                                             : program;
        const std::string src =
            !kernel_src.empty() ? kernel_src : is_kernel_str ? program : GetKernelSrc(program);

        if(miopen::EndsWith(filename, ".cpp"))
        {
#if MIOPEN_BUILD_DEV
            params += " -Werror" + HipKernelWarningsString();
#else
            params += " -Wno-everything";
#endif
        }
        else if(miopen::EndsWith(filename, ".cl"))
        {
#if MIOPEN_BUILD_DEV
            params += " -Werror" + OclKernelWarningsString();
#else
            params += " -Wno-everything";
#endif
        }

#if MIOPEN_USE_COMGR /// \todo Refactor when functionality stabilize.
        BuildCodeObjectInMemory(params, src, filename);
#else
        BuildCodeObjectInFile(params, src, filename);
#endif
    }
};

HIPOCProgram::HIPOCProgram() {}
HIPOCProgram::HIPOCProgram(const std::string& program_name,
                           std::string params,
                           bool is_kernel_str,
                           std::string dev_name,
                           const std::string& kernel_src)
    : impl(std::make_shared<HIPOCProgramImpl>(
          program_name, params, is_kernel_str, dev_name, kernel_src))
{
}

HIPOCProgram::HIPOCProgram(const std::string& program_name, const boost::filesystem::path& hsaco)
    : impl(std::make_shared<HIPOCProgramImpl>(program_name, hsaco))
{
}

HIPOCProgram::HIPOCProgram(const std::string& program_name, const std::string& hsaco)
    : impl(std::make_shared<HIPOCProgramImpl>(program_name, hsaco))
{
}

hipModule_t HIPOCProgram::GetModule() const { return impl->module.get(); }

boost::filesystem::path HIPOCProgram::GetCodeObjectPathname() const { return impl->hsaco_file; }

std::string HIPOCProgram::GetCodeObjectBlob() const
{
    return {impl->binary.data(), impl->binary.size()};
}

bool HIPOCProgram::IsCodeObjectInMemory() const { return !impl->binary.empty(); };

} // namespace miopen
<|endoftext|>


<commit_before>// Copyright 2017 Global Phasing Ltd.
//
// CIF parser (based on PEGTL), struct Document that represents the CIF file,
// and a set of actions for the parser to prepare Document.

#ifndef GEMMI_CIF_HPP_
#define GEMMI_CIF_HPP_
#include <cassert>
#include <cstdio>     // for FILE
#include <iosfwd>     // for size_t, istream
#include <string>

#include <tao/pegtl.hpp>
//#include <tao/pegtl/contrib/tracer.hpp>  // for debugging

#include "cifdoc.hpp" // for Document, etc

#if defined(_MSC_VER)
#pragma warning(push)
// warning C4244: an integer type is converted to a smaller integer type
#pragma warning(disable: 4244)
// warning C4267: conversion from 'size_t' to 'type', possible loss of data
#pragma warning(disable: 4267)
#endif

namespace gemmi {
namespace cif {
using std::size_t;
namespace pegtl = tao::pegtl;

// **** grammar rules, named similarly as in the CIF 1.1 spec ****
namespace rules {

  using namespace pegtl;

  // (letter) refers to sections in Table 2.2.7.1 in Vol.G of ITfC (2006).

  // (g) Character sets.
  // OrdinaryCharacter: ! % &  ()*+,-./0-9:  <=>?@A-Z[]  \ ^  `a-z{|}~

  // !"#$%&'()*+,-./0-9:;<=>?@A-Z[\]^_`a-z{|}~
  struct nonblank_ch : range<'!', '~'> {};

  // ascii space is just before '!'
  struct anyprint_ch : ranges<' ', '~', '\t'> {};

  // (f) White space and comments.
  struct comment : if_must<one<'#'>, until<eolf>> {};
  struct whitespace : plus<sor<one<' ','\n','\r','\t'>, comment>> {};

  // (b) Reserved words.
  struct str_data : TAOCPP_PEGTL_ISTRING("data_") {};
  struct str_loop : TAOCPP_PEGTL_ISTRING("loop_") {};
  struct str_global : TAOCPP_PEGTL_ISTRING("global_") {};
  struct str_save : TAOCPP_PEGTL_ISTRING("save_") {};
  struct str_stop : TAOCPP_PEGTL_ISTRING("stop_") {};
  struct keyword : sor<str_data, str_loop, str_global, str_save, str_stop> {};

  // (e) Character strings and text fields.
  template <typename Q>
  struct endq : seq<Q, at<sor<one<' ','\n','\r','\t','#'>, pegtl::eof>>> {};
  // strict rule would be:
  // template <typename Q> struct quoted_tail : until<endq<Q>, anyprint_ch> {};
  // but it was relaxed after PDB accepted 5q1h with non-ascii character
  template <typename Q> struct quoted_tail : until<endq<Q>, not_one<'\n'>> {};
  template <typename Q> struct quoted : if_must<Q, quoted_tail<Q>> {};
  struct singlequoted : quoted<one<'\''>> {};
  struct doublequoted : quoted<one<'"'>> {};
  struct field_sep : seq<bol, one<';'>> {};
  // CIF 2.0 requires whitespace after text field, so it'd be:
  // until<endq<field_sep>> instead of until<field_sep>.
  struct textfield : if_must<field_sep, until<field_sep>> {};
  struct unquoted : seq<not_at<keyword>, not_at<one<'_','$','#'>>,
                        plus<nonblank_ch>> {};

  // (c) Tags and values.

  // (a) Basic structure of CIF.
  struct datablockname : plus<nonblank_ch> {};
  struct datablockheading : sor<if_must<str_data, datablockname>,
                                str_global> {};
  struct tag : seq<one<'_'>, plus<nonblank_ch>> {};
  // simple unquoted value - for a typical mmCIF file it is faster
  // to check first this risking backtracking.
  struct simunq : seq<plus<ranges<'(', ':', '<', 'Z', 'a', 'z'>>,
                      at<one<' ','\n','\r','\t'>>> {};
  struct value: sor<simunq, singlequoted, doublequoted, textfield, unquoted> {};
  struct loop_tag : tag {};
  struct loop_value : value {};
  struct loop_end : opt<seq<whitespace, str_stop>> {};
  struct loop: if_must<str_loop, plus<seq<whitespace, loop_tag, discard>>,
                                 plus<seq<whitespace, loop_value, discard>>,
                                 loop_end> {};
  struct dataitem: if_must<tag, whitespace, value, discard> {};
  struct framename : plus<nonblank_ch> {};
  struct endframe : str_save {};
  struct frame : if_must<str_save, framename, whitespace,
                         star<sor<dataitem, loop>, whitespace>,
                         endframe> {};
  struct datablock : seq<datablockheading,
                         star<whitespace, sor<dataitem, loop, frame>>> {};
  struct file : must<opt<whitespace>,
                     until<pegtl::eof, list_tail<datablock, whitespace>>> {};

} // namespace rules

// **** error messages ****

template<typename Rule> struct Errors : public pegtl::normal<Rule> {
  static const std::string msg;

  template<typename Input, typename ... States>
  static void raise(const Input& in, States&& ...) {
    throw pegtl::parse_error(msg, in);
  }
};
#if defined(_MSC_VER)
# define error_msg(x) \
  template<> __declspec(selectany) const std::string Errors<x>::msg
#else
# define error_msg(x) \
  template<> const std::string Errors<x>::msg __attribute__((weak))
#endif
// TODO: error "expected data_ keyword
error_msg(rules::quoted_tail<rules::one<'\''>>) = "unterminated 'string'";
error_msg(rules::quoted_tail<rules::one<'"'>>) = "unterminated \"string\"";
error_msg(pegtl::until<rules::field_sep>) = "unterminated text field";
error_msg(rules::value) = "expected value";
error_msg(rules::datablockname) = "unnamed DataBlock";
error_msg(rules::framename) = "unnamed save_ frame";
#undef error_msg
template<typename T> const std::string Errors<T>::msg = "parse error";

// **** parsing actions that fill the storage ****

template<typename Rule> struct Action : pegtl::nothing<Rule> {};

template<> struct Action<rules::datablockname> {
  template<typename Input> static void apply(const Input& in, Document& out) {
    out.blocks.emplace_back(in.string());
    out.items_ = &out.blocks.back().items;
  }
};
template<> struct Action<rules::str_global> {
  template<typename Input> static void apply(const Input&, Document& out) {
    out.blocks.emplace_back();
    out.items_ = &out.blocks.back().items;
  }
};
template<> struct Action<rules::framename> {
  template<typename Input> static void apply(const Input& in, Document& out) {
    out.items_->emplace_back(FrameArg{in.string()});
    out.items_->back().line_number = in.iterator().line;
    out.items_ = &out.items_->back().frame.items;
  }
};
template<> struct Action<rules::endframe> {
  template<typename Input> static void apply(const Input&, Document& out) {
    out.items_ = &out.blocks.back().items;
  }
};
template<> struct Action<rules::tag> {
  template<typename Input> static void apply(const Input& in, Document& out) {
    out.items_->emplace_back(in.string());
    out.items_->back().line_number = in.iterator().line;
  }
};
template<> struct Action<rules::value> {
  template<typename Input> static void apply(const Input& in, Document& out) {
    Item& last_item = out.items_->back();
    assert(last_item.type == ItemType::Pair);
    last_item.pair[1] = in.string();
  }
};
template<> struct Action<rules::str_loop> {
  template<typename Input> static void apply(const Input& in, Document& out) {
    out.items_->emplace_back(LoopArg{});
    out.items_->back().line_number = in.iterator().line;
  }
};
template<> struct Action<rules::loop_tag> {
  template<typename Input> static void apply(const Input& in, Document& out) {
    Item& last_item = out.items_->back();
    assert(last_item.type == ItemType::Loop);
    last_item.loop.tags.emplace_back(in.string());
  }
};
template<> struct Action<rules::loop_value> {
  template<typename Input> static void apply(const Input& in, Document& out) {
    Item& last_item = out.items_->back();
    assert(last_item.type == ItemType::Loop);
    last_item.loop.values.emplace_back(in.string());
  }
};
template<> struct Action<rules::loop> {
  template<typename Input> static void apply(const Input& in, Document& out) {
    Item& last_item = out.items_->back();
    assert(last_item.type == ItemType::Loop);
    const Loop& loop = last_item.loop;
    if (loop.values.size() % loop.tags.size() != 0)
      throw pegtl::parse_error("Wrong number of values in the loop", in);
  }
};

template<typename Input> void parse_input(Document& d, Input&& in) {
  pegtl::parse<rules::file, Action, Errors>(in, d);
  d.source = in.source();
  check_duplicates(d);
}

template<typename Input> Document read_input(Input&& in) {
  Document doc;
  parse_input(doc, in);
  return doc;
}

inline Document read_file(const std::string& filename) {
  pegtl::file_input<> in(filename);
  return read_input(in);
}

inline Document read_string(const std::string& data) {
  pegtl::memory_input<> in(data, "string");
  return read_input(in);
}

inline Document read_memory(const char* data, size_t size, const char* name) {
  pegtl::memory_input<> in(data, size, name);
  return read_input(in);
}

inline Document read_cstream(std::FILE *f, size_t maximum, const char* name) {
  pegtl::cstream_input<> in(f, maximum, name);
  return read_input(in);
}

inline Document read_istream(std::istream &is,
                             size_t maximum, const char* name) {
  pegtl::istream_input<> in(is, maximum, name);
  return read_input(in);
}

template<typename Input> bool check_syntax(Input&& in, std::string* msg) {
  try {
    return pegtl::parse<rules::file, pegtl::nothing, Errors>(in);
  } catch (pegtl::parse_error& e) {
    if (msg)
      *msg = e.what();
    return false;
  }
}

// A function for transparent reading of stdin and/or gzipped files
// in addition to normal CIF files. For example, if used as:
//   Document doc = read(MaybeStdin(argv[1]));
// it reads from stdin if argv[1] is "-", or from a file otherwise.
template<typename T>
Document read(T&& input) {
  if (input.is_stdin())
    return read_cstream(stdin, 16*1024, "stdin");
  if (std::unique_ptr<char[]> mem = input.memory())
    return read_memory(mem.get(), input.mem_size(), input.path().c_str());
  return read_file(input.path());
}

template<typename T>
bool check_syntax_any(T&& input, std::string* msg) {
  if (std::unique_ptr<char[]> mem = input.memory()) {
    pegtl::memory_input<> in(mem.get(), input.mem_size(), input.path());
    return check_syntax(in, msg);
  }
  pegtl::file_input<> in(input.path());
  return check_syntax(in, msg);
}

#if defined(_MSC_VER)
#pragma warning(pop)
#endif

} // namespace cif
} // namespace gemmi
#endif
// vim:sw=2:ts=2:et
<commit_msg>handle incorrect cif files from Refmac dictionary<commit_after>// Copyright 2017 Global Phasing Ltd.
//
// CIF parser (based on PEGTL), struct Document that represents the CIF file,
// and a set of actions for the parser to prepare Document.

#ifndef GEMMI_CIF_HPP_
#define GEMMI_CIF_HPP_
#include <cassert>
#include <cstdio>     // for FILE
#include <iosfwd>     // for size_t, istream
#include <string>

#include <tao/pegtl.hpp>
//#include <tao/pegtl/contrib/tracer.hpp>  // for debugging

#include "cifdoc.hpp" // for Document, etc

#if defined(_MSC_VER)
#pragma warning(push)
// warning C4244: an integer type is converted to a smaller integer type
#pragma warning(disable: 4244)
// warning C4267: conversion from 'size_t' to 'type', possible loss of data
#pragma warning(disable: 4267)
#endif

namespace gemmi {
namespace cif {
using std::size_t;
namespace pegtl = tao::pegtl;

// **** grammar rules, named similarly as in the CIF 1.1 spec ****
namespace rules {

  using namespace pegtl;

  // (letter) refers to sections in Table 2.2.7.1 in Vol.G of ITfC (2006).

  // (g) Character sets.
  // OrdinaryCharacter: ! % &  ()*+,-./0-9:  <=>?@A-Z[]  \ ^  `a-z{|}~

  // !"#$%&'()*+,-./0-9:;<=>?@A-Z[\]^_`a-z{|}~
  struct nonblank_ch : range<'!', '~'> {};

  // ascii space is just before '!'
  struct anyprint_ch : ranges<' ', '~', '\t'> {};

  // (f) White space and comments.
  struct comment : if_must<one<'#'>, until<eolf>> {};
  struct whitespace : plus<sor<one<' ','\n','\r','\t'>, comment>> {};
  struct ws_or_eof : sor<whitespace, pegtl::eof> {};

  // (b) Reserved words.
  struct str_data : TAOCPP_PEGTL_ISTRING("data_") {};
  struct str_loop : TAOCPP_PEGTL_ISTRING("loop_") {};
  struct str_global : TAOCPP_PEGTL_ISTRING("global_") {};
  struct str_save : TAOCPP_PEGTL_ISTRING("save_") {};
  struct str_stop : TAOCPP_PEGTL_ISTRING("stop_") {};
  struct keyword : sor<str_data, str_loop, str_global, str_save, str_stop> {};

  // (e) Character strings and text fields.
  template <typename Q>
  struct endq : seq<Q, at<sor<one<' ','\n','\r','\t','#'>, pegtl::eof>>> {};
  // strict rule would be:
  // template <typename Q> struct quoted_tail : until<endq<Q>, anyprint_ch> {};
  // but it was relaxed after PDB accepted 5q1h with non-ascii character
  template <typename Q> struct quoted_tail : until<endq<Q>, not_one<'\n'>> {};
  template <typename Q> struct quoted : if_must<Q, quoted_tail<Q>> {};
  struct singlequoted : quoted<one<'\''>> {};
  struct doublequoted : quoted<one<'"'>> {};
  struct field_sep : seq<bol, one<';'>> {};
  // CIF 2.0 requires whitespace after text field, so it'd be:
  // until<endq<field_sep>> instead of until<field_sep>.
  struct textfield : if_must<field_sep, until<field_sep>> {};
  struct unquoted : seq<not_at<keyword>, not_at<one<'_','$','#'>>,
                        plus<nonblank_ch>> {};

  // (c) Tags and values.

  // (a) Basic structure of CIF.
  struct datablockname : plus<nonblank_ch> {};
  struct datablockheading : sor<if_must<str_data, datablockname>,
                                str_global> {};
  struct tag : seq<one<'_'>, plus<nonblank_ch>> {};
  // simple unquoted value - for a typical mmCIF file it is faster
  // to check first this risking backtracking.
  struct simunq : seq<plus<ranges<'(', ':', '<', 'Z', 'a', 'z'>>,
                      at<one<' ','\n','\r','\t'>>> {};
  struct value: sor<simunq, singlequoted, doublequoted, textfield, unquoted> {};
  struct loop_tag : tag {};
  struct loop_value : value {};
  struct loop_end : opt<str_stop, ws_or_eof> {};
  struct loop: if_must<str_loop, whitespace,
                                 plus<seq<loop_tag, whitespace, discard>>,
                                 sor<plus<seq<loop_value, ws_or_eof, discard>>,
                                     // handle incorrect CIF with empty loop
                                     at<sor<str_loop, pegtl::eof>>>,
                                 loop_end> {};
  struct dataitem : if_must<tag, whitespace, value, ws_or_eof, discard> {};
  struct framename : plus<nonblank_ch> {};
  struct endframe : str_save {};
  struct frame : if_must<str_save, framename, whitespace,
                         star<sor<dataitem, loop>>,
                         endframe, ws_or_eof> {};
  struct datablock : seq<datablockheading, ws_or_eof,
                         star<sor<dataitem, loop, frame>>> {};
  struct file : must<opt<whitespace>, star<datablock>, pegtl::eof> {};

} // namespace rules

// **** error messages ****

template<typename Rule> struct Errors : public pegtl::normal<Rule> {
  static const std::string msg;

  template<typename Input, typename ... States>
  static void raise(const Input& in, States&& ...) {
    throw pegtl::parse_error(msg, in);
  }
};
#if defined(_MSC_VER)
# define error_msg(x) \
  template<> __declspec(selectany) const std::string Errors<x>::msg
#else
# define error_msg(x) \
  template<> const std::string Errors<x>::msg __attribute__((weak))
#endif
// TODO: error "expected data_ keyword
error_msg(rules::quoted_tail<rules::one<'\''>>) = "unterminated 'string'";
error_msg(rules::quoted_tail<rules::one<'"'>>) = "unterminated \"string\"";
error_msg(pegtl::until<rules::field_sep>) = "unterminated text field";
error_msg(rules::value) = "expected value";
error_msg(rules::datablockname) = "unnamed DataBlock";
error_msg(rules::framename) = "unnamed save_ frame";
#undef error_msg
template<typename T> const std::string Errors<T>::msg = "parse error";

// **** parsing actions that fill the storage ****

template<typename Rule> struct Action : pegtl::nothing<Rule> {};

template<> struct Action<rules::datablockname> {
  template<typename Input> static void apply(const Input& in, Document& out) {
    out.blocks.emplace_back(in.string());
    out.items_ = &out.blocks.back().items;
  }
};
template<> struct Action<rules::str_global> {
  template<typename Input> static void apply(const Input&, Document& out) {
    out.blocks.emplace_back();
    out.items_ = &out.blocks.back().items;
  }
};
template<> struct Action<rules::framename> {
  template<typename Input> static void apply(const Input& in, Document& out) {
    out.items_->emplace_back(FrameArg{in.string()});
    out.items_->back().line_number = in.iterator().line;
    out.items_ = &out.items_->back().frame.items;
  }
};
template<> struct Action<rules::endframe> {
  template<typename Input> static void apply(const Input&, Document& out) {
    out.items_ = &out.blocks.back().items;
  }
};
template<> struct Action<rules::tag> {
  template<typename Input> static void apply(const Input& in, Document& out) {
    out.items_->emplace_back(in.string());
    out.items_->back().line_number = in.iterator().line;
  }
};
template<> struct Action<rules::value> {
  template<typename Input> static void apply(const Input& in, Document& out) {
    Item& last_item = out.items_->back();
    assert(last_item.type == ItemType::Pair);
    last_item.pair[1] = in.string();
  }
};
template<> struct Action<rules::str_loop> {
  template<typename Input> static void apply(const Input& in, Document& out) {
    out.items_->emplace_back(LoopArg{});
    out.items_->back().line_number = in.iterator().line;
  }
};
template<> struct Action<rules::loop_tag> {
  template<typename Input> static void apply(const Input& in, Document& out) {
    Item& last_item = out.items_->back();
    assert(last_item.type == ItemType::Loop);
    last_item.loop.tags.emplace_back(in.string());
  }
};
template<> struct Action<rules::loop_value> {
  template<typename Input> static void apply(const Input& in, Document& out) {
    Item& last_item = out.items_->back();
    assert(last_item.type == ItemType::Loop);
    last_item.loop.values.emplace_back(in.string());
  }
};
template<> struct Action<rules::loop> {
  template<typename Input> static void apply(const Input& in, Document& out) {
    Item& last_item = out.items_->back();
    assert(last_item.type == ItemType::Loop);
    const Loop& loop = last_item.loop;
    if (loop.values.size() % loop.tags.size() != 0)
      throw pegtl::parse_error("Wrong number of values in the loop", in);
  }
};

template<typename Input> void parse_input(Document& d, Input&& in) {
  pegtl::parse<rules::file, Action, Errors>(in, d);
  d.source = in.source();
  check_duplicates(d);
}

template<typename Input> Document read_input(Input&& in) {
  Document doc;
  parse_input(doc, in);
  return doc;
}

inline Document read_file(const std::string& filename) {
  pegtl::file_input<> in(filename);
  return read_input(in);
}

inline Document read_string(const std::string& data) {
  pegtl::memory_input<> in(data, "string");
  return read_input(in);
}

inline Document read_memory(const char* data, size_t size, const char* name) {
  pegtl::memory_input<> in(data, size, name);
  return read_input(in);
}

inline Document read_cstream(std::FILE *f, size_t maximum, const char* name) {
  pegtl::cstream_input<> in(f, maximum, name);
  return read_input(in);
}

inline Document read_istream(std::istream &is,
                             size_t maximum, const char* name) {
  pegtl::istream_input<> in(is, maximum, name);
  return read_input(in);
}

template<typename Input> bool check_syntax(Input&& in, std::string* msg) {
  try {
    return pegtl::parse<rules::file, pegtl::nothing, Errors>(in);
  } catch (pegtl::parse_error& e) {
    if (msg)
      *msg = e.what();
    return false;
  }
}

// A function for transparent reading of stdin and/or gzipped files
// in addition to normal CIF files. For example, if used as:
//   Document doc = read(MaybeStdin(argv[1]));
// it reads from stdin if argv[1] is "-", or from a file otherwise.
template<typename T>
Document read(T&& input) {
  if (input.is_stdin())
    return read_cstream(stdin, 16*1024, "stdin");
  if (std::unique_ptr<char[]> mem = input.memory())
    return read_memory(mem.get(), input.mem_size(), input.path().c_str());
  return read_file(input.path());
}

template<typename T>
bool check_syntax_any(T&& input, std::string* msg) {
  if (std::unique_ptr<char[]> mem = input.memory()) {
    pegtl::memory_input<> in(mem.get(), input.mem_size(), input.path());
    return check_syntax(in, msg);
  }
  pegtl::file_input<> in(input.path());
  return check_syntax(in, msg);
}

#if defined(_MSC_VER)
#pragma warning(pop)
#endif

} // namespace cif
} // namespace gemmi
#endif
// vim:sw=2:ts=2:et
<|endoftext|>


<commit_before>#ifndef LIBICS3_ICS3_CORE_H_
#define LIBICS3_ICS3_CORE_H_

#include <vector>

namespace ics {
  class Core {
  public:
    static const Core &getReference();
    std::vector<unsigned char> &communicate(std::vector<unsigned char>);
  private:
    static const Core INSTANCE;
  };
}

#endif // LIBICS3_ICS3_CORE_H_
<commit_msg>Update Core class for remove static instance<commit_after>#ifndef LIBICS3_ICS3_CORE_H_
#define LIBICS3_ICS3_CORE_H_

#include <vector>

namespace ics {
  class Core {
  public:
    static const Core &getReference();
    std::vector<unsigned char> &communicate(std::vector<unsigned char>);
  private:
  };
}

#endif // LIBICS3_ICS3_CORE_H_
<|endoftext|>


<commit_before>#include <common.cxx>
#include <utility/membitmap.hpp>

CASE( "Empty chunk data means no set bits" )
{
  uint32_t data = 0;
  MemBitmap bmp(&data, sizeof(data) / sizeof(MemBitmap::word));

  EXPECT( bmp.first_set() == -1 );
  EXPECT( bmp.first_free() == 0 );
}
CASE( "All bits set in 32-bits of chunk data" )
{
  uint32_t data = UINT32_MAX;
  MemBitmap bmp(&data, sizeof(data) / sizeof(MemBitmap::word));

  EXPECT( bmp.first_set() ==  0 );
  EXPECT( bmp.last_set()  == 31 );
}
CASE( "Set and verify each individual bit in 32-bits chunk" )
{
  uint32_t data = 0;
  MemBitmap bmp(&data, sizeof(data) / sizeof(MemBitmap::word));

  for (int i = 0; i < 32; i++) {
    bmp.set(i);
    EXPECT( bmp.get(i) == true );
    EXPECT( bmp.last_set() == i );
  }
}
CASE( "Reset and verify each individual bit in 32-bits chunk" )
{
  uint32_t data = UINT32_MAX;
  MemBitmap bmp(&data, sizeof(data) / sizeof(MemBitmap::word));

  for (int i = 0; i < 32; i++) {
    EXPECT( bmp.first_set() == i);
    bmp.reset(i);
    EXPECT( bmp.get(i) == false );
  }
}
CASE( "Verify that the index operator matches get function" )
{
  uint32_t data = 0x12345678;
  MemBitmap bmp(&data, sizeof(data) / sizeof(MemBitmap::word));

  for (int i = 0; i < 32; i++) {
    EXPECT( bmp.get(i) == bmp[i]);
  }
}
CASE( "Verify zeroing the chunk data" )
{
  uint32_t data = 0x12345678;
  MemBitmap bmp(&data, sizeof(data) / sizeof(MemBitmap::word));

  bmp.zero_all();
  EXPECT( bmp.first_set() == -1 );
  EXPECT( bmp.last_set() == -1 );
}
CASE( "Verify flipping bits work" )
{
  uint32_t data = 0;
  MemBitmap bmp(&data, sizeof(data) / sizeof(MemBitmap::word));

  for (int i = 0; i < 32; i++) {
    bmp.flip(i);
    EXPECT( bmp.get(i) == true );
    bmp.flip(i);
    EXPECT( bmp.get(i) == false );
  }
}
CASE( "Verify setting data location works" )
{
  uint32_t data = 0;
  MemBitmap bmp;
  bmp.set_location(&data, sizeof(data) / sizeof(MemBitmap::word));

  EXPECT( bmp.data() == (char*) &data );
  EXPECT( bmp.size() == sizeof(data) );
}
CASE( "Verify size and data for multiple chunks" )
{
  uint32_t data[16];
  MemBitmap bmp(data, sizeof(data) / sizeof(MemBitmap::word));

  EXPECT( bmp.data() == (char*) &data );
  EXPECT( bmp.size() == sizeof(data) );
}

CASE( "Bit-and two bitmaps together" )
{
  uint32_t data1[2] = { 0xFFFFFFFF, 0x0 };
  uint32_t data2[2] = { 0xFFFFFFFF, 0xFFFFFFFF };
  uint32_t data3[2];

  MemBitmap bmp1(data1, sizeof(data1) / sizeof(MemBitmap::word));
  MemBitmap bmp2(data2, sizeof(data2) / sizeof(MemBitmap::word));
  MemBitmap bmp3(data3, sizeof(data3) / sizeof(MemBitmap::word));

  bmp3.set_from_and(bmp1, bmp2);
  EXPECT( bmp3.get_chunk(0) == 0xFFFFFFFF );
  EXPECT( bmp3.get_chunk(1) == 0x0 );

  bmp2 &= bmp1;
  EXPECT( bmp2.get_chunk(0) == 0xFFFFFFFF );
  EXPECT( bmp2.get_chunk(1) == 0x0 );
}
<commit_msg>test: Add set_all for membitmap<commit_after>#include <common.cxx>
#include <utility/membitmap.hpp>

CASE( "Empty chunk data means no set bits" )
{
  uint32_t data = 0;
  MemBitmap bmp(&data, sizeof(data) / sizeof(MemBitmap::word));

  EXPECT( bmp.first_set() == -1 );
  EXPECT( bmp.first_free() == 0 );
}
CASE( "All bits set in 32-bits of chunk data" )
{
  uint32_t data = UINT32_MAX;
  MemBitmap bmp(&data, sizeof(data) / sizeof(MemBitmap::word));

  EXPECT( bmp.first_set() ==  0 );
  EXPECT( bmp.last_set()  == 31 );
}
CASE( "Set and verify each individual bit in 32-bits chunk" )
{
  uint32_t data = 0;
  MemBitmap bmp(&data, sizeof(data) / sizeof(MemBitmap::word));

  for (int i = 0; i < 32; i++) {
    bmp.set(i);
    EXPECT( bmp.get(i) == true );
    EXPECT( bmp.last_set() == i );
  }
}
CASE( "Reset and verify each individual bit in 32-bits chunk" )
{
  uint32_t data = UINT32_MAX;
  MemBitmap bmp(&data, sizeof(data) / sizeof(MemBitmap::word));

  for (int i = 0; i < 32; i++) {
    EXPECT( bmp.first_set() == i);
    bmp.reset(i);
    EXPECT( bmp.get(i) == false );
  }
}
CASE( "Verify that the index operator matches get function" )
{
  uint32_t data = 0x12345678;
  MemBitmap bmp(&data, sizeof(data) / sizeof(MemBitmap::word));

  for (int i = 0; i < 32; i++) {
    EXPECT( bmp.get(i) == bmp[i]);
  }
}
CASE( "Verify zeroing the chunk data" )
{
  uint32_t data = 0x12345678;
  MemBitmap bmp(&data, sizeof(data) / sizeof(MemBitmap::word));

  bmp.zero_all();
  EXPECT( bmp.first_set() == -1 );
  EXPECT( bmp.last_set() == -1 );
}
CASE( "Verify setting all bits in chunk data" )
{
  uint32_t data = 0x12345678;
  MemBitmap bmp(&data, sizeof(data) / sizeof(MemBitmap::word));

  bmp.set_all();
  EXPECT( bmp.first_set() == 0 );
  EXPECT( bmp.last_set() == 31 );
  for (int i = 0; i < 32; i++) {
    EXPECT( bmp.get(i) == true );
  }
}
CASE( "Verify flipping bits work" )
{
  uint32_t data = 0;
  MemBitmap bmp(&data, sizeof(data) / sizeof(MemBitmap::word));

  for (int i = 0; i < 32; i++) {
    bmp.flip(i);
    EXPECT( bmp.get(i) == true );
    bmp.flip(i);
    EXPECT( bmp.get(i) == false );
  }
}
CASE( "Verify setting data location works" )
{
  uint32_t data = 0;
  MemBitmap bmp;
  bmp.set_location(&data, sizeof(data) / sizeof(MemBitmap::word));

  EXPECT( bmp.data() == (char*) &data );
  EXPECT( bmp.size() == sizeof(data) );
}
CASE( "Verify size and data for multiple chunks" )
{
  uint32_t data[16];
  MemBitmap bmp(data, sizeof(data) / sizeof(MemBitmap::word));

  EXPECT( bmp.data() == (char*) &data );
  EXPECT( bmp.size() == sizeof(data) );
}

CASE( "Bit-and two bitmaps together" )
{
  uint32_t data1[2] = { 0xFFFFFFFF, 0x0 };
  uint32_t data2[2] = { 0xFFFFFFFF, 0xFFFFFFFF };
  uint32_t data3[2];

  MemBitmap bmp1(data1, sizeof(data1) / sizeof(MemBitmap::word));
  MemBitmap bmp2(data2, sizeof(data2) / sizeof(MemBitmap::word));
  MemBitmap bmp3(data3, sizeof(data3) / sizeof(MemBitmap::word));

  bmp3.set_from_and(bmp1, bmp2);
  EXPECT( bmp3.get_chunk(0) == 0xFFFFFFFF );
  EXPECT( bmp3.get_chunk(1) == 0x0 );

  bmp2 &= bmp1;
  EXPECT( bmp2.get_chunk(0) == 0xFFFFFFFF );
  EXPECT( bmp2.get_chunk(1) == 0x0 );
}
<|endoftext|>


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

#include <dali-toolkit/dali-toolkit.h>
#include <dali/integration-api/adaptors/adaptor.h>
#include <dali/devel-api/adaptor-framework/application-devel.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>

using namespace Dali::Toolkit;

namespace Dali
{
const char* SCENE_IMAGE_1( DEMO_IMAGE_DIR "gallery-small-10.jpg");
const char* SCENE_IMAGE_2( DEMO_IMAGE_DIR "gallery-small-42.jpg");
const char* SCENE_IMAGE_3( DEMO_IMAGE_DIR "gallery-small-48.jpg");
const char* ROTATE_TEXT("-\\|/");
const float TEXT_HEIGHT = 40.0f;

void AddText( Control textContainer, std::string text, unsigned int yIndex )
{
  auto label = TextLabel::New(text);
  label.SetParentOrigin( ParentOrigin::TOP_CENTER );
  label.SetAnchorPoint( AnchorPoint::TOP_LEFT );
  label.SetSize( 300,TEXT_HEIGHT );
  label.SetY( yIndex*TEXT_HEIGHT );
  textContainer.Add( label );
}

class PreRenderCallbackController : public ConnectionTracker
{
public:

  /**
   * @brief Constructor.
   * @param[in]  application  The application.
   */
  PreRenderCallbackController ( Application& application )
  : mApplication( application ),
    mStage(),
    mTapDetector(),
    mKeepPreRender(false),
    mRotateTextCharacter(0),
    mLastRTC(-1),
    mImageActor1(),
    mImageActor2(),
    mImageActor3(),
    mAngle1Index( Property::INVALID_INDEX ),
    mAngle3Index( Property::INVALID_INDEX ),
    mSceneActor(),
    mSceneAnimation(),
    mSpinner()
  {
    // Connect to the Application's Init signal
    mApplication.InitSignal().Connect( this, &PreRenderCallbackController::Create );
  }

private:
  struct RotationConstraint
  {
    RotationConstraint(float sign)
    : mSign(sign)
    {
    }

    void operator()( Quaternion& current, const PropertyInputContainer& inputs )
    {
      Radian angle( inputs[0]->GetFloat() );
      current = Quaternion( angle * mSign, Vector3::YAXIS );
    }

    float mSign;
  };

  /**
   * @brief Creates the scene.
   */
  void Create( Application& application )
  {
    mStage = Stage::GetCurrent();
    mStage.SetBackgroundColor( Color::WHITE );
    mStage.KeyEventSignal().Connect( this, &PreRenderCallbackController::OnKeyEvent );

    // Hide the indicator bar.
    mApplication.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );

    // Detect taps on the root layer.
    mTapDetector = TapGestureDetector::New();
    mTapDetector.Attach( mStage.GetRootLayer() );
    mTapDetector.DetectedSignal().Connect( this, &PreRenderCallbackController::OnTap );

    CreateAnimatingScene();

    auto textContainer = Control::New();
    textContainer.SetAnchorPoint(AnchorPoint::TOP_LEFT);
    AddText(textContainer, "Click to add callback", 1 );
    AddText(textContainer, "Press 1 to add callback", 2 );
    AddText(textContainer, "Press 2 to clear callback", 3 );
    AddText(textContainer, "Press 3 to toggle keep alive", 4 );

    mSpinner = TextLabel::New("");
    mSpinner.SetAnchorPoint( AnchorPoint::TOP_LEFT );
    mSpinner.SetParentOrigin( ParentOrigin::TOP_LEFT );
    mSpinner.SetSize(100,100);

    mStage.Add(mSpinner);
    mStage.Add(textContainer);

    DevelApplication::AddIdleWithReturnValue( application, MakeCallback( this, &PreRenderCallbackController::OnIdle ) );
  }

  void CreateAnimatingScene()
  {
    mSceneActor = Layer::New();
    mSceneActor.SetBehavior( Layer::LAYER_3D );
    mSceneActor.SetParentOrigin(ParentOrigin::CENTER);

    // Create and add images to the scene actor:
    mImageActor1 = ImageView::New( SCENE_IMAGE_1 );
    mImageActor2 = ImageView::New( SCENE_IMAGE_2 );
    mImageActor3 = ImageView::New( SCENE_IMAGE_3 );

    mImageActor1.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
    mImageActor2.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
    mImageActor3.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );

    mImageActor2.SetParentOrigin(ParentOrigin::CENTER);

    mImageActor1.SetParentOrigin(ParentOrigin::CENTER_LEFT);
    mImageActor1.SetAnchorPoint(AnchorPoint::CENTER_RIGHT);

    mImageActor3.SetParentOrigin(ParentOrigin::CENTER_RIGHT);
    mImageActor3.SetAnchorPoint(AnchorPoint::CENTER_LEFT);

    mSceneActor.Add(mImageActor2);
    mImageActor2.Add(mImageActor1);
    mImageActor2.Add(mImageActor3);

    Property::Index angleIndex = mImageActor2.RegisterProperty("angle", Property::Value( Dali::ANGLE_30 ) );
    Source angleSrc( mImageActor2, angleIndex );

    Constraint constraint = Constraint::New<Quaternion>( mImageActor1, Actor::Property::ORIENTATION, RotationConstraint(-1.0f) );
    constraint.AddSource( angleSrc );
    constraint.Apply();

    constraint = Constraint::New<Quaternion>( mImageActor3, Actor::Property::ORIENTATION, RotationConstraint(+1.0f) );
    constraint.AddSource( angleSrc );
    constraint.Apply();

    mSceneAnimation = Animation::New(2.5f);

    // Want to animate angle from 30 => -30 and back again smoothly.
    mSceneAnimation.AnimateTo( Property( mImageActor2, angleIndex ), Property::Value(-Dali::ANGLE_30), AlphaFunction::SIN );

    mSceneAnimation.SetLooping(true);
    mSceneAnimation.Play();

    mSceneActor.SetSize(250.0f, 250.0f);
    mSceneActor.SetPosition(0.0f, 0.0f, 130.0f);
    Quaternion p( Degree( -6.0f ), Vector3::XAXIS );
    Quaternion q( Degree( 20.0f ), Vector3::YAXIS );
    mSceneActor.SetOrientation( p * q );

    mStage.Add( mSceneActor );
  }

  void OnTap( Actor /* actor */, const TapGesture& /* tap */ )
  {
    Adaptor::Get().SetPreRenderCallback( MakeCallback( this, &PreRenderCallbackController::OnPreRender ) );
  }

  /**
   * @brief Called when any key event is received
   *
   * Will use this to quit the application if Back or the Escape key is received
   * @param[in] event The key event information
   */
  void OnKeyEvent( const KeyEvent& event )
  {
    if( event.state == KeyEvent::Down )
    {
      if ( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) )
      {
        mApplication.Quit();
      }
      else if( event.keyPressedName.compare("1") == 0)
      {
        Adaptor::Get().SetPreRenderCallback( MakeCallback( this, &PreRenderCallbackController::OnPreRender ) );
      }
      else if( event.keyPressedName.compare("2") == 0)
      {
        Adaptor::Get().SetPreRenderCallback( NULL );
      }
      else if( event.keyPressedName.compare("3") == 0)
      {
        mKeepPreRender = !mKeepPreRender;
      }
    }
  }

  bool OnPreRender()
  {
    // Called from Update/Render thread
    printf("Pre-render callback\n");
    ++mRotateTextCharacter;
    return mKeepPreRender;
  }

  bool OnIdle()
  {
    // Called from Event thread on main loop
    int rotation = mRotateTextCharacter;
    if( rotation != mLastRTC )
    {
      mLastRTC = rotation;
      mSpinner.SetProperty(TextLabel::Property::TEXT, std::string(1, ROTATE_TEXT[rotation%4]));
    }
    return true;
  }

private:
  Application& mApplication;
  Stage mStage;
  TapGestureDetector  mTapDetector;          ///< Tap detector to enable the PreRenderCallback
  bool mKeepPreRender;
  int mRotateTextCharacter;
  int mLastRTC;

  // Scene objects:
  ImageView                 mImageActor1;
  ImageView                 mImageActor2;
  ImageView                 mImageActor3;
  Property::Index           mAngle1Index;
  Property::Index           mAngle3Index;
  Layer                     mSceneActor;
  Animation                 mSceneAnimation;
  TextLabel                 mSpinner;
};

} // namespace Dali

int main( int argc, char **argv )
{
  Dali::Application application = Dali::Application::New( &argc, &argv );
  Dali::PreRenderCallbackController controller( application );
  application.MainLoop();
  return 0;
}
<commit_msg>Changes after adaptor integration-api folder move<commit_after>/*
 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <dali-toolkit/dali-toolkit.h>
#include <dali/integration-api/adaptor-framework/adaptor.h>
#include <dali/devel-api/adaptor-framework/application-devel.h>
#include <dali-toolkit/devel-api/controls/control-devel.h>

using namespace Dali::Toolkit;

namespace Dali
{
const char* SCENE_IMAGE_1( DEMO_IMAGE_DIR "gallery-small-10.jpg");
const char* SCENE_IMAGE_2( DEMO_IMAGE_DIR "gallery-small-42.jpg");
const char* SCENE_IMAGE_3( DEMO_IMAGE_DIR "gallery-small-48.jpg");
const char* ROTATE_TEXT("-\\|/");
const float TEXT_HEIGHT = 40.0f;

void AddText( Control textContainer, std::string text, unsigned int yIndex )
{
  auto label = TextLabel::New(text);
  label.SetParentOrigin( ParentOrigin::TOP_CENTER );
  label.SetAnchorPoint( AnchorPoint::TOP_LEFT );
  label.SetSize( 300,TEXT_HEIGHT );
  label.SetY( yIndex*TEXT_HEIGHT );
  textContainer.Add( label );
}

class PreRenderCallbackController : public ConnectionTracker
{
public:

  /**
   * @brief Constructor.
   * @param[in]  application  The application.
   */
  PreRenderCallbackController ( Application& application )
  : mApplication( application ),
    mStage(),
    mTapDetector(),
    mKeepPreRender(false),
    mRotateTextCharacter(0),
    mLastRTC(-1),
    mImageActor1(),
    mImageActor2(),
    mImageActor3(),
    mAngle1Index( Property::INVALID_INDEX ),
    mAngle3Index( Property::INVALID_INDEX ),
    mSceneActor(),
    mSceneAnimation(),
    mSpinner()
  {
    // Connect to the Application's Init signal
    mApplication.InitSignal().Connect( this, &PreRenderCallbackController::Create );
  }

private:
  struct RotationConstraint
  {
    RotationConstraint(float sign)
    : mSign(sign)
    {
    }

    void operator()( Quaternion& current, const PropertyInputContainer& inputs )
    {
      Radian angle( inputs[0]->GetFloat() );
      current = Quaternion( angle * mSign, Vector3::YAXIS );
    }

    float mSign;
  };

  /**
   * @brief Creates the scene.
   */
  void Create( Application& application )
  {
    mStage = Stage::GetCurrent();
    mStage.SetBackgroundColor( Color::WHITE );
    mStage.KeyEventSignal().Connect( this, &PreRenderCallbackController::OnKeyEvent );

    // Hide the indicator bar.
    mApplication.GetWindow().ShowIndicator( Dali::Window::INVISIBLE );

    // Detect taps on the root layer.
    mTapDetector = TapGestureDetector::New();
    mTapDetector.Attach( mStage.GetRootLayer() );
    mTapDetector.DetectedSignal().Connect( this, &PreRenderCallbackController::OnTap );

    CreateAnimatingScene();

    auto textContainer = Control::New();
    textContainer.SetAnchorPoint(AnchorPoint::TOP_LEFT);
    AddText(textContainer, "Click to add callback", 1 );
    AddText(textContainer, "Press 1 to add callback", 2 );
    AddText(textContainer, "Press 2 to clear callback", 3 );
    AddText(textContainer, "Press 3 to toggle keep alive", 4 );

    mSpinner = TextLabel::New("");
    mSpinner.SetAnchorPoint( AnchorPoint::TOP_LEFT );
    mSpinner.SetParentOrigin( ParentOrigin::TOP_LEFT );
    mSpinner.SetSize(100,100);

    mStage.Add(mSpinner);
    mStage.Add(textContainer);

    DevelApplication::AddIdleWithReturnValue( application, MakeCallback( this, &PreRenderCallbackController::OnIdle ) );
  }

  void CreateAnimatingScene()
  {
    mSceneActor = Layer::New();
    mSceneActor.SetBehavior( Layer::LAYER_3D );
    mSceneActor.SetParentOrigin(ParentOrigin::CENTER);

    // Create and add images to the scene actor:
    mImageActor1 = ImageView::New( SCENE_IMAGE_1 );
    mImageActor2 = ImageView::New( SCENE_IMAGE_2 );
    mImageActor3 = ImageView::New( SCENE_IMAGE_3 );

    mImageActor1.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
    mImageActor2.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );
    mImageActor3.SetResizePolicy( ResizePolicy::USE_NATURAL_SIZE, Dimension::ALL_DIMENSIONS );

    mImageActor2.SetParentOrigin(ParentOrigin::CENTER);

    mImageActor1.SetParentOrigin(ParentOrigin::CENTER_LEFT);
    mImageActor1.SetAnchorPoint(AnchorPoint::CENTER_RIGHT);

    mImageActor3.SetParentOrigin(ParentOrigin::CENTER_RIGHT);
    mImageActor3.SetAnchorPoint(AnchorPoint::CENTER_LEFT);

    mSceneActor.Add(mImageActor2);
    mImageActor2.Add(mImageActor1);
    mImageActor2.Add(mImageActor3);

    Property::Index angleIndex = mImageActor2.RegisterProperty("angle", Property::Value( Dali::ANGLE_30 ) );
    Source angleSrc( mImageActor2, angleIndex );

    Constraint constraint = Constraint::New<Quaternion>( mImageActor1, Actor::Property::ORIENTATION, RotationConstraint(-1.0f) );
    constraint.AddSource( angleSrc );
    constraint.Apply();

    constraint = Constraint::New<Quaternion>( mImageActor3, Actor::Property::ORIENTATION, RotationConstraint(+1.0f) );
    constraint.AddSource( angleSrc );
    constraint.Apply();

    mSceneAnimation = Animation::New(2.5f);

    // Want to animate angle from 30 => -30 and back again smoothly.
    mSceneAnimation.AnimateTo( Property( mImageActor2, angleIndex ), Property::Value(-Dali::ANGLE_30), AlphaFunction::SIN );

    mSceneAnimation.SetLooping(true);
    mSceneAnimation.Play();

    mSceneActor.SetSize(250.0f, 250.0f);
    mSceneActor.SetPosition(0.0f, 0.0f, 130.0f);
    Quaternion p( Degree( -6.0f ), Vector3::XAXIS );
    Quaternion q( Degree( 20.0f ), Vector3::YAXIS );
    mSceneActor.SetOrientation( p * q );

    mStage.Add( mSceneActor );
  }

  void OnTap( Actor /* actor */, const TapGesture& /* tap */ )
  {
    Adaptor::Get().SetPreRenderCallback( MakeCallback( this, &PreRenderCallbackController::OnPreRender ) );
  }

  /**
   * @brief Called when any key event is received
   *
   * Will use this to quit the application if Back or the Escape key is received
   * @param[in] event The key event information
   */
  void OnKeyEvent( const KeyEvent& event )
  {
    if( event.state == KeyEvent::Down )
    {
      if ( IsKey( event, Dali::DALI_KEY_ESCAPE ) || IsKey( event, Dali::DALI_KEY_BACK ) )
      {
        mApplication.Quit();
      }
      else if( event.keyPressedName.compare("1") == 0)
      {
        Adaptor::Get().SetPreRenderCallback( MakeCallback( this, &PreRenderCallbackController::OnPreRender ) );
      }
      else if( event.keyPressedName.compare("2") == 0)
      {
        Adaptor::Get().SetPreRenderCallback( NULL );
      }
      else if( event.keyPressedName.compare("3") == 0)
      {
        mKeepPreRender = !mKeepPreRender;
      }
    }
  }

  bool OnPreRender()
  {
    // Called from Update/Render thread
    printf("Pre-render callback\n");
    ++mRotateTextCharacter;
    return mKeepPreRender;
  }

  bool OnIdle()
  {
    // Called from Event thread on main loop
    int rotation = mRotateTextCharacter;
    if( rotation != mLastRTC )
    {
      mLastRTC = rotation;
      mSpinner.SetProperty(TextLabel::Property::TEXT, std::string(1, ROTATE_TEXT[rotation%4]));
    }
    return true;
  }

private:
  Application& mApplication;
  Stage mStage;
  TapGestureDetector  mTapDetector;          ///< Tap detector to enable the PreRenderCallback
  bool mKeepPreRender;
  int mRotateTextCharacter;
  int mLastRTC;

  // Scene objects:
  ImageView                 mImageActor1;
  ImageView                 mImageActor2;
  ImageView                 mImageActor3;
  Property::Index           mAngle1Index;
  Property::Index           mAngle3Index;
  Layer                     mSceneActor;
  Animation                 mSceneAnimation;
  TextLabel                 mSpinner;
};

} // namespace Dali

int main( int argc, char **argv )
{
  Dali::Application application = Dali::Application::New( &argc, &argv );
  Dali::PreRenderCallbackController controller( application );
  application.MainLoop();
  return 0;
}
<|endoftext|>