<commit_before>/*************************************************************************
 *                                                                       *
 * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith.       *
 * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
 *                                                                       *
 * This library is free software; you can redistribute it and/or         *
 * modify it under the terms of EITHER:                                  *
 *   (1) The GNU Lesser General Public License as published by the Free  *
 *       Software Foundation; either version 2.1 of the License, or (at  *
 *       your option) any later version. The text of the GNU Lesser      *
 *       General Public License is included with this library in the     *
 *       file LICENSE.TXT.                                               *
 *   (2) The BSD-style license that is included with this library in     *
 *       the file LICENSE-BSD.TXT.                                       *
 *                                                                       *
 * This library is distributed in the hope that it will be useful,       *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
 * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
 *                                                                       *
 *************************************************************************/

// TriMesh code by Erwin de Vries.

#include <ode/collision.h>
#include <ode/matrix.h>
#include <ode/rotation.h>
#include <ode/odemath.h>
#include "collision_util.h"

#define TRIMESH_INTERNAL
#include "collision_trimesh_internal.h"

int dCollideRTL(dxGeom* g1, dxGeom* RayGeom, int Flags, dContactGeom* Contacts, int Stride){
	dxTriMesh* TriMesh = (dxTriMesh*)g1;

	const dVector3& TLPosition = *(const dVector3*)dGeomGetPosition(TriMesh);
	const dMatrix3& TLRotation = *(const dMatrix3*)dGeomGetRotation(TriMesh);

	RayCollider& Collider = TriMesh->_RayCollider;

	dReal Length = dGeomRayGetLength(RayGeom);

	int FirstContact, BackfaceCull;
	dGeomRayGetParams(RayGeom, &FirstContact, &BackfaceCull);
	int ClosestHit = dGeomRayGetClosestHit(RayGeom);

	Collider.SetFirstContact(FirstContact != 0);
	Collider.SetClosestHit(ClosestHit != 0);
	Collider.SetCulling(BackfaceCull != 0);
	Collider.SetMaxDist(Length);

	dVector3 Origin, Direction;
	dGeomRayGet(RayGeom, Origin, Direction);

	/* Make Ray */
	Ray WorldRay;
	WorldRay.mOrig.x = Origin[0];
	WorldRay.mOrig.y = Origin[1];
	WorldRay.mOrig.z = Origin[2];
	WorldRay.mDir.x = Direction[0];
	WorldRay.mDir.y = Direction[1];
	WorldRay.mDir.z = Direction[2];

	/* Intersect */
	Matrix4x4 amatrix;
	Collider.Collide(WorldRay, TriMesh->Data->BVTree, &MakeMatrix(TLPosition, TLRotation, amatrix));

	/* Retrieve data */
	int TriCount = TriMesh->Faces.GetNbFaces();

	if (TriCount != 0){
		const CollisionFace* Faces = TriMesh->Faces.GetFaces();

		int OutTriCount = 0;
		for (int i = 0; i < TriCount; i++){
			if (OutTriCount == (Flags & 0xffff)){
				break;
			}

			if (TriMesh->RayCallback == null || TriMesh->RayCallback(TriMesh, RayGeom, Faces[i].mFaceID, Faces[i].mU, Faces[i].mV)){
				const int& TriIndex = Faces[i].mFaceID;

				if (!Callback(TriMesh, RayGeom, TriIndex)) continue;

				dContactGeom* Contact = SAFECONTACT(Flags, Contacts, OutTriCount, Stride);

				dVector3 dv[3];
				FetchTriangle(TriMesh, TriIndex, TLPosition, TLRotation, dv);

				float T = Faces[i].mDistance;
				Contact->pos[0] = Origin[0] + (Direction[0] * T);
				Contact->pos[1] = Origin[1] + (Direction[1] * T);
				Contact->pos[2] = Origin[2] + (Direction[2] * T);
				Contact->pos[3] = REAL(0.0);

				dVector3 vu;
				vu[0] = dv[1][0] - dv[0][0];
				vu[1] = dv[1][1] - dv[0][1];
				vu[2] = dv[1][2] - dv[0][2];
				vu[3] = REAL(0.0);

				dVector3 vv;
				vv[0] = dv[2][0] - dv[0][0];
				vv[1] = dv[2][1] - dv[0][1];
				vv[2] = dv[2][2] - dv[0][2];
				vv[3] = REAL(0.0);

				dCROSS(Contact->normal, =, vv, vu);	// Reversed

				dNormalize3(Contact->normal);

				Contact->depth = T;
				Contact->g1 = TriMesh;
				Contact->g2 = RayGeom;

				OutTriCount++;
			}
		}
		return OutTriCount;
	}
	else return 0;
}
<commit_msg>ray-triangle collider correctness fix from Joe Ante <joe@uti.is><commit_after>/*************************************************************************
 *                                                                       *
 * Open Dynamics Engine, Copyright (C) 2001-2003 Russell L. Smith.       *
 * All rights reserved.  Email: russ@q12.org   Web: www.q12.org          *
 *                                                                       *
 * This library is free software; you can redistribute it and/or         *
 * modify it under the terms of EITHER:                                  *
 *   (1) The GNU Lesser General Public License as published by the Free  *
 *       Software Foundation; either version 2.1 of the License, or (at  *
 *       your option) any later version. The text of the GNU Lesser      *
 *       General Public License is included with this library in the     *
 *       file LICENSE.TXT.                                               *
 *   (2) The BSD-style license that is included with this library in     *
 *       the file LICENSE-BSD.TXT.                                       *
 *                                                                       *
 * This library is distributed in the hope that it will be useful,       *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files    *
 * LICENSE.TXT and LICENSE-BSD.TXT for more details.                     *
 *                                                                       *
 *************************************************************************/

// TriMesh code by Erwin de Vries.

#include <ode/collision.h>
#include <ode/matrix.h>
#include <ode/rotation.h>
#include <ode/odemath.h>
#include "collision_util.h"

#define TRIMESH_INTERNAL
#include "collision_trimesh_internal.h"

int dCollideRTL(dxGeom* g1, dxGeom* RayGeom, int Flags, dContactGeom* Contacts, int Stride){
	dxTriMesh* TriMesh = (dxTriMesh*)g1;

	const dVector3& TLPosition = *(const dVector3*)dGeomGetPosition(TriMesh);
	const dMatrix3& TLRotation = *(const dMatrix3*)dGeomGetRotation(TriMesh);

	RayCollider& Collider = TriMesh->_RayCollider;

	dReal Length = dGeomRayGetLength(RayGeom);

	int FirstContact, BackfaceCull;
	dGeomRayGetParams(RayGeom, &FirstContact, &BackfaceCull);
	int ClosestHit = dGeomRayGetClosestHit(RayGeom);

	Collider.SetFirstContact(FirstContact != 0);
	Collider.SetClosestHit(ClosestHit != 0);
	Collider.SetCulling(BackfaceCull != 0);
	Collider.SetMaxDist(Length);

	dVector3 Origin, Direction;
	dGeomRayGet(RayGeom, Origin, Direction);

	/* Make Ray */
	Ray WorldRay;
	WorldRay.mOrig.x = Origin[0];
	WorldRay.mOrig.y = Origin[1];
	WorldRay.mOrig.z = Origin[2];
	WorldRay.mDir.x = Direction[0];
	WorldRay.mDir.y = Direction[1];
	WorldRay.mDir.z = Direction[2];

	/* Intersect */
	Matrix4x4 amatrix;
        int TriCount = 0;
        if (Collider.Collide(WorldRay, TriMesh->Data->BVTree, &MakeMatrix(TLPosition, TLRotation, amatrix))) {
                TriCount = TriMesh->Faces.GetNbFaces();
        }

        if (TriCount == 0) {
                return 0;
        }

	const CollisionFace* Faces = TriMesh->Faces.GetFaces();

	int OutTriCount = 0;
	for (int i = 0; i < TriCount; i++) {
		if (OutTriCount == (Flags & 0xffff)) {
			break;
		}
		if (TriMesh->RayCallback == null ||
                    TriMesh->RayCallback(TriMesh, RayGeom, Faces[i].mFaceID,
                                         Faces[i].mU, Faces[i].mV)) {
			const int& TriIndex = Faces[i].mFaceID;
			if (!Callback(TriMesh, RayGeom, TriIndex)) {
                                continue;
                        }

			dContactGeom* Contact = SAFECONTACT(Flags, Contacts, OutTriCount, Stride);

			dVector3 dv[3];
			FetchTriangle(TriMesh, TriIndex, TLPosition, TLRotation, dv);

			float T = Faces[i].mDistance;
			Contact->pos[0] = Origin[0] + (Direction[0] * T);
			Contact->pos[1] = Origin[1] + (Direction[1] * T);
			Contact->pos[2] = Origin[2] + (Direction[2] * T);
			Contact->pos[3] = REAL(0.0);

			dVector3 vu;
			vu[0] = dv[1][0] - dv[0][0];
			vu[1] = dv[1][1] - dv[0][1];
			vu[2] = dv[1][2] - dv[0][2];
			vu[3] = REAL(0.0);

			dVector3 vv;
			vv[0] = dv[2][0] - dv[0][0];
			vv[1] = dv[2][1] - dv[0][1];
			vv[2] = dv[2][2] - dv[0][2];
			vv[3] = REAL(0.0);

			dCROSS(Contact->normal, =, vv, vu);	// Reversed

			dNormalize3(Contact->normal);

			Contact->depth = T;
			Contact->g1 = TriMesh;
			Contact->g2 = RayGeom;

			OutTriCount++;
		}
	}
	return OutTriCount;
}
<|endoftext|>


<commit_before>/* =======================================================================
   Copyright (c) 2011, Institute for Microelectronics, TU Wien
   http://www.iue.tuwien.ac.at
                             -----------------
           ViennaFVM - The Vienna Finite Volume Method Library
                             -----------------

   authors:    Karl Rupp                          rupp@iue.tuwien.ac.at
               (add your name here)

   license:    To be discussed, see file LICENSE in the ViennaFVM base directory
======================================================================= */

// include necessary system headers
#include <iostream>

#define VIENNAFVM_DEBUG

// ViennaFVM includes:
#include "viennafvm/forwards.h"
//#include "viennafvm/poisson_assembler.hpp"
#include "viennafvm/linear_assembler.hpp"
#include "viennafvm/io/vtk_writer.hpp"
#include "viennafvm/ncell_quantity.hpp"
#include "viennafvm/linear_solve.hpp"
#include "viennafvm/pde_solver.hpp"

// ViennaGrid includes:
#include "viennagrid/domain/domain.hpp"
#include "viennagrid/config/default_configs.hpp"
#include "viennagrid/io/netgen_reader.hpp"
#include "viennagrid/io/vtk_writer.hpp"
#include "viennagrid/algorithm/voronoi.hpp"

// ViennaData includes:
#include "viennadata/api.hpp"

// ViennaMath includes:
#include "viennamath/expression.hpp"

#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/matrix_sparse.hpp>
#include <boost/numeric/ublas/operation.hpp>
#include <boost/numeric/ublas/operation_sparse.hpp>

struct permittivity_key
{
  // Operator< is required for compatibility with std::map
  bool operator<(permittivity_key const & /*other*/) const { return false; }
};

int main()
{
  typedef double   numeric_type;

  typedef viennagrid::tetrahedral_3d_domain   DomainType;
  typedef viennagrid::result_of::segmentation<DomainType>::type SegmentationType;

  typedef viennagrid::result_of::cell_tag<DomainType>::type CellTag;

  typedef viennagrid::result_of::element<DomainType, CellTag>::type        CellType;

  typedef viennamath::function_symbol   FunctionSymbol;
  typedef viennamath::equation          Equation;

  typedef viennadata::storage<> StorageType;

  typedef viennagrid::result_of::element_range<DomainType, CellTag>::type  CellContainer;
  typedef viennagrid::result_of::iterator<CellContainer>::type                CellIterator;
  typedef viennagrid::result_of::vertex_range<CellType>::type               VertexOnCellContainer;
  typedef viennagrid::result_of::iterator<VertexOnCellContainer>::type        VertexOnCellIterator;

  typedef viennamath::function_symbol   FunctionSymbol;
  typedef viennamath::equation          Equation;

  typedef viennafvm::boundary_key      BoundaryKey;

  //
  // Create a domain from file
  //
  DomainType domain;
  SegmentationType segmentation(domain);
  StorageType storage/**/;

  try
  {
    viennagrid::io::netgen_reader my_netgen_reader;
    my_netgen_reader(domain, segmentation, "../examples/data/cube3072.mesh");
  }
  catch (...)
  {
    std::cerr << "File-Reader failed. Aborting program..." << std::endl;
    return EXIT_FAILURE;
  }

  // Specify Poisson equation:
  viennafvm::ncell_quantity<CellType, viennamath::expr::interface_type>  permittivity; permittivity.wrap_constant( storage, permittivity_key() );

  FunctionSymbol u(0, viennamath::unknown_tag<>());   //an unknown function used for PDE specification
  Equation poisson_eq = viennamath::make_equation( viennamath::div(permittivity * viennamath::grad(u)), -1);  // \Delta u = -1

  //
  // Setting boundary information on domain (this should come from device specification)
  //
  //setting some boundary flags:

  viennagrid::result_of::default_point_accessor<DomainType>::type point_accessor = viennagrid::default_point_accessor(domain);

  viennadata::result_of::accessor<StorageType, permittivity_key, double, CellType>::type permittivity_accessor =
      viennadata::accessor<permittivity_key, double, CellType>(storage, permittivity_key());

  viennadata::result_of::accessor<StorageType, BoundaryKey, bool, CellType>::type boundary_accessor =
      viennadata::accessor<BoundaryKey, bool, CellType>(storage, BoundaryKey( u.id() ));

  CellContainer cells = viennagrid::elements(domain);
  for (CellIterator cit  = cells.begin();
                    cit != cells.end();
                  ++cit)
  {
    bool cell_on_boundary = false;

    // write dummy permittivity to cells:
    permittivity_accessor(*cit) = 1.0;

    VertexOnCellContainer vertices = viennagrid::elements(*cit);
    for (VertexOnCellIterator vit  = vertices.begin();
                              vit != vertices.end();
                            ++vit)
    {
      //boundary for first equation: Homogeneous Dirichlet everywhere
      if (point_accessor(*vit)[0] == 0.0 || point_accessor(*vit)[0] == 1.0
        || point_accessor(*vit)[2] == 0.0 || point_accessor(*vit)[2] == 1.0 )
      {
        cell_on_boundary = true;
        break;
      }
    }
    boundary_accessor(*cit) = cell_on_boundary;
  }

  //
  // Create PDE solver instance
  //
  viennafvm::pde_solver<> pde_solver;

  //
  // Pass system to solver:
  //
  pde_solver(viennafvm::make_linear_pde_system(poisson_eq, u),  // PDE with associated unknown
             domain,
             storage);

  //
  // Writing solution back to domain (discussion about proper way of returning a solution required...)
  //
  viennafvm::io::write_solution_to_VTK_file(pde_solver.result(), "poisson_3d", domain, segmentation, storage, 0);

  std::cout << "*****************************************" << std::endl;
  std::cout << "* Poisson solver finished successfully! *" << std::endl;
  std::cout << "*****************************************" << std::endl;
  return EXIT_SUCCESS;
}
<commit_msg>Removed unnecessary comment, removed duplicate typedef<commit_after>/* =======================================================================
   Copyright (c) 2011, Institute for Microelectronics, TU Wien
   http://www.iue.tuwien.ac.at
                             -----------------
           ViennaFVM - The Vienna Finite Volume Method Library
                             -----------------

   authors:    Karl Rupp                          rupp@iue.tuwien.ac.at
               (add your name here)

   license:    To be discussed, see file LICENSE in the ViennaFVM base directory
======================================================================= */

// include necessary system headers
#include <iostream>

#define VIENNAFVM_DEBUG

// ViennaFVM includes:
#include "viennafvm/forwards.h"
//#include "viennafvm/poisson_assembler.hpp"
#include "viennafvm/linear_assembler.hpp"
#include "viennafvm/io/vtk_writer.hpp"
#include "viennafvm/ncell_quantity.hpp"
#include "viennafvm/linear_solve.hpp"
#include "viennafvm/pde_solver.hpp"

// ViennaGrid includes:
#include "viennagrid/domain/domain.hpp"
#include "viennagrid/config/default_configs.hpp"
#include "viennagrid/io/netgen_reader.hpp"
#include "viennagrid/io/vtk_writer.hpp"
#include "viennagrid/algorithm/voronoi.hpp"

// ViennaData includes:
#include "viennadata/api.hpp"

// ViennaMath includes:
#include "viennamath/expression.hpp"

#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/matrix_sparse.hpp>
#include <boost/numeric/ublas/operation.hpp>
#include <boost/numeric/ublas/operation_sparse.hpp>

struct permittivity_key
{
  // Operator< is required for compatibility with std::map
  bool operator<(permittivity_key const & /*other*/) const { return false; }
};

int main()
{
  typedef double   numeric_type;

  typedef viennagrid::tetrahedral_3d_domain   DomainType;
  typedef viennagrid::result_of::segmentation<DomainType>::type SegmentationType;

  typedef viennagrid::result_of::cell_tag<DomainType>::type CellTag;

  typedef viennagrid::result_of::element<DomainType, CellTag>::type        CellType;

  typedef viennadata::storage<> StorageType;

  typedef viennagrid::result_of::element_range<DomainType, CellTag>::type  CellContainer;
  typedef viennagrid::result_of::iterator<CellContainer>::type                CellIterator;
  typedef viennagrid::result_of::vertex_range<CellType>::type               VertexOnCellContainer;
  typedef viennagrid::result_of::iterator<VertexOnCellContainer>::type        VertexOnCellIterator;

  typedef viennamath::function_symbol   FunctionSymbol;
  typedef viennamath::equation          Equation;

  typedef viennafvm::boundary_key      BoundaryKey;

  //
  // Create a domain from file
  //
  DomainType domain;
  SegmentationType segmentation(domain);
  StorageType storage;

  try
  {
    viennagrid::io::netgen_reader my_netgen_reader;
    my_netgen_reader(domain, segmentation, "../examples/data/cube3072.mesh");
  }
  catch (...)
  {
    std::cerr << "File-Reader failed. Aborting program..." << std::endl;
    return EXIT_FAILURE;
  }

  // Specify Poisson equation:
  viennafvm::ncell_quantity<CellType, viennamath::expr::interface_type>  permittivity; permittivity.wrap_constant( storage, permittivity_key() );

  FunctionSymbol u(0, viennamath::unknown_tag<>());   //an unknown function used for PDE specification
  Equation poisson_eq = viennamath::make_equation( viennamath::div(permittivity * viennamath::grad(u)), -1);  // \Delta u = -1

  //
  // Setting boundary information on domain (this should come from device specification)
  //
  //setting some boundary flags:

  viennagrid::result_of::default_point_accessor<DomainType>::type point_accessor = viennagrid::default_point_accessor(domain);

  viennadata::result_of::accessor<StorageType, permittivity_key, double, CellType>::type permittivity_accessor =
      viennadata::accessor<permittivity_key, double, CellType>(storage, permittivity_key());

  viennadata::result_of::accessor<StorageType, BoundaryKey, bool, CellType>::type boundary_accessor =
      viennadata::accessor<BoundaryKey, bool, CellType>(storage, BoundaryKey( u.id() ));

  CellContainer cells = viennagrid::elements(domain);
  for (CellIterator cit  = cells.begin();
                    cit != cells.end();
                  ++cit)
  {
    bool cell_on_boundary = false;

    // write dummy permittivity to cells:
    permittivity_accessor(*cit) = 1.0;

    VertexOnCellContainer vertices = viennagrid::elements(*cit);
    for (VertexOnCellIterator vit  = vertices.begin();
                              vit != vertices.end();
                            ++vit)
    {
      //boundary for first equation: Homogeneous Dirichlet everywhere
      if (point_accessor(*vit)[0] == 0.0 || point_accessor(*vit)[0] == 1.0
        || point_accessor(*vit)[2] == 0.0 || point_accessor(*vit)[2] == 1.0 )
      {
        cell_on_boundary = true;
        break;
      }
    }
    boundary_accessor(*cit) = cell_on_boundary;
  }

  //
  // Create PDE solver instance
  //
  viennafvm::pde_solver<> pde_solver;

  //
  // Pass system to solver:
  //
  pde_solver(viennafvm::make_linear_pde_system(poisson_eq, u),  // PDE with associated unknown
             domain,
             storage);

  //
  // Writing solution back to domain (discussion about proper way of returning a solution required...)
  //
  viennafvm::io::write_solution_to_VTK_file(pde_solver.result(), "poisson_3d", domain, segmentation, storage, 0);

  std::cout << "*****************************************" << std::endl;
  std::cout << "* Poisson solver finished successfully! *" << std::endl;
  std::cout << "*****************************************" << std::endl;
  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>/** @file tutorialAdaptiveCDR.cpp

    @brief Tutorial on how to use G+Smo to solve a convection-diffusion-reaction problem.

    This file is part of the G+Smo library.

    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
    file, You can obtain one at http://mozilla.org/MPL/2.0/.

    Author(s): S. Kleiss
*/

//! [Include namespace]
# include <gismo.h>
# include <gsAssembler/gsAdaptiveRefUtils.h>

using namespace std;
using namespace gismo;
//! [Include namespace]

int main(int argc, char *argv[])
{
    //! [Parse command line]
    bool plot = false;

    gsCmdLine cmd("Example for solving a convection-diffusion problem.");
    cmd.addSwitch("plot", "Create a ParaView visualization file with the solution", plot);
    const bool ok = cmd.getValues(argc,argv);
    if (!ok) { gsWarn << "Error during parsing the command line!\n"; return 0;}
    //! [Parse command line]

    // --------------- specify exact solution and right-hand-side ---------------

    //! [Function data]
    // Define exact solution (will be used for specifying Dirichlet boundary conditions
    //gsFunctionExpr<> g("if( y<-x/2-1/2, 1, 0 )", 2);
    gsFunctionExpr<> g("if( y>=0, if( x <=-1, 1, 0 ), 0 )", 2);
    // Define source function
    gsFunctionExpr<> rhs("0",2);

    // diffusion coefficient:
    gsFunctionExpr<> coeff_diff("0.000001","0","0","0.000001",2);
    // convection coefficient:
    gsFunctionExpr<> coeff_conv("3/sqrt(13)","-2/sqrt(13)",2);
    // reaction coefficient:
    gsFunctionExpr<> coeff_reac("0",2);
    //! [Function data]

    // Print out source function and solution
    gsInfo<<"Source function " << rhs << "\n";
    gsInfo<<"Dirichlet boundary conditions "  << g << "\n\n";

    // --------------- read geometry from file ---------------

    // Read geometry from file (full path needed, or
    // GISMO_DATA_DIR macro which leads to the "filedata" directory
    //! [GetGeometryData]
    // Read xml and create gsMultiPatch
    string fileSrc( GISMO_DATA_DIR "/planar/lshape2d_3patches_thb.xml" );
    gsMultiPatch<real_t> patches;
    gsReadFile<real_t>( fileSrc, patches);
    //! [GetGeometryData]
    gsInfo << "The domain is a "<< patches <<"\n";

    //! [computeTopology]
    // Get all interfaces and boundaries:
    patches.computeTopology();
    //! [computeTopology]

    // --------------- add bonudary conditions ---------------
    //! [Boundary conditions]
    gsBoundaryConditions<> bcInfo;

    // For simplicity, set Dirichlet boundary conditions
    // given by exact solution g on all boundaries:
    for ( gsMultiPatch<>::const_biterator
             bit = patches.bBegin(); bit != patches.bEnd(); ++bit)
    {
        bcInfo.addCondition( *bit, condition_type::dirichlet, &g );
    }
    //! [Boundary conditions]

    // --------------- define Pde ---------------
    //! [definePde]
    gsConvDiffRePde<real_t> cdrPde(patches, bcInfo, & coeff_diff,& coeff_conv, & coeff_reac, & rhs);
    //! [definePde]

    // --------------- set up basis ---------------

    //! [GetBasisFromTHB]
    // Copy basis from the geometry
    gsMultiBasis<> bases( patches );
    //! [GetBasisFromTHB]

    //! [initialRefinements]
    // Number of initial uniform refinement steps:
    int numInitUniformRefine  = 2;

    for (int i = 0; i < numInitUniformRefine; ++i)
      bases.uniformRefine();
    //! [initialRefinements]

    // --------------- set up adaptive refinement loop ---------------

    //! [adaptRefSettings]
    // Number of refinement loops to be done
    int numRefinementLoops = 4;

    // Specify cell-marking strategy...
    MarkingStrategy adaptRefCrit = PUCA;
//    MarkingStrategy adaptRefCrit = GARU;
//    MarkingStrategy adaptRefCrit = errorFraction;

    // ... and parameter.
    const real_t adaptRefParam = 0.7;

    //! [adaptRefSettings]

    //! [constructAssembler]
    // Construct assembler
    gsCDRAssembler<real_t> cdrAss( cdrPde, bases);
    // Set stabilization flag to 1 = SUPG
    cdrAss.options().setInt("Stabilization", 1);
    // Compute Dirichlet values by L2-projection
    // Caution: Interpolation does not work for locally refined (T)HB-splines!
    cdrAss.options().setInt("DirichletValues",dirichlet::l2Projection);
    //! [constructAssembler]

    // --------------- adaptive refinement loop ---------------

    //! [beginRefLoop]
    for( int refLoop = 0; refLoop <= numRefinementLoops; refLoop++)
    {
    //! [beginRefLoop]
        gsInfo << "====== Loop " << refLoop << " of "
               <<numRefinementLoops<< " ======" << "\n";

        // --------------- solving ---------------

        //! [solverPart]
        // Generate system matrix and load vector
        cdrAss.assemble();

        // Solve the system
        gsMatrix<real_t> solVector = Eigen::BiCGSTAB< gsSparseMatrix<real_t>, Eigen::IncompleteLUT<real_t> >( cdrAss.matrix() ).solve( cdrAss.rhs() );

        // Construct the solution as a scalar field
        gsField<> solField;
        solField = cdrAss.constructSolution(solVector);
        //! [solverPart]

        // --------------- error estimation/computation ---------------

        //! [errorComputation]
        // Compute the H1-seminorm of the computed solution
        // ( which is, at least, equivalent to the energy norm in this example )
        // using the known exact solution.
        gsSeminormH1<real_t> norm( solField );
        norm.compute(true); // "true" indicates that element-wise norms shall be stored

        // Get the element-wise norms.
        const std::vector<real_t> & eltErrs  = norm.elementNorms();
        //! [errorComputation]

        // --------------- adaptive refinement ---------------

        //! [adaptRefinementPart]
        // Mark elements for refinement, based on the computed local errors and
        // the refinement-criterion and -parameter.
        std::vector<bool> elMarked( eltErrs.size() );
        gsMarkElementsForRef( eltErrs, adaptRefCrit, adaptRefParam, elMarked);
        gsInfo <<"Marked "<< std::count(elMarked.begin(), elMarked.end(), true) <<" elements.\n";

        // Refine the marked elements with a 1-ring of cells around marked elements
        gsRefineMarkedElements( cdrAss.multiBasis(), elMarked, 1 );
        //! [adaptRefinementPart]

        //! [repairInterfaces]
        // Call repair interfaces to make sure that the new meshes
        // match along patch interfaces.
        cdrAss.multiBasis().repairInterfaces( patches.interfaces() );
        //! [repairInterfaces]

        //! [refreshAssembler]
        cdrAss.refresh();
        //! [refreshAssembler]

        //! [Export to Paraview]
        // Export the final solution
        if( plot && refLoop == numRefinementLoops )
        {
            // Write the computed solution to paraview files
            gsWriteParaview<>( solField, "adaptRef", 1000, true);
        }
        //! [Export to Paraview]

    }

    //! [Plot in Paraview]
    if( plot )
    {
        // Run paraview
        return system("paraview adaptRef.pvd &");
    }
    //! [Plot in Paraview]
    else
    {
        gsInfo<<"Quitting.. No output created, re-run with --plot to get a ParaView "
                "file containing Plotting image data.\n";
        return 0;
    }

}// end main
<commit_msg>minor<commit_after>/** @file tutorialAdaptiveCDR.cpp

    @brief Tutorial on how to use G+Smo to solve a convection-diffusion-reaction problem.

    This file is part of the G+Smo library.

    This Source Code Form is subject to the terms of the Mozilla Public
    License, v. 2.0. If a copy of the MPL was not distributed with this
    file, You can obtain one at http://mozilla.org/MPL/2.0/.

    Author(s): S. Kleiss
*/

//! [Include namespace]
# include <gismo.h>
# include <gsAssembler/gsAdaptiveRefUtils.h>

using namespace std;
using namespace gismo;
//! [Include namespace]

int main(int argc, char *argv[])
{
    //! [Parse command line]
    bool plot = false;

    gsCmdLine cmd("Example for solving a convection-diffusion problem.");
    cmd.addSwitch("plot", "Create a ParaView visualization file with the solution", plot);
    const bool ok = cmd.getValues(argc,argv);
    if (!ok) { gsWarn << "Error during parsing the command line!\n"; return 0;}
    //! [Parse command line]

    // --------------- specify exact solution and right-hand-side ---------------

    //! [Function data]
    // Define exact solution (will be used for specifying Dirichlet boundary conditions
    //gsFunctionExpr<> g("if( y<-x/2-1/2, 1, 0 )", 2);
    gsFunctionExpr<> g("if( y>=0, if( x <=-1, 1, 0 ), 0 )", 2);
    // Define source function
    gsFunctionExpr<> rhs("0",2);

    // diffusion coefficient:
    gsFunctionExpr<> coeff_diff("0.000001","0","0","0.000001",2);
    // convection coefficient:
    gsFunctionExpr<> coeff_conv("3/sqrt(13)","-2/sqrt(13)",2);
    // reaction coefficient:
    gsFunctionExpr<> coeff_reac("0",2);
    //! [Function data]

    // Print out source function and solution
    gsInfo<<"Source function " << rhs << "\n";
    gsInfo<<"Dirichlet boundary conditions "  << g << "\n\n";

    // --------------- read geometry from file ---------------

    // Read geometry from file (full path needed, or
    // GISMO_DATA_DIR macro which leads to the "filedata" directory
    //! [GetGeometryData]
    // Read xml and create gsMultiPatch
    string fileSrc( GISMO_DATA_DIR "/planar/lshape2d_3patches_thb.xml" );
    gsMultiPatch<real_t> patches;
    gsReadFile<real_t>( fileSrc, patches);
    //! [GetGeometryData]
    gsInfo << "The domain is a "<< patches <<"\n";

    //! [computeTopology]
    // Get all interfaces and boundaries:
    patches.computeTopology();
    //! [computeTopology]

    // --------------- add bonudary conditions ---------------
    //! [Boundary conditions]
    gsBoundaryConditions<> bcInfo;

    // For simplicity, set Dirichlet boundary conditions
    // given by exact solution g on all boundaries:
    for ( gsMultiPatch<>::const_biterator
             bit = patches.bBegin(); bit != patches.bEnd(); ++bit)
    {
        bcInfo.addCondition( *bit, condition_type::dirichlet, &g );
    }
    //! [Boundary conditions]

    // --------------- define Pde ---------------
    //! [definePde]
    gsConvDiffRePde<real_t> cdrPde(patches, bcInfo, & coeff_diff,& coeff_conv, & coeff_reac, & rhs);
    //! [definePde]

    // --------------- set up basis ---------------

    //! [GetBasisFromTHB]
    // Copy basis from the geometry
    gsMultiBasis<> bases( patches );
    //! [GetBasisFromTHB]

    //! [initialRefinements]
    // Number of initial uniform refinement steps:
    int numInitUniformRefine  = 2;

    for (int i = 0; i < numInitUniformRefine; ++i)
      bases.uniformRefine();
    //! [initialRefinements]

    // --------------- set up adaptive refinement loop ---------------

    //! [adaptRefSettings]
    // Number of refinement loops to be done
    int numRefinementLoops = 4;

    // Specify cell-marking strategy...
    MarkingStrategy adaptRefCrit = PUCA;
//    MarkingStrategy adaptRefCrit = GARU;
//    MarkingStrategy adaptRefCrit = errorFraction;

    // ... and parameter.
    const real_t adaptRefParam = 0.7;

    //! [adaptRefSettings]

    //! [constructAssembler]
    // Construct assembler
    gsCDRAssembler<real_t> cdrAss( cdrPde, bases);
    // Set stabilization flag to 1 = SUPG
    cdrAss.options().setInt("Stabilization", 1);
    // Compute Dirichlet values by L2-projection
    // Caution: Interpolation does not work for locally refined (T)HB-splines!
    cdrAss.options().setInt("DirichletValues",dirichlet::l2Projection);
    //! [constructAssembler]

    // --------------- adaptive refinement loop ---------------

    //! [beginRefLoop]
    for( int refLoop = 0; refLoop <= numRefinementLoops; refLoop++)
    {
    //! [beginRefLoop]
        gsInfo << "====== Loop " << refLoop << " of "
               <<numRefinementLoops<< " ======" << "\n";

        // --------------- solving ---------------

        //! [solverPart]
        // Generate system matrix and load vector
        cdrAss.assemble();

        // Solve the system
        gsMatrix<real_t> solVector =
            gsSparseSolver<>::BiCGSTABILUT( cdrAss.matrix() ).solve( cdrAss.rhs() );

        // Construct the solution as a scalar field
        gsField<> solField;
        solField = cdrAss.constructSolution(solVector);
        //! [solverPart]

        // --------------- error estimation/computation ---------------

        //! [errorComputation]
        // Compute the H1-seminorm of the computed solution
        // ( which is, at least, equivalent to the energy norm in this example )
        // using the known exact solution.
        gsSeminormH1<real_t> norm( solField );
        norm.compute(true); // "true" indicates that element-wise norms shall be stored

        // Get the element-wise norms.
        const std::vector<real_t> & eltErrs  = norm.elementNorms();
        //! [errorComputation]

        // --------------- adaptive refinement ---------------

        //! [adaptRefinementPart]
        // Mark elements for refinement, based on the computed local errors and
        // the refinement-criterion and -parameter.
        std::vector<bool> elMarked( eltErrs.size() );
        gsMarkElementsForRef( eltErrs, adaptRefCrit, adaptRefParam, elMarked);
        gsInfo <<"Marked "<< std::count(elMarked.begin(), elMarked.end(), true) <<" elements.\n";

        // Refine the marked elements with a 1-ring of cells around marked elements
        gsRefineMarkedElements( cdrAss.multiBasis(), elMarked, 1 );
        //! [adaptRefinementPart]

        //! [repairInterfaces]
        // Call repair interfaces to make sure that the new meshes
        // match along patch interfaces.
        cdrAss.multiBasis().repairInterfaces( patches.interfaces() );
        //! [repairInterfaces]

        //! [refreshAssembler]
        cdrAss.refresh();
        //! [refreshAssembler]

        //! [Export to Paraview]
        // Export the final solution
        if( plot && refLoop == numRefinementLoops )
        {
            // Write the computed solution to paraview files
            gsWriteParaview<>( solField, "adaptRef", 1000, true);
        }
        //! [Export to Paraview]

    }

    //! [Plot in Paraview]
    if( plot )
    {
        // Run paraview
        return system("paraview adaptRef.pvd &");
    }
    //! [Plot in Paraview]
    else
    {
        gsInfo<<"Quitting.. No output created, re-run with --plot to get a ParaView "
                "file containing Plotting image data.\n";
        return 0;
    }

}// end main
<|endoftext|>


<commit_before>/* <x0/HttpListener.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 *
 * (c) 2009 Chrisitan Parpart <trapni@gentoo.org>
 */

#include <x0/http/HttpListener.h>
#include <x0/http/HttpConnection.h>
#include <x0/http/HttpServer.h>
#include <x0/SocketDriver.h>

#include <x0/sysconfig.h>

#if defined(WITH_SSL)
#	include <x0/SslDriver.h>
#endif

#include <arpa/inet.h>		// inet_pton()
#include <netinet/tcp.h>	// TCP_QUICKACK, TCP_DEFER_ACCEPT
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>

namespace x0 {

HttpListener::HttpListener(HttpServer& srv) :
	watcher_(srv.loop()),
	fd_(-1),
	server_(srv),
	address_(),
	port_(-1),
	backlog_(SOMAXCONN),
	errors_(0),
	socketDriver_(new SocketDriver(srv.loop()))
{
	watcher_.set<HttpListener, &HttpListener::callback>(this);
}

HttpListener::~HttpListener()
{
	stop();
}

void HttpListener::stop()
{
	if (fd_ == -1)
		return;

	watcher_.stop();

	::close(fd_);
	fd_ = -1;

	setSocketDriver(NULL);
}

inline void HttpListener::setsockopt(int socket, int layer, int option, int value)
{
	if (::setsockopt(socket, layer, option, &value, sizeof(value)) < 0)
	{
		log(Severity::error, "Error setting socket option (fd=%d, layer=%d, opt=%d, val=%d): %s",
				socket, layer, option, value, strerror(errno));
	}
}

void HttpListener::setSocketDriver(SocketDriver *sd)
{
	if (socketDriver_)
		delete socketDriver_;

	socketDriver_ = sd;
}

std::error_code HttpListener::prepare()
{
#if defined(WITH_SSL)
	if (isSecure())
		log(Severity::info, "Start listening on [%s]:%d [secure]", address_.c_str(), port_);
	else
		log(Severity::info, "Start listening on [%s]:%d", address_.c_str(), port_);
#else
	log(Severity::info, "Start listening on [%s]:%d", address_.c_str(), port_);
#endif

	fd_ = ::socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
	if (fd_ < 0) return std::make_error_code(static_cast<std::errc>(errno));

	fcntl(fd_, F_SETFL, FD_CLOEXEC);

	if (fcntl(fd_, F_SETFL, O_NONBLOCK) < 0)
	{
		//log(Severity::error, "could not set server socket into non-blocking mode: %s\n", strerror(errno));
		return std::make_error_code(static_cast<std::errc>(errno));
	}

	sockaddr_in6 sin;
	bzero(&sin, sizeof(sin));

	sin.sin6_family = AF_INET6;
	sin.sin6_port = htons(port_);

	if (inet_pton(sin.sin6_family, address_.c_str(), sin.sin6_addr.s6_addr) < 0)
		log(Severity::error, "Could not resolve IP address (%s): %s", address_.c_str(), strerror(errno));

#if defined(SO_REUSEADDR)
	//! \todo SO_REUSEADDR: could be configurable
	setsockopt(fd_, SOL_SOCKET, SO_REUSEADDR, 1);
#endif

#if defined(TCP_QUICKACK)
	//! \todo TCP_QUICKACK: could be configurable
	setsockopt(fd_, SOL_TCP, TCP_QUICKACK, 1);
#endif

#if defined(TCP_DEFER_ACCEPT)
	setsockopt(fd_, SOL_TCP, TCP_DEFER_ACCEPT, 1);
#endif

//	acceptor_.set_option(asio::ip::tcp::acceptor::linger(false, 0));
//	acceptor_.set_option(asio::ip::tcp::acceptor::keep_alive(true));

	if (::bind(fd_, (sockaddr *)&sin, sizeof(sin)) < 0) {
		log(Severity::error, "Cannot bind to IP-address (%s): %s", address_.c_str(), strerror(errno));
		return std::make_error_code(static_cast<std::errc>(errno));
	}

	if (::listen(fd_, backlog_) < 0) {
		log(Severity::error, "Cannot listen to IP-address (%s): %s", address_.c_str(), strerror(errno));
		return std::make_error_code(static_cast<std::errc>(errno));
	}

	return std::error_code();
}

std::error_code HttpListener::start()
{
	std::error_code ec;

	if (fd_ == -1)
	{
		ec = prepare();

		if (ec)
			return ec;
	}

	watcher_.start(fd_, ev::READ);
	return ec;
}

void HttpListener::callback(ev::io& watcher, int revents)
{
	// TODO accept() as much until it would block.
	if (HttpConnection *c = new HttpConnection(*this))
	{
		if (c->isClosed())
			delete c;
		else
			// TODO: introduce a PREPARE mode, that would defer the code fragment below - required for SSL handshaking, which takes place *before* processing the HTTP request
			c->start();
	}
}

std::string HttpListener::address() const
{
	return address_;
}

void HttpListener::address(const std::string& value)
{
	address_ = value;
}

int HttpListener::port() const
{
	return port_;
}

void HttpListener::port(int value)
{
	port_ = value;
}

int HttpListener::backlog() const
{
	return backlog_;
}

void HttpListener::backlog(int value)
{
	backlog_ = value;
}

} // namespace x0
<commit_msg>code cleanup<commit_after>/* <x0/HttpListener.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 *
 * (c) 2009 Chrisitan Parpart <trapni@gentoo.org>
 */

#include <x0/http/HttpListener.h>
#include <x0/http/HttpConnection.h>
#include <x0/http/HttpServer.h>
#include <x0/SocketDriver.h>

#include <x0/sysconfig.h>

#include <arpa/inet.h>		// inet_pton()
#include <netinet/tcp.h>	// TCP_QUICKACK, TCP_DEFER_ACCEPT
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <netdb.h>
#include <fcntl.h>

namespace x0 {

HttpListener::HttpListener(HttpServer& srv) :
	watcher_(srv.loop()),
	fd_(-1),
	server_(srv),
	address_(),
	port_(-1),
	backlog_(SOMAXCONN),
	errors_(0),
	socketDriver_(new SocketDriver(srv.loop()))
{
	watcher_.set<HttpListener, &HttpListener::callback>(this);
}

HttpListener::~HttpListener()
{
	stop();
}

void HttpListener::stop()
{
	if (fd_ == -1)
		return;

	watcher_.stop();

	::close(fd_);
	fd_ = -1;

	setSocketDriver(NULL);
}

inline void HttpListener::setsockopt(int socket, int layer, int option, int value)
{
	if (::setsockopt(socket, layer, option, &value, sizeof(value)) < 0)
	{
		log(Severity::error, "Error setting socket option (fd=%d, layer=%d, opt=%d, val=%d): %s",
				socket, layer, option, value, strerror(errno));
	}
}

void HttpListener::setSocketDriver(SocketDriver *sd)
{
	if (socketDriver_)
		delete socketDriver_;

	socketDriver_ = sd;
}

std::error_code HttpListener::prepare()
{
#if defined(WITH_SSL)
	if (isSecure())
		log(Severity::info, "Start listening on [%s]:%d [secure]", address_.c_str(), port_);
	else
		log(Severity::info, "Start listening on [%s]:%d", address_.c_str(), port_);
#else
	log(Severity::info, "Start listening on [%s]:%d", address_.c_str(), port_);
#endif

	fd_ = ::socket(PF_INET6, SOCK_STREAM, IPPROTO_TCP);
	if (fd_ < 0) return std::make_error_code(static_cast<std::errc>(errno));

	fcntl(fd_, F_SETFL, FD_CLOEXEC);

	if (fcntl(fd_, F_SETFL, O_NONBLOCK) < 0)
	{
		//log(Severity::error, "could not set server socket into non-blocking mode: %s\n", strerror(errno));
		return std::make_error_code(static_cast<std::errc>(errno));
	}

	sockaddr_in6 sin;
	bzero(&sin, sizeof(sin));

	sin.sin6_family = AF_INET6;
	sin.sin6_port = htons(port_);

	if (inet_pton(sin.sin6_family, address_.c_str(), sin.sin6_addr.s6_addr) < 0)
		log(Severity::error, "Could not resolve IP address (%s): %s", address_.c_str(), strerror(errno));

#if defined(SO_REUSEADDR)
	//! \todo SO_REUSEADDR: could be configurable
	setsockopt(fd_, SOL_SOCKET, SO_REUSEADDR, 1);
#endif

#if defined(TCP_QUICKACK)
	//! \todo TCP_QUICKACK: could be configurable
	setsockopt(fd_, SOL_TCP, TCP_QUICKACK, 1);
#endif

#if defined(TCP_DEFER_ACCEPT)
	setsockopt(fd_, SOL_TCP, TCP_DEFER_ACCEPT, 1);
#endif

//	acceptor_.set_option(asio::ip::tcp::acceptor::linger(false, 0));
//	acceptor_.set_option(asio::ip::tcp::acceptor::keep_alive(true));

	if (::bind(fd_, (sockaddr *)&sin, sizeof(sin)) < 0) {
		log(Severity::error, "Cannot bind to IP-address (%s): %s", address_.c_str(), strerror(errno));
		return std::make_error_code(static_cast<std::errc>(errno));
	}

	if (::listen(fd_, backlog_) < 0) {
		log(Severity::error, "Cannot listen to IP-address (%s): %s", address_.c_str(), strerror(errno));
		return std::make_error_code(static_cast<std::errc>(errno));
	}

	return std::error_code();
}

std::error_code HttpListener::start()
{
	std::error_code ec;

	if (fd_ == -1)
	{
		ec = prepare();

		if (ec)
			return ec;
	}

	watcher_.start(fd_, ev::READ);
	return ec;
}

void HttpListener::callback(ev::io& watcher, int revents)
{
	// TODO accept() as much until it would block.
	if (HttpConnection *c = new HttpConnection(*this))
	{
		if (c->isClosed())
			delete c;
		else
			// TODO: introduce a PREPARE mode, that would defer the code fragment below - required for SSL handshaking, which takes place *before* processing the HTTP request
			c->start();
	}
}

std::string HttpListener::address() const
{
	return address_;
}

void HttpListener::address(const std::string& value)
{
	address_ = value;
}

int HttpListener::port() const
{
	return port_;
}

void HttpListener::port(int value)
{
	port_ = value;
}

int HttpListener::backlog() const
{
	return backlog_;
}

void HttpListener::backlog(int value)
{
	backlog_ = value;
}

} // namespace x0
<|endoftext|>


<commit_before>/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 Module
 * -------------------------------------------------
 *
 * Copyright 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Negative Precise Tests
 *//*--------------------------------------------------------------------*/

#include "es31fNegativePreciseTests.hpp"

#include "gluShaderProgram.hpp"
#include "glwEnums.hpp"

namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace NegativeTestShared
{
namespace
{

enum TestPrecise
{
	TEST_PRECISE_AS_VARIABLE_NAME = 0,
	TEST_PRECISE_AS_FUNCTION_NAME,
	TEST_PRECISE_AS_ARGUMENT_NAME,
	TEST_PRECISE_AS_MACRO_NAME,
	TEST_PRECISE_MACRO_AND_VARIABLE,
	TEST_PRECISE_MACRO_AND_FUNCTION,
	TEST_PRECISE_MACRO_AND_ARGUMENT,

	TEST_PRECISE_LAST
};

static const glu::ShaderType s_shaderTypes[] =
{
	glu::SHADERTYPE_VERTEX,
	glu::SHADERTYPE_FRAGMENT,
	glu::SHADERTYPE_GEOMETRY,
	glu::SHADERTYPE_COMPUTE,
	glu::SHADERTYPE_TESSELLATION_CONTROL,
	glu::SHADERTYPE_TESSELLATION_EVALUATION
};

std::string generateShaderSource (NegativeTestContext& ctx, glu::ShaderType shaderType, TestPrecise test)
{
	const bool				isES32	= contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
	const glu::GLSLVersion	version	= isES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
	std::ostringstream		source;

	source	<< glu::getGLSLVersionDeclaration(version) << "\n"
			<< (isES32 ? "" : "#extension GL_EXT_gpu_shader5 : enable\n");

	switch (test)
	{
		case TEST_PRECISE_AS_MACRO_NAME:		source << "#define precise 0\n";		break;

		case TEST_PRECISE_MACRO_AND_VARIABLE:
		case TEST_PRECISE_MACRO_AND_FUNCTION:
		case TEST_PRECISE_MACRO_AND_ARGUMENT:	source << "#define precise aName\n";	break;
		default:
			break;
	}

    switch (shaderType)
    {
        case glu::SHADERTYPE_GEOMETRY:
            source  << (isES32 ? "" : "#extension GL_EXT_geometry_shader : enable\n")
                    << "layout(max_vertices = 5) out;\n";
            break;

        case glu::SHADERTYPE_TESSELLATION_CONTROL:
            source  << (isES32 ? "" : "#extension GL_EXT_tessellation_shader : enable\n")
                    << "layout(vertices = 3) out;\n";
            break;

        case glu::SHADERTYPE_TESSELLATION_EVALUATION:
            source  << (isES32 ? "" : "#extension GL_EXT_tessellation_shader : enable\n")
                    << "layout(triangles, equal_spacing, cw) in;\n";
            break;

        default:
            break;
    }

	switch (test)
	{
		case TEST_PRECISE_AS_FUNCTION_NAME:
		case TEST_PRECISE_MACRO_AND_FUNCTION:
			source	<< "\n"
					<< "void precise()\n"
					<< "{\n"
					<< "}\n";
			break;

		case TEST_PRECISE_AS_ARGUMENT_NAME:
		case TEST_PRECISE_MACRO_AND_ARGUMENT:
			source	<< "\n"
					<< "void example(int precise)\n"
					<< "{\n"
					<< "}\n";
			break;

		default:
			break;
	}

    source  << "void main()\n"
			<< "{\n";

	switch (test)
	{
		case TEST_PRECISE_AS_VARIABLE_NAME:
		case TEST_PRECISE_MACRO_AND_VARIABLE:	source << "	int precise = 1;\n";		break;
		case TEST_PRECISE_AS_MACRO_NAME:		source << "	int number = precise;\n";	break;
		default:
			break;
	}

	source << "}\n";

	return source.str();
}

void generateAndVerifyShader (NegativeTestContext& ctx, glu::ShaderType shaderType, TestPrecise test)
{
	glu::Shader			shader			(ctx.getRenderContext(), shaderType);
	std::string			shaderSource	= generateShaderSource(ctx, shaderType, test);
	const char* const	source			= shaderSource.c_str();
	const int			length			= (int) shaderSource.size();

	shader.setSources(1, &source, &length);
	shader.compile();

	ctx.getLog() << shader;

	if (shader.getCompileStatus())
		ctx.fail("Shader was not expected to compile.");
}

void precise_as_variable_name (NegativeTestContext& ctx)
{
	TCU_CHECK_AND_THROW(NotSupportedError,
		ctx.isExtensionSupported("GL_EXT_gpu_shader5") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
		"This test requires support for the extension GL_EXT_gpu_shader5 or context version 3.2 or higher.");

	ctx.beginSection("Test that precise cannot be used as a variable name.");
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaderTypes); ++ndx)
		generateAndVerifyShader(ctx, s_shaderTypes[ndx], TEST_PRECISE_AS_VARIABLE_NAME);
	ctx.endSection();
}

void precise_as_function_name (NegativeTestContext& ctx)
{
	TCU_CHECK_AND_THROW(NotSupportedError,
		ctx.isExtensionSupported("GL_EXT_gpu_shader5") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
		"This test requires support for the extension GL_EXT_gpu_shader5 or context version 3.2 or higher.");

	ctx.beginSection("Test that precise cannot be used as a function name.");
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaderTypes); ++ndx)
		generateAndVerifyShader(ctx, s_shaderTypes[ndx], TEST_PRECISE_AS_FUNCTION_NAME);
	ctx.endSection();
}

void precise_as_function_argument (NegativeTestContext& ctx)
{
	TCU_CHECK_AND_THROW(NotSupportedError,
		ctx.isExtensionSupported("GL_EXT_gpu_shader5") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
		"This test requires support for the extension GL_EXT_gpu_shader5 or context version 3.2 or higher.");

	ctx.beginSection("Test that precise cannot be used as a argument name.");
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaderTypes); ++ndx)
		generateAndVerifyShader(ctx, s_shaderTypes[ndx], TEST_PRECISE_AS_ARGUMENT_NAME);
	ctx.endSection();
}

} // anonymous

std::vector<FunctionContainer> getNegativePreciseTestFunctions (void)
{
	const FunctionContainer funcs[] =
	{
        {precise_as_variable_name,			"precise_as_variable_name",			"Test precise keyword as variable name."			},
        {precise_as_function_name,			"precise_as_function_name",			"Test precise keyword as function name."			},
        {precise_as_function_argument,		"precise_as_function_argument",		"Test precise keyword as argument name."			},
	};

	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
}

} // NegativeTestShared
} // Functional
} // gles31
} // deqp
<commit_msg>Check for shader type support in negative precise tests am: 4a3a2d79a0<commit_after>/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 Module
 * -------------------------------------------------
 *
 * Copyright 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Negative Precise Tests
 *//*--------------------------------------------------------------------*/

#include "es31fNegativePreciseTests.hpp"

#include "gluShaderProgram.hpp"
#include "glwEnums.hpp"

namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace NegativeTestShared
{
namespace
{

enum TestPrecise
{
	TEST_PRECISE_AS_VARIABLE_NAME = 0,
	TEST_PRECISE_AS_FUNCTION_NAME,
	TEST_PRECISE_AS_ARGUMENT_NAME,
	TEST_PRECISE_AS_MACRO_NAME,
	TEST_PRECISE_MACRO_AND_VARIABLE,
	TEST_PRECISE_MACRO_AND_FUNCTION,
	TEST_PRECISE_MACRO_AND_ARGUMENT,

	TEST_PRECISE_LAST
};

static const glu::ShaderType s_shaderTypes[] =
{
	glu::SHADERTYPE_VERTEX,
	glu::SHADERTYPE_FRAGMENT,
	glu::SHADERTYPE_GEOMETRY,
	glu::SHADERTYPE_COMPUTE,
	glu::SHADERTYPE_TESSELLATION_CONTROL,
	glu::SHADERTYPE_TESSELLATION_EVALUATION
};

std::string generateShaderSource (NegativeTestContext& ctx, glu::ShaderType shaderType, TestPrecise test)
{
	const bool				isES32	= contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
	const glu::GLSLVersion	version	= isES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
	std::ostringstream		source;

	source	<< glu::getGLSLVersionDeclaration(version) << "\n"
			<< (isES32 ? "" : "#extension GL_EXT_gpu_shader5 : enable\n");

	switch (test)
	{
		case TEST_PRECISE_AS_MACRO_NAME:		source << "#define precise 0\n";		break;

		case TEST_PRECISE_MACRO_AND_VARIABLE:
		case TEST_PRECISE_MACRO_AND_FUNCTION:
		case TEST_PRECISE_MACRO_AND_ARGUMENT:	source << "#define precise aName\n";	break;
		default:
			break;
	}

    switch (shaderType)
    {
        case glu::SHADERTYPE_GEOMETRY:
            source  << (isES32 ? "" : "#extension GL_EXT_geometry_shader : enable\n")
                    << "layout(max_vertices = 5) out;\n";
            break;

        case glu::SHADERTYPE_TESSELLATION_CONTROL:
            source  << (isES32 ? "" : "#extension GL_EXT_tessellation_shader : enable\n")
                    << "layout(vertices = 3) out;\n";
            break;

        case glu::SHADERTYPE_TESSELLATION_EVALUATION:
            source  << (isES32 ? "" : "#extension GL_EXT_tessellation_shader : enable\n")
                    << "layout(triangles, equal_spacing, cw) in;\n";
            break;

        default:
            break;
    }

	switch (test)
	{
		case TEST_PRECISE_AS_FUNCTION_NAME:
		case TEST_PRECISE_MACRO_AND_FUNCTION:
			source	<< "\n"
					<< "void precise()\n"
					<< "{\n"
					<< "}\n";
			break;

		case TEST_PRECISE_AS_ARGUMENT_NAME:
		case TEST_PRECISE_MACRO_AND_ARGUMENT:
			source	<< "\n"
					<< "void example(int precise)\n"
					<< "{\n"
					<< "}\n";
			break;

		default:
			break;
	}

    source  << "void main()\n"
			<< "{\n";

	switch (test)
	{
		case TEST_PRECISE_AS_VARIABLE_NAME:
		case TEST_PRECISE_MACRO_AND_VARIABLE:	source << "	int precise = 1;\n";		break;
		case TEST_PRECISE_AS_MACRO_NAME:		source << "	int number = precise;\n";	break;
		default:
			break;
	}

	source << "}\n";

	return source.str();
}

void generateAndVerifyShader (NegativeTestContext& ctx, glu::ShaderType shaderType, TestPrecise test)
{
	glu::Shader			shader			(ctx.getRenderContext(), shaderType);
	std::string			shaderSource	= generateShaderSource(ctx, shaderType, test);
	const char* const	source			= shaderSource.c_str();
	const int			length			= (int) shaderSource.size();

	shader.setSources(1, &source, &length);
	shader.compile();

	ctx.getLog() << shader;

	if (shader.getCompileStatus())
		ctx.fail("Shader was not expected to compile.");
}

void precise_as_variable_name (NegativeTestContext& ctx)
{
	TCU_CHECK_AND_THROW(NotSupportedError,
		ctx.isExtensionSupported("GL_EXT_gpu_shader5") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
		"This test requires support for the extension GL_EXT_gpu_shader5 or context version 3.2 or higher.");

	ctx.beginSection("Test that precise cannot be used as a variable name.");
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaderTypes); ++ndx)
	{
		if (ctx.isShaderSupported(s_shaderTypes[ndx]))
			generateAndVerifyShader(ctx, s_shaderTypes[ndx], TEST_PRECISE_AS_VARIABLE_NAME);
	}
	ctx.endSection();
}

void precise_as_function_name (NegativeTestContext& ctx)
{
	TCU_CHECK_AND_THROW(NotSupportedError,
		ctx.isExtensionSupported("GL_EXT_gpu_shader5") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
		"This test requires support for the extension GL_EXT_gpu_shader5 or context version 3.2 or higher.");

	ctx.beginSection("Test that precise cannot be used as a function name.");
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaderTypes); ++ndx)
	{
		if (ctx.isShaderSupported(s_shaderTypes[ndx]))
			generateAndVerifyShader(ctx, s_shaderTypes[ndx], TEST_PRECISE_AS_FUNCTION_NAME);
	}
	ctx.endSection();
}

void precise_as_function_argument (NegativeTestContext& ctx)
{
	TCU_CHECK_AND_THROW(NotSupportedError,
		ctx.isExtensionSupported("GL_EXT_gpu_shader5") || contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
		"This test requires support for the extension GL_EXT_gpu_shader5 or context version 3.2 or higher.");

	ctx.beginSection("Test that precise cannot be used as a argument name.");
	for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_shaderTypes); ++ndx)
	{
		if (ctx.isShaderSupported(s_shaderTypes[ndx]))
			generateAndVerifyShader(ctx, s_shaderTypes[ndx], TEST_PRECISE_AS_ARGUMENT_NAME);
	}
	ctx.endSection();
}

} // anonymous

std::vector<FunctionContainer> getNegativePreciseTestFunctions (void)
{
	const FunctionContainer funcs[] =
	{
        {precise_as_variable_name,			"precise_as_variable_name",			"Test precise keyword as variable name."			},
        {precise_as_function_name,			"precise_as_function_name",			"Test precise keyword as function name."			},
        {precise_as_function_argument,		"precise_as_function_argument",		"Test precise keyword as argument name."			},
	};

	return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
}

} // NegativeTestShared
} // Functional
} // gles31
} // deqp
<|endoftext|>


<commit_before>#include "execHelperOptions.h"

#include <iostream>
#include <string>
#include <assert.h>

#include "log/log.h"
#include "yaml/yaml.h"
#include "config/settingsNode.h"
#include "executorInterface.h"
#include "pattern.h"
#include "patternsHandler.h"

using std::cout;
using std::endl;
using std::string;
using std::vector;
using std::shared_ptr;
using std::make_shared;

using boost::program_options::variables_map;

using execHelper::core::CommandCollection;

using execHelper::config::SettingsNode;

using execHelper::yaml::Yaml;
using execHelper::yaml::YamlFile;

namespace execHelper { namespace core {
    ExecHelperOptions::ExecHelperOptions() noexcept :
        m_verbose(false),
        m_singleThreaded(false),
        m_executor(0)
    {
        ;
    }

    ExecHelperOptions::ExecHelperOptions(const ExecHelperOptions& other) noexcept :
        m_verbose(other.m_verbose),
        m_singleThreaded(other.m_singleThreaded),
        m_settings(other.m_settings),
        m_executor(other.m_executor)
    {
        ;
    }

    bool ExecHelperOptions::operator==(const ExecHelperOptions& other) const noexcept {
        return (
                    m_verbose == other.m_verbose &&
                    m_singleThreaded == other.m_singleThreaded &&
                    m_settings == other.m_settings &&
                    m_patternsHandler == other.m_patternsHandler &&
                    m_executor == other.m_executor
               );
    }

    bool ExecHelperOptions::operator!=(const ExecHelperOptions& other) const noexcept {
        return !(*this == other);
    }

    bool ExecHelperOptions::getVerbosity() const noexcept {
        return m_verbose;
    }

    bool ExecHelperOptions::getDryRun() const noexcept {
        return m_dryRun;
    }

    bool ExecHelperOptions::getSingleThreaded() const noexcept {
        return m_singleThreaded;
    }

    const CommandCollection& ExecHelperOptions::getCommands() const noexcept {
        return m_commands;
    }

    string ExecHelperOptions::getSettingsFile(int argc, const char* const * argv) const noexcept {
        variables_map optionsMap = m_optionsDescriptions.getOptionsMap(argc, argv, true);
        if(optionsMap.count("settings-file")) {
            return optionsMap["settings-file"].as<string>();
        }
        return ".exec-helper";
    }

    bool ExecHelperOptions::parse(int argc, const char* const * argv) {
        m_optionsMap = m_optionsDescriptions.getOptionsMap(argc, argv);
        if(m_optionsMap.count("verbose")) {
            m_verbose = true;
        }

        if(m_optionsMap.count("single-threaded")) {
            m_singleThreaded = true;
        }

        if(m_optionsMap.count("command")) {
            m_commands.clear();
            m_commands = m_optionsMap["command"].as<CommandCollection>();
        }

        return true;
    }

    bool ExecHelperOptions::parseSettingsFile(const std::string& file) noexcept {
        YamlFile yamlFile;
        yamlFile.file = file;
        Yaml yaml(yamlFile);
        if(! yaml.getTree({}, m_settings)) {
            LOG("Could not get settings tree");
            return false;
        }

        static const string patternsKey("patterns");
        if(m_settings.contains(patternsKey)) {
            for(const auto& pattern : m_settings[patternsKey].m_values) {
                PatternKey key = pattern.m_key;
                PatternValues defaultValues;
                for(const auto& defaultValue : pattern["default-values"].toStringCollection()) {
                    defaultValues.push_back(defaultValue);
                }
                static const string shortOptionKey("short-option");
                string shortOptionString;
                if(pattern.contains(shortOptionKey)) {
                    shortOptionString = pattern[shortOptionKey].m_values.back().m_key;
                }
                char shortOption = '\0';
                if(shortOptionString.size() > 0) {
                    shortOption = shortOptionString.at(0);
                }

                static const string longOptionKey("long-option");
                string longOption;
                if(pattern.contains(longOptionKey)) {
                    longOption = pattern[longOptionKey].m_values.back().m_key;
                }

                m_patternsHandler.addPattern(Pattern(key, defaultValues, shortOption, longOption));
                string option = longOption + "," + shortOptionString;
                string explanation = string("Values for pattern '") + key + "'";
                m_optionsDescriptions.addOption<PatternValues>(option, explanation, true);
            }
        }
        return true;
    }

    bool ExecHelperOptions::containsHelp() const noexcept {
        return (m_optionsMap.count("help") > 0U);
    }

    const config::SettingsNode& ExecHelperOptions::getSettings() const noexcept {
        return m_settings;
    }

    const config::SettingsNode& ExecHelperOptions::getSettings(const std::string& key) noexcept {
        if(m_settings.contains(key)) {
            return m_settings[key];
        }
        return m_settings;
    }

    const config::SettingsNode& ExecHelperOptions::getSettings(const std::string& key) const noexcept {
        if(m_settings.contains(key)) {
            return m_settings[key];
        }
        return m_settings;
    }

    void ExecHelperOptions::setExecutor(ExecutorInterface* const executor) noexcept {
        m_executor = executor;
    }

    ExecutorInterface* ExecHelperOptions::getExecutor() const noexcept {
        assert(m_executor != 0);
        return m_executor;
    }

    void ExecHelperOptions::printHelp() const noexcept {
        user_feedback(m_optionsDescriptions.getOptionDescriptions());
    }

    bool ExecHelperOptions::contains(const std::string& longOptions) const noexcept {
        return m_optionsMap.count(longOptions) > 0;
    }

    vector<string> ExecHelperOptions::getLongOption(const std::string& longOptions) const noexcept {
        return m_optionsMap[longOptions].as<vector<string>>();
    }

    const PatternsHandler& ExecHelperOptions::getPatternsHandler() const noexcept {
        return m_patternsHandler;
    }

    PatternValues ExecHelperOptions::getValues(const Pattern& pattern) const noexcept {
        string longOption = pattern.getLongOption();
        if(contains(longOption)) {
            return getLongOption(longOption);
        }
        return pattern.getDefaultValues();
    }

    PatternPermutator ExecHelperOptions::makePatternPermutator(const PatternKeys& patterns) const noexcept {
        std::map<core::PatternKey, core::PatternValues> patternValuesMatrix;
        for(const auto& patternKey : patterns) {
            core::Pattern pattern = m_patternsHandler.getPattern(patternKey);
            PatternValues commandlineValues = getValues(pattern);
            patternValuesMatrix.emplace(pattern.getKey(), commandlineValues);
        }
        return core::PatternPermutator(patternValuesMatrix);
    }
} }
<commit_msg>Fixed issue where everything got dry-runned all the time<commit_after>#include "execHelperOptions.h"

#include <iostream>
#include <string>
#include <assert.h>

#include "log/log.h"
#include "yaml/yaml.h"
#include "config/settingsNode.h"
#include "executorInterface.h"
#include "pattern.h"
#include "patternsHandler.h"

using std::cout;
using std::endl;
using std::string;
using std::vector;
using std::shared_ptr;
using std::make_shared;

using boost::program_options::variables_map;

using execHelper::core::CommandCollection;

using execHelper::config::SettingsNode;

using execHelper::yaml::Yaml;
using execHelper::yaml::YamlFile;

namespace execHelper { namespace core {
    ExecHelperOptions::ExecHelperOptions() noexcept :
        m_verbose(false),
        m_dryRun(false),
        m_singleThreaded(false),
        m_executor(0)
    {
        ;
    }

    ExecHelperOptions::ExecHelperOptions(const ExecHelperOptions& other) noexcept :
        m_verbose(other.m_verbose),
        m_dryRun(other.m_dryRun),
        m_singleThreaded(other.m_singleThreaded),
        m_settings(other.m_settings),
        m_executor(other.m_executor)
    {
        ;
    }

    bool ExecHelperOptions::operator==(const ExecHelperOptions& other) const noexcept {
        return (
                    m_verbose == other.m_verbose &&
                    m_dryRun == other.m_dryRun &&
                    m_singleThreaded == other.m_singleThreaded &&
                    m_settings == other.m_settings &&
                    m_patternsHandler == other.m_patternsHandler &&
                    m_executor == other.m_executor
               );
    }

    bool ExecHelperOptions::operator!=(const ExecHelperOptions& other) const noexcept {
        return !(*this == other);
    }

    bool ExecHelperOptions::getVerbosity() const noexcept {
        return m_verbose;
    }

    bool ExecHelperOptions::getDryRun() const noexcept {
        return m_dryRun;
    }

    bool ExecHelperOptions::getSingleThreaded() const noexcept {
        return m_singleThreaded;
    }

    const CommandCollection& ExecHelperOptions::getCommands() const noexcept {
        return m_commands;
    }

    string ExecHelperOptions::getSettingsFile(int argc, const char* const * argv) const noexcept {
        variables_map optionsMap = m_optionsDescriptions.getOptionsMap(argc, argv, true);
        if(optionsMap.count("settings-file")) {
            return optionsMap["settings-file"].as<string>();
        }
        return ".exec-helper";
    }

    bool ExecHelperOptions::parse(int argc, const char* const * argv) {
        m_optionsMap = m_optionsDescriptions.getOptionsMap(argc, argv);
        if(m_optionsMap.count("verbose")) {
            m_verbose = true;
        }

        if(m_optionsMap.count("dry-run")) {
            m_dryRun = true;
        }

        if(m_optionsMap.count("single-threaded")) {
            m_singleThreaded = true;
        }

        if(m_optionsMap.count("command")) {
            m_commands.clear();
            m_commands = m_optionsMap["command"].as<CommandCollection>();
        }

        return true;
    }

    bool ExecHelperOptions::parseSettingsFile(const std::string& file) noexcept {
        YamlFile yamlFile;
        yamlFile.file = file;
        Yaml yaml(yamlFile);
        if(! yaml.getTree({}, m_settings)) {
            LOG("Could not get settings tree");
            return false;
        }

        static const string patternsKey("patterns");
        if(m_settings.contains(patternsKey)) {
            for(const auto& pattern : m_settings[patternsKey].m_values) {
                PatternKey key = pattern.m_key;
                PatternValues defaultValues;
                for(const auto& defaultValue : pattern["default-values"].toStringCollection()) {
                    defaultValues.push_back(defaultValue);
                }
                static const string shortOptionKey("short-option");
                string shortOptionString;
                if(pattern.contains(shortOptionKey)) {
                    shortOptionString = pattern[shortOptionKey].m_values.back().m_key;
                }
                char shortOption = '\0';
                if(shortOptionString.size() > 0) {
                    shortOption = shortOptionString.at(0);
                }

                static const string longOptionKey("long-option");
                string longOption;
                if(pattern.contains(longOptionKey)) {
                    longOption = pattern[longOptionKey].m_values.back().m_key;
                }

                m_patternsHandler.addPattern(Pattern(key, defaultValues, shortOption, longOption));
                string option = longOption + "," + shortOptionString;
                string explanation = string("Values for pattern '") + key + "'";
                m_optionsDescriptions.addOption<PatternValues>(option, explanation, true);
            }
        }
        return true;
    }

    bool ExecHelperOptions::containsHelp() const noexcept {
        return (m_optionsMap.count("help") > 0U);
    }

    const config::SettingsNode& ExecHelperOptions::getSettings() const noexcept {
        return m_settings;
    }

    const config::SettingsNode& ExecHelperOptions::getSettings(const std::string& key) noexcept {
        if(m_settings.contains(key)) {
            return m_settings[key];
        }
        return m_settings;
    }

    const config::SettingsNode& ExecHelperOptions::getSettings(const std::string& key) const noexcept {
        if(m_settings.contains(key)) {
            return m_settings[key];
        }
        return m_settings;
    }

    void ExecHelperOptions::setExecutor(ExecutorInterface* const executor) noexcept {
        m_executor = executor;
    }

    ExecutorInterface* ExecHelperOptions::getExecutor() const noexcept {
        assert(m_executor != 0);
        return m_executor;
    }

    void ExecHelperOptions::printHelp() const noexcept {
        user_feedback(m_optionsDescriptions.getOptionDescriptions());
    }

    bool ExecHelperOptions::contains(const std::string& longOptions) const noexcept {
        return m_optionsMap.count(longOptions) > 0;
    }

    vector<string> ExecHelperOptions::getLongOption(const std::string& longOptions) const noexcept {
        return m_optionsMap[longOptions].as<vector<string>>();
    }

    const PatternsHandler& ExecHelperOptions::getPatternsHandler() const noexcept {
        return m_patternsHandler;
    }

    PatternValues ExecHelperOptions::getValues(const Pattern& pattern) const noexcept {
        string longOption = pattern.getLongOption();
        if(contains(longOption)) {
            return getLongOption(longOption);
        }
        return pattern.getDefaultValues();
    }

    PatternPermutator ExecHelperOptions::makePatternPermutator(const PatternKeys& patterns) const noexcept {
        std::map<core::PatternKey, core::PatternValues> patternValuesMatrix;
        for(const auto& patternKey : patterns) {
            core::Pattern pattern = m_patternsHandler.getPattern(patternKey);
            PatternValues commandlineValues = getValues(pattern);
            patternValuesMatrix.emplace(pattern.getKey(), commandlineValues);
        }
        return core::PatternPermutator(patternValuesMatrix);
    }
} }
<|endoftext|>


<commit_before><commit_msg>perception:io_util add range check<commit_after><|endoftext|>


<commit_before>/*
 * Copyright (c) 2015 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Erik Hallnor
 *          Steve Reinhardt
 *          Andreas Hansson
 */

#include "cpu/testers/memtest/memtest.hh"

#include "base/random.hh"
#include "base/statistics.hh"
#include "base/trace.hh"
#include "debug/MemTest.hh"
#include "sim/sim_exit.hh"
#include "sim/stats.hh"
#include "sim/system.hh"

using namespace std;

unsigned int TESTER_ALLOCATOR = 0;

bool
MemTest::CpuPort::recvTimingResp(PacketPtr pkt)
{
    memtest.completeRequest(pkt);
    return true;
}

void
MemTest::CpuPort::recvReqRetry()
{
    memtest.recvRetry();
}

bool
MemTest::sendPkt(PacketPtr pkt) {
    if (atomic) {
        port.sendAtomic(pkt);
        completeRequest(pkt);
    } else {
        if (!port.sendTimingReq(pkt)) {
            retryPkt = pkt;
            return false;
        }
    }
    return true;
}

MemTest::MemTest(const Params *p)
    : ClockedObject(p),
      tickEvent([this]{ tick(); }, name()),
      noRequestEvent([this]{ noRequest(); }, name()),
      noResponseEvent([this]{ noResponse(); }, name()),
      port("port", *this),
      retryPkt(nullptr),
      size(p->size),
      interval(p->interval),
      percentReads(p->percent_reads),
      percentFunctional(p->percent_functional),
      percentUncacheable(p->percent_uncacheable),
      masterId(p->system->getMasterId(this)),
      blockSize(p->system->cacheLineSize()),
      blockAddrMask(blockSize - 1),
      progressInterval(p->progress_interval),
      progressCheck(p->progress_check),
      nextProgressMessage(p->progress_interval),
      maxLoads(p->max_loads),
      atomic(p->system->isAtomicMode()),
      suppressFuncWarnings(p->suppress_func_warnings)
{
    id = TESTER_ALLOCATOR++;
    fatal_if(id >= blockSize, "Too many testers, only %d allowed\n",
             blockSize - 1);

    baseAddr1 = 0x100000;
    baseAddr2 = 0x400000;
    uncacheAddr = 0x800000;

    // set up counters
    numReads = 0;
    numWrites = 0;

    // kick things into action
    schedule(tickEvent, curTick());
    schedule(noRequestEvent, clockEdge(progressCheck));
    schedule(noResponseEvent, clockEdge(progressCheck));
}

Port &
MemTest::getPort(const std::string &if_name, PortID idx)
{
    if (if_name == "port")
        return port;
    else
        return ClockedObject::getPort(if_name, idx);
}

void
MemTest::completeRequest(PacketPtr pkt, bool functional)
{
    const RequestPtr &req = pkt->req;
    assert(req->getSize() == 1);

    // this address is no longer outstanding
    auto remove_addr = outstandingAddrs.find(req->getPaddr());
    assert(remove_addr != outstandingAddrs.end());
    outstandingAddrs.erase(remove_addr);

    DPRINTF(MemTest, "Completing %s at address %x (blk %x) %s\n",
            pkt->isWrite() ? "write" : "read",
            req->getPaddr(), blockAlign(req->getPaddr()),
            pkt->isError() ? "error" : "success");

    const uint8_t *pkt_data = pkt->getConstPtr<uint8_t>();

    if (pkt->isError()) {
        if (!functional || !suppressFuncWarnings) {
            warn("%s access failed at %#x\n",
                 pkt->isWrite() ? "Write" : "Read", req->getPaddr());
        }
    } else {
        if (pkt->isRead()) {
            uint8_t ref_data = referenceData[req->getPaddr()];
            if (pkt_data[0] != ref_data) {
                panic("%s: read of %x (blk %x) @ cycle %d "
                      "returns %x, expected %x\n", name(),
                      req->getPaddr(), blockAlign(req->getPaddr()), curTick(),
                      pkt_data[0], ref_data);
            }

            numReads++;
            numReadsStat++;

            if (numReads == (uint64_t)nextProgressMessage) {
                ccprintf(cerr, "%s: completed %d read, %d write accesses @%d\n",
                         name(), numReads, numWrites, curTick());
                nextProgressMessage += progressInterval;
            }

            if (maxLoads != 0 && numReads >= maxLoads)
                exitSimLoop("maximum number of loads reached");
        } else {
            assert(pkt->isWrite());

            // update the reference data
            referenceData[req->getPaddr()] = pkt_data[0];
            numWrites++;
            numWritesStat++;
        }
    }

    // the packet will delete the data
    delete pkt;

    // finally shift the response timeout forward
    reschedule(noResponseEvent, clockEdge(progressCheck), true);
}

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

    using namespace Stats;

    numReadsStat
        .name(name() + ".num_reads")
        .desc("number of read accesses completed")
        ;

    numWritesStat
        .name(name() + ".num_writes")
        .desc("number of write accesses completed")
        ;
}

void
MemTest::tick()
{
    // we should never tick if we are waiting for a retry
    assert(!retryPkt);

    // create a new request
    unsigned cmd = random_mt.random(0, 100);
    uint8_t data = random_mt.random<uint8_t>();
    bool uncacheable = random_mt.random(0, 100) < percentUncacheable;
    unsigned base = random_mt.random(0, 1);
    Request::Flags flags;
    Addr paddr;

    // generate a unique address
    do {
        unsigned offset = random_mt.random<unsigned>(0, size - 1);

        // use the tester id as offset within the block for false sharing
        offset = blockAlign(offset);
        offset += id;

        if (uncacheable) {
            flags.set(Request::UNCACHEABLE);
            paddr = uncacheAddr + offset;
        } else  {
            paddr = ((base) ? baseAddr1 : baseAddr2) + offset;
        }
    } while (outstandingAddrs.find(paddr) != outstandingAddrs.end());

    bool do_functional = (random_mt.random(0, 100) < percentFunctional) &&
        !uncacheable;
    RequestPtr req = std::make_shared<Request>(paddr, 1, flags, masterId);
    req->setContext(id);

    outstandingAddrs.insert(paddr);

    // sanity check
    panic_if(outstandingAddrs.size() > 100,
             "Tester %s has more than 100 outstanding requests\n", name());

    PacketPtr pkt = nullptr;
    uint8_t *pkt_data = new uint8_t[1];

    if (cmd < percentReads) {
        // start by ensuring there is a reference value if we have not
        // seen this address before
        uint8_t M5_VAR_USED ref_data = 0;
        auto ref = referenceData.find(req->getPaddr());
        if (ref == referenceData.end()) {
            referenceData[req->getPaddr()] = 0;
        } else {
            ref_data = ref->second;
        }

        DPRINTF(MemTest,
                "Initiating %sread at addr %x (blk %x) expecting %x\n",
                do_functional ? "functional " : "", req->getPaddr(),
                blockAlign(req->getPaddr()), ref_data);

        pkt = new Packet(req, MemCmd::ReadReq);
        pkt->dataDynamic(pkt_data);
    } else {
        DPRINTF(MemTest, "Initiating %swrite at addr %x (blk %x) value %x\n",
                do_functional ? "functional " : "", req->getPaddr(),
                blockAlign(req->getPaddr()), data);

        pkt = new Packet(req, MemCmd::WriteReq);
        pkt->dataDynamic(pkt_data);
        pkt_data[0] = data;
    }

    // there is no point in ticking if we are waiting for a retry
    bool keep_ticking = true;
    if (do_functional) {
        pkt->setSuppressFuncError();
        port.sendFunctional(pkt);
        completeRequest(pkt, true);
    } else {
        keep_ticking = sendPkt(pkt);
    }

    if (keep_ticking) {
        // schedule the next tick
        schedule(tickEvent, clockEdge(interval));

        // finally shift the timeout for sending of requests forwards
        // as we have successfully sent a packet
        reschedule(noRequestEvent, clockEdge(progressCheck), true);
    } else {
        DPRINTF(MemTest, "Waiting for retry\n");
    }
}

void
MemTest::noRequest()
{
    panic("%s did not send a request for %d cycles", name(), progressCheck);
}

void
MemTest::noResponse()
{
    panic("%s did not see a response for %d cycles", name(), progressCheck);
}

void
MemTest::recvRetry()
{
    assert(retryPkt);
    if (port.sendTimingReq(retryPkt)) {
        DPRINTF(MemTest, "Proceeding after successful retry\n");

        retryPkt = nullptr;
        // kick things into action again
        schedule(tickEvent, clockEdge(interval));
    }
}

MemTest *
MemTestParams::create()
{
    return new MemTest(this);
}
<commit_msg>cpu: Fix rescheduling of progress check events<commit_after>/*
 * Copyright (c) 2015, 2019 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Erik Hallnor
 *          Steve Reinhardt
 *          Andreas Hansson
 */

#include "cpu/testers/memtest/memtest.hh"

#include "base/random.hh"
#include "base/statistics.hh"
#include "base/trace.hh"
#include "debug/MemTest.hh"
#include "sim/sim_exit.hh"
#include "sim/stats.hh"
#include "sim/system.hh"

using namespace std;

unsigned int TESTER_ALLOCATOR = 0;

bool
MemTest::CpuPort::recvTimingResp(PacketPtr pkt)
{
    memtest.completeRequest(pkt);
    return true;
}

void
MemTest::CpuPort::recvReqRetry()
{
    memtest.recvRetry();
}

bool
MemTest::sendPkt(PacketPtr pkt) {
    if (atomic) {
        port.sendAtomic(pkt);
        completeRequest(pkt);
    } else {
        if (!port.sendTimingReq(pkt)) {
            retryPkt = pkt;
            return false;
        }
    }
    return true;
}

MemTest::MemTest(const Params *p)
    : ClockedObject(p),
      tickEvent([this]{ tick(); }, name()),
      noRequestEvent([this]{ noRequest(); }, name()),
      noResponseEvent([this]{ noResponse(); }, name()),
      port("port", *this),
      retryPkt(nullptr),
      size(p->size),
      interval(p->interval),
      percentReads(p->percent_reads),
      percentFunctional(p->percent_functional),
      percentUncacheable(p->percent_uncacheable),
      masterId(p->system->getMasterId(this)),
      blockSize(p->system->cacheLineSize()),
      blockAddrMask(blockSize - 1),
      progressInterval(p->progress_interval),
      progressCheck(p->progress_check),
      nextProgressMessage(p->progress_interval),
      maxLoads(p->max_loads),
      atomic(p->system->isAtomicMode()),
      suppressFuncWarnings(p->suppress_func_warnings)
{
    id = TESTER_ALLOCATOR++;
    fatal_if(id >= blockSize, "Too many testers, only %d allowed\n",
             blockSize - 1);

    baseAddr1 = 0x100000;
    baseAddr2 = 0x400000;
    uncacheAddr = 0x800000;

    // set up counters
    numReads = 0;
    numWrites = 0;

    // kick things into action
    schedule(tickEvent, curTick());
    schedule(noRequestEvent, clockEdge(progressCheck));
}

Port &
MemTest::getPort(const std::string &if_name, PortID idx)
{
    if (if_name == "port")
        return port;
    else
        return ClockedObject::getPort(if_name, idx);
}

void
MemTest::completeRequest(PacketPtr pkt, bool functional)
{
    const RequestPtr &req = pkt->req;
    assert(req->getSize() == 1);

    // this address is no longer outstanding
    auto remove_addr = outstandingAddrs.find(req->getPaddr());
    assert(remove_addr != outstandingAddrs.end());
    outstandingAddrs.erase(remove_addr);

    DPRINTF(MemTest, "Completing %s at address %x (blk %x) %s\n",
            pkt->isWrite() ? "write" : "read",
            req->getPaddr(), blockAlign(req->getPaddr()),
            pkt->isError() ? "error" : "success");

    const uint8_t *pkt_data = pkt->getConstPtr<uint8_t>();

    if (pkt->isError()) {
        if (!functional || !suppressFuncWarnings) {
            warn("%s access failed at %#x\n",
                 pkt->isWrite() ? "Write" : "Read", req->getPaddr());
        }
    } else {
        if (pkt->isRead()) {
            uint8_t ref_data = referenceData[req->getPaddr()];
            if (pkt_data[0] != ref_data) {
                panic("%s: read of %x (blk %x) @ cycle %d "
                      "returns %x, expected %x\n", name(),
                      req->getPaddr(), blockAlign(req->getPaddr()), curTick(),
                      pkt_data[0], ref_data);
            }

            numReads++;
            numReadsStat++;

            if (numReads == (uint64_t)nextProgressMessage) {
                ccprintf(cerr, "%s: completed %d read, %d write accesses @%d\n",
                         name(), numReads, numWrites, curTick());
                nextProgressMessage += progressInterval;
            }

            if (maxLoads != 0 && numReads >= maxLoads)
                exitSimLoop("maximum number of loads reached");
        } else {
            assert(pkt->isWrite());

            // update the reference data
            referenceData[req->getPaddr()] = pkt_data[0];
            numWrites++;
            numWritesStat++;
        }
    }

    // the packet will delete the data
    delete pkt;

    // finally shift the response timeout forward if we are still
    // expecting responses; deschedule it otherwise
    if (outstandingAddrs.size() != 0)
        reschedule(noResponseEvent, clockEdge(progressCheck));
    else if (noResponseEvent.scheduled())
        deschedule(noResponseEvent);
}

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

    using namespace Stats;

    numReadsStat
        .name(name() + ".num_reads")
        .desc("number of read accesses completed")
        ;

    numWritesStat
        .name(name() + ".num_writes")
        .desc("number of write accesses completed")
        ;
}

void
MemTest::tick()
{
    // we should never tick if we are waiting for a retry
    assert(!retryPkt);

    // create a new request
    unsigned cmd = random_mt.random(0, 100);
    uint8_t data = random_mt.random<uint8_t>();
    bool uncacheable = random_mt.random(0, 100) < percentUncacheable;
    unsigned base = random_mt.random(0, 1);
    Request::Flags flags;
    Addr paddr;

    // generate a unique address
    do {
        unsigned offset = random_mt.random<unsigned>(0, size - 1);

        // use the tester id as offset within the block for false sharing
        offset = blockAlign(offset);
        offset += id;

        if (uncacheable) {
            flags.set(Request::UNCACHEABLE);
            paddr = uncacheAddr + offset;
        } else  {
            paddr = ((base) ? baseAddr1 : baseAddr2) + offset;
        }
    } while (outstandingAddrs.find(paddr) != outstandingAddrs.end());

    bool do_functional = (random_mt.random(0, 100) < percentFunctional) &&
        !uncacheable;
    RequestPtr req = std::make_shared<Request>(paddr, 1, flags, masterId);
    req->setContext(id);

    outstandingAddrs.insert(paddr);

    // sanity check
    panic_if(outstandingAddrs.size() > 100,
             "Tester %s has more than 100 outstanding requests\n", name());

    PacketPtr pkt = nullptr;
    uint8_t *pkt_data = new uint8_t[1];

    if (cmd < percentReads) {
        // start by ensuring there is a reference value if we have not
        // seen this address before
        uint8_t M5_VAR_USED ref_data = 0;
        auto ref = referenceData.find(req->getPaddr());
        if (ref == referenceData.end()) {
            referenceData[req->getPaddr()] = 0;
        } else {
            ref_data = ref->second;
        }

        DPRINTF(MemTest,
                "Initiating %sread at addr %x (blk %x) expecting %x\n",
                do_functional ? "functional " : "", req->getPaddr(),
                blockAlign(req->getPaddr()), ref_data);

        pkt = new Packet(req, MemCmd::ReadReq);
        pkt->dataDynamic(pkt_data);
    } else {
        DPRINTF(MemTest, "Initiating %swrite at addr %x (blk %x) value %x\n",
                do_functional ? "functional " : "", req->getPaddr(),
                blockAlign(req->getPaddr()), data);

        pkt = new Packet(req, MemCmd::WriteReq);
        pkt->dataDynamic(pkt_data);
        pkt_data[0] = data;
    }

    // there is no point in ticking if we are waiting for a retry
    bool keep_ticking = true;
    if (do_functional) {
        pkt->setSuppressFuncError();
        port.sendFunctional(pkt);
        completeRequest(pkt, true);
    } else {
        keep_ticking = sendPkt(pkt);
    }

    if (keep_ticking) {
        // schedule the next tick
        schedule(tickEvent, clockEdge(interval));

        // finally shift the timeout for sending of requests forwards
        // as we have successfully sent a packet
        reschedule(noRequestEvent, clockEdge(progressCheck), true);
    } else {
        DPRINTF(MemTest, "Waiting for retry\n");
    }

    // Schedule noResponseEvent now if we are expecting a response
    if (!noResponseEvent.scheduled() && (outstandingAddrs.size() != 0))
        schedule(noResponseEvent, clockEdge(progressCheck));
}

void
MemTest::noRequest()
{
    panic("%s did not send a request for %d cycles", name(), progressCheck);
}

void
MemTest::noResponse()
{
    panic("%s did not see a response for %d cycles", name(), progressCheck);
}

void
MemTest::recvRetry()
{
    assert(retryPkt);
    if (port.sendTimingReq(retryPkt)) {
        DPRINTF(MemTest, "Proceeding after successful retry\n");

        retryPkt = nullptr;
        // kick things into action again
        schedule(tickEvent, clockEdge(interval));
        reschedule(noRequestEvent, clockEdge(progressCheck), true);
    }
}

MemTest *
MemTestParams::create()
{
    return new MemTest(this);
}
<|endoftext|>