Commit 83078057 authored by Stenger, Florian's avatar Stenger, Florian
Browse files

geo-caching, benchmarking

parent 8912c2e0
......@@ -52,10 +52,10 @@ namespace Dune
// BackupRestoreFacility for CurvedSurfaceGrid
// -------------------------------------------
template< class HostGrid, class CoordFunction, int order, class Allocator >
struct BackupRestoreFacility< CurvedSurfaceGrid< HostGrid, CoordFunction, order, Allocator > >
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator >
struct BackupRestoreFacility< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator > >
{
typedef CurvedSurfaceGrid< HostGrid, CoordFunction, order, Allocator > Grid;
typedef CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator > Grid;
typedef BackupRestoreFacility< HostGrid > HostBackupRestoreFacility;
static void backup ( const Grid &grid, const std::string &filename )
......
......@@ -24,61 +24,61 @@ namespace Dune
// Capabilities from dune-grid
// ---------------------------
template< class HostGrid, class CoordFunction, int order, class Allocator >
struct hasSingleGeometryType< CurvedSurfaceGrid< HostGrid, CoordFunction, order, Allocator > >
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator >
struct hasSingleGeometryType< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator > >
{
static const bool v = hasSingleGeometryType< HostGrid > :: v;
static const unsigned int topologyId = hasSingleGeometryType< HostGrid > :: topologyId;
};
template< class HostGrid, class CoordFunction, int order, class Allocator, int codim >
struct hasEntity< CurvedSurfaceGrid< HostGrid, CoordFunction, order, Allocator >, codim >
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator, int codim >
struct hasEntity< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator >, codim >
{
static const bool v = true;
};
template< class HostGrid, class CoordFunction, int order, class Allocator, int codim >
struct hasEntityIterator< CurvedSurfaceGrid< HostGrid, CoordFunction, order, Allocator >, codim >
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator, int codim >
struct hasEntityIterator< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator >, codim >
{
static const bool v = true;
};
template< class HostGrid, class CoordFunction, int order, class Allocator, int codim >
struct canCommunicate< CurvedSurfaceGrid< HostGrid, CoordFunction, order, Allocator >, codim >
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator, int codim >
struct canCommunicate< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator >, codim >
{
static const bool v = canCommunicate< HostGrid, codim >::v && hasEntity< HostGrid, codim >::v;
};
template< class HostGrid, class CoordFunction, int order, class Allocator >
struct hasBackupRestoreFacilities< CurvedSurfaceGrid< HostGrid, CoordFunction, order, Allocator > >
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator >
struct hasBackupRestoreFacilities< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator > >
{
static const bool v = hasBackupRestoreFacilities< HostGrid >::v;
};
template< class HostGrid, class CoordFunction, int order, class Allocator >
struct isLevelwiseConforming< CurvedSurfaceGrid< HostGrid, CoordFunction, order, Allocator > >
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator >
struct isLevelwiseConforming< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator > >
{
static const bool v = isLevelwiseConforming< HostGrid >::v;
};
template< class HostGrid, class CoordFunction, int order, class Allocator >
struct isLeafwiseConforming< CurvedSurfaceGrid< HostGrid, CoordFunction, order, Allocator > >
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator >
struct isLeafwiseConforming< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator > >
{
static const bool v = isLeafwiseConforming< HostGrid >::v;
};
template< class HostGrid, class CoordFunction, int order, class Allocator >
struct threadSafe< CurvedSurfaceGrid< HostGrid, CoordFunction, order, Allocator > >
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator >
struct threadSafe< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator > >
{
static const bool v = false;
};
template< class HostGrid, class CoordFunction, int order, class Allocator >
struct viewThreadSafe< CurvedSurfaceGrid< HostGrid, CoordFunction, order, Allocator > >
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator >
struct viewThreadSafe< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator > >
{
static const bool v = false;
};
......@@ -88,8 +88,8 @@ namespace Dune
// hasHostEntity
// -------------
template< class HostGrid, class CoordFunction, int order, class Allocator, int codim >
struct hasHostEntity< CurvedSurfaceGrid< HostGrid, CoordFunction, order, Allocator >, codim >
template< class HostGrid, class CoordFunction, int order, bool geoCaching, class Allocator, int codim >
struct hasHostEntity< CurvedSurfaceGrid< HostGrid, CoordFunction, order, geoCaching, Allocator >, codim >
{
static const bool v = hasEntity< HostGrid, codim >::v;
};
......
......@@ -44,7 +44,7 @@ namespace Dune
}
#if COLLECTOR_BENCHMARK != 0
void collector_benchmark(bool fresh_cache){
void collectorBenchmark(bool fresh_cache){
double start_time = dbl_time();
for(auto &input : inputs){
input *= radius_ / input.two_norm();
......@@ -84,7 +84,7 @@ namespace Dune
}
#if COLLECTOR_BENCHMARK != 0
void collector_benchmark(bool fresh_cache){
void collectorBenchmark(bool fresh_cache){
double start_time = dbl_time();
for(auto &input : inputs){
FieldVector<double, 3> direction = input - center_;
......@@ -108,18 +108,24 @@ namespace Dune
//SurfaceDistanceCoordFunction
template<bool cached=true>
struct SurfaceDistanceCoordFunction
: public AnalyticalCoordFunction<double, 3, 3, SurfaceDistanceCoordFunction>
: public AnalyticalCoordFunction<double, 3, 3, SurfaceDistanceCoordFunction<cached> >
{
const bool coordCaching = cached;
//constructor using vtu-reader to read "file"
SurfaceDistanceCoordFunction(const std::string &file, double expansion_width=-1.0, bool no_scaling=false){
SurfaceDistanceCoordFunction(const std::string &file, double expansion_width=-1.0,
bool no_scaling=false) : cache(nullptr){
surface_mesh = new crvsrf::Mesh(2, 3);
read_vtu_file(file, *surface_mesh);
backgrid = new crvsrf::BackGrid(*surface_mesh, expansion_width, no_scaling);
crvsrf::Vertex c_begin, c_end;
surface_mesh->determine_coordinate_extrema(c_begin, c_end);
crvsrf::Vertex c_expansion = (c_end - c_begin) * 0.1;
cache = new crvsrf::VertexMap<crvsrf::Vertex>(c_begin - c_expansion, c_end + c_expansion, 3);
if(cached){
cache = new crvsrf::VertexMap<crvsrf::Vertex>(c_begin - c_expansion, c_end + c_expansion, 3);
}
}
//constructor using a pre-loaded Dune-surface-mesh
......@@ -131,61 +137,75 @@ namespace Dune
//destructor
~SurfaceDistanceCoordFunction(){
delete cache;
if(cached) delete cache;
delete backgrid;
delete surface_mesh;
}
//operator()
FieldVector<double, 3> operator()(const FieldVector<double, 3> &x) const{
#if COLLECTOR_BENCHMARK != 0
inputs.push_back(x);
#endif
crvsrf::Vertex hit_vertex;
crvsrf::Vertex v(x[0], x[1], x[2]);
//uncached
//backgrid->distance_to_surface_3d(v, hit_vertex);
//cached
if(!cache->find_3d(v, hit_vertex)){
backgrid->distance_to_surface_3d(v, hit_vertex);
cache->insert(v, hit_vertex);
//resetCache
void resetCache(crvsrf::Vertex begin = crvsrf::Vertex(),
crvsrf::Vertex end = crvsrf::Vertex(),
double expansion_factor = 0.1){
if(cached){
delete cache;
if(begin.is_origin() && end.is_origin()){
surface_mesh->determine_coordinate_extrema(begin, end);
}
crvsrf::Vertex c_expansion = (end - begin) * expansion_factor;
cache = new crvsrf::VertexMap<crvsrf::Vertex>(begin - c_expansion, end + c_expansion, 3);
}else{
crvsrf::error("Cannot reset cache in uncached SurfaceDistanceCoordFunction!");
}
return {hit_vertex[0], hit_vertex[1], hit_vertex[2]};
}
//operator()
FieldVector<double, 3> operator()(const FieldVector<double, 3> &x) const;
//output_backgrid_dimensions
void output_backgrid_dimensions(){
backgrid->debug_output_dimensions();
}
#if COLLECTOR_BENCHMARK != 0
void collector_benchmark(bool fresh_cache){
if(fresh_cache) cache->clear();
int uncached_cnt = 0;
double start_time = dbl_time();
for(auto &input : inputs){
crvsrf::Vertex hit_vertex;
crvsrf::Vertex v(input[0], input[1], input[2]);
//uncached
/*backgrid->distance_to_surface_3d(v, hit_vertex);
++uncached_cnt;*/
//cached
if(!cache->find_3d(v, hit_vertex)){
void collectorBenchmark(bool fresh_cache){
if(cached){
if(fresh_cache) cache->clear();
int uncached_cnt = 0;
double start_time = dbl_time();
for(auto &input : inputs){
crvsrf::Vertex hit_vertex;
crvsrf::Vertex v(input[0], input[1], input[2]);
if(!cache->find_3d(v, hit_vertex)){
backgrid->distance_to_surface_3d(v, hit_vertex);
cache->insert(v, hit_vertex);
++uncached_cnt;
}
}
double run_time = dbl_time() - start_time;
std::cout << "surfdist time: " << crvsrf::ft(run_time, 11, 9) << ", count: "<< inputs.size()
<< ", uncached: " << uncached_cnt << std::endl;
}else{ //uncached
double start_time = dbl_time();
for(auto &input : inputs){
crvsrf::Vertex hit_vertex;
crvsrf::Vertex v(input[0], input[1], input[2]);
backgrid->distance_to_surface_3d(v, hit_vertex);
cache->insert(v, hit_vertex);
++uncached_cnt;
}
double run_time = dbl_time() - start_time;
std::cout << "surfdist time: " << crvsrf::ft(run_time, 11, 9)
<< ", count: "<< inputs.size() << std::endl;
}
}
#endif
input = {hit_vertex[0], hit_vertex[1], hit_vertex[2]};
#if VERTEXMAP_DEBUG_MODE != 0
void output_vertexmap_statistics(){
if(cached){
cache->debug_output_statistics();
}else{
crvsrf::error("Cannot output vertexmap-statistics in "
"uncached SurfaceDistanceCoordFunction!");
}
double run_time = dbl_time() - start_time;
std::cout << "surfdist time: " << crvsrf::ft(run_time, 11, 9) << ", count: "<< inputs.size()
<< ", uncached: " << uncached_cnt << std::endl;
}
#endif
......@@ -198,6 +218,37 @@ namespace Dune
#endif
};
//operator() (cached)
template<>
inline FieldVector<double, 3> SurfaceDistanceCoordFunction<true>::operator()(
const FieldVector<double, 3> &x) const{
#if COLLECTOR_BENCHMARK != 0
inputs.push_back(x);
#endif
crvsrf::Vertex hit_vertex;
crvsrf::Vertex v(x[0], x[1], x[2]);
if(!cache->find_3d(v, hit_vertex)){
backgrid->distance_to_surface_3d(v, hit_vertex);
cache->insert(v, hit_vertex);
}
return {hit_vertex[0], hit_vertex[1], hit_vertex[2]};
}
//operator() (uncached)
template<>
inline FieldVector<double, 3> SurfaceDistanceCoordFunction<false>::operator()(
const FieldVector<double, 3> &x) const{
#if COLLECTOR_BENCHMARK != 0
inputs.push_back(x);
#endif
crvsrf::Vertex hit_vertex;
crvsrf::Vertex v(x[0], x[1], x[2]);
backgrid->distance_to_surface_3d(v, hit_vertex);
return {hit_vertex[0], hit_vertex[1], hit_vertex[2]};
}
} // namespace Dune
#endif // #ifndef DUNE_CRVSRF_COORDFUNCTIONIMPLEMENTATIONS_HH
......@@ -6,7 +6,7 @@
namespace Dune
{
template< class HostGrid, class CoordFunction, int interpolatory_order, class Allocator >
template< class HostGrid, class CoordFunction, int interpolatoryOrder, bool geoCaching, class Allocator >
class CurvedSurfaceGrid;
} // namespace Dune
......
......@@ -10,6 +10,8 @@
#include <dune/curvedsurfacegrid/capabilities.hh>
#include <dune/curvedsurfacegrid/coordprovider.hh>
#define GEO_CACHE_BENCHMARK 0
namespace Dune
{
......@@ -90,7 +92,6 @@ namespace Dune
//! \b true, if the entity is faked, i.e., if there is no corresponding host entity
static const bool fake = false;
/** \} */
/** \name Types Required by DUNE
......@@ -135,62 +136,71 @@ namespace Dune
EntityBase ()
: hostEntity_()
, grid_( nullptr )
, geo_()
, geo_( nullptr )
{}
EntityBase ( const Grid &grid, const EntitySeed &seed )
: hostEntity_( grid.hostGrid().entity( seed.impl().hostEntitySeed() ) )
, grid_( &grid )
, geo_( nullptr )
{}
EntityBase ( const Grid &grid, const HostElement &hostElement, int i )
: hostEntity_( hostElement.template subEntity<codim>(i) )
, grid_( &grid )
, geo_( nullptr )
{}
EntityBase ( const GeometryImpl &geo, const HostEntity &hostEntity )
: hostEntity_( hostEntity )
, grid_( &geo.grid() )
, geo_( geo )
, geo_( new GeometryImpl( geo ) )
{}
EntityBase ( const GeometryImpl &geo, HostEntity&& hostEntity )
: hostEntity_( std::move( hostEntity ) )
, grid_( &geo.grid() )
, geo_( geo )
, geo_( new GeometryImpl( geo ) )
{}
EntityBase ( const Grid &grid, const HostEntity& hostEntity )
: hostEntity_( hostEntity )
, grid_( &grid )
, geo_( nullptr )
{}
EntityBase ( const Grid &grid, HostEntity&& hostEntity )
: hostEntity_( std::move( hostEntity ) )
, grid_( &grid )
, geo_( nullptr )
{}
EntityBase ( const EntityBase &other )
: hostEntity_( other.hostEntity_ )
, grid_( other.grid_ )
, geo_( other.geo_ )
, geo_( other.geo_? new GeometryImpl( *other.geo_ ) : nullptr )
{}
EntityBase ( EntityBase&& other )
: hostEntity_( std::move( other.hostEntity_ ) )
, grid_( other.grid_ )
, grid_( std::move( other.grid_ ) )
, geo_( std::move( other.geo_ ) )
{}
~EntityBase ()
{
if(geo_ && !grid_->useGeometryCaching) delete geo_;
}
/** \} */
const EntityBase &operator= ( const EntityBase &other )
{
hostEntity_ = other.hostEntity_;
grid_ = other.grid_;
geo_ = other.geo_;
geo_ = other.geo_? new GeometryImpl( *other.geo_ ) : nullptr;
return *this;
}
......@@ -252,10 +262,47 @@ namespace Dune
{
if( !geo_ )
{
CoordProvider coords( hostEntity(), grid().coordFunction() );
geo_ = GeometryImpl( grid(), type(), coords );
Grid &grid_ref = *grid_;
if(grid_->useGeometryCaching)
{
auto &cached_geo =
std::get<codim>(grid_ref.geometryCache_)[id(grid_ref.hostGrid().localIdSet())];
if(cached_geo)
{
#if GEO_CACHE_BENCHMARK != 0
std::cout << "u: " << grid_ref.geo_uncached
<< ", e: " << ++grid_ref.geo_cached_external
<< ", i: " << grid_ref.geo_cached_internal << std::endl;
#endif
geo_ = cached_geo;
}else{
#if GEO_CACHE_BENCHMARK != 0
std::cout << "u: " << ++grid_ref.geo_uncached
<< ", e: " << grid_ref.geo_cached_external
<< ", i: " << grid_ref.geo_cached_internal << std::endl;
#endif
CoordProvider coords( hostEntity(), grid().coordFunction() );
geo_ = new GeometryImpl( grid(), type(), coords );
cached_geo = geo_;
}
}else{
#if GEO_CACHE_BENCHMARK != 0
std::cout << "u: " << ++grid_ref.geo_uncached
<< ", e: " << grid_ref.geo_cached_external
<< ", i: " << grid_ref.geo_cached_internal << std::endl;
#endif
CoordProvider coords( hostEntity(), grid().coordFunction() );
geo_ = new GeometryImpl( grid(), type(), coords );
}
}
return Geometry( geo_ );
#if GEO_CACHE_BENCHMARK != 0
else{
std::cout << "u: " << grid_->geo_uncached
<< ", e: " << grid_->geo_cached_external
<< ", i: " << ++grid_->geo_cached_internal << std::endl;
}
#endif
return Geometry( *geo_ );
}
unsigned int subEntities ( unsigned int cc ) const
......@@ -345,7 +392,7 @@ namespace Dune
private:
HostEntity hostEntity_;
const Grid *grid_;
mutable GeometryImpl geo_;
mutable GeometryImpl *geo_;
};
......@@ -425,32 +472,34 @@ namespace Dune
: hostElement_()
, subEntity_(-1)
, grid_(nullptr)
, geo_()
, geo_( nullptr )
{}
EntityBase(const Grid& grid, const HostElement& hostElement, unsigned int subEntity)
: hostElement_(hostElement)
, subEntity_(subEntity)
, grid_(&grid)
, geo_( nullptr )
{}
EntityBase ( const Grid &grid, const EntitySeed &seed )
: hostElement_( grid.hostGrid().entity( seed.impl().hostElementSeed() ) )
, subEntity_( seed.impl().subEntity() )
, grid_( &grid )
, geo_( nullptr )
{}
EntityBase ( const EntityBase &other )
: hostElement_( other.hostElement_ )
, subEntity_( other.subEntity_ )
, grid_(other.grid_)
, geo_( other.geo_ )
, grid_( other.grid_ )
, geo_( other.geo_? new GeometryImpl( *other.geo_ ) : nullptr )
{}
EntityBase ( EntityBase &&other )
: hostElement_( std::move( other.hostElement_ ) )
, subEntity_( std::move( other.subEntity_ ) )
, grid_( std::move( other.grid_ ) )
, grid_( std::move ( other.grid_ ) )
, geo_( std::move( other.geo_ ) )
{}
......@@ -464,6 +513,11 @@ namespace Dune
DUNE_THROW(Dune::Exception, "CurvedSurfaceGrid: Cannot create fake entity of codim " << codimension << " from real host entity.");
}
~EntityBase ()
{
if(geo_ && !grid_->useGeometryCaching) delete geo_;
}
/** \} */
const EntityBase &operator= ( const EntityBase &other )
......@@ -471,7 +525,7 @@ namespace Dune
hostElement_ = other.hostElement_;
subEntity_ = other.subEntity_;
grid_ = other.grid_;
geo_ = other.geo_;
geo_ = other.geo_? new GeometryImpl( *other.geo_ ) : nullptr;
return *this;
}
......@@ -569,10 +623,47 @@ namespace Dune
{
if( !geo_ )
{
CoordProvider coords( hostElement(), subEntity_, grid().coordFunction() );
geo_ = GeometryImpl( grid(), type(), coords );
Grid &grid_ref = *grid_;
if(grid_->useGeometryCaching)
{
auto &cached_geo =
std::get<codim>(grid_ref.geometryCache_)[id(grid_ref.hostGrid().localIdSet())];
if(cached_geo)
{
#if GEO_CACHE_BENCHMARK != 0
std::cout << "u: " << grid_ref.geo_uncached
<< ", e: " << ++grid_ref.geo_cached_external
<< ", i: " << grid_ref.geo_cached_internal << std::endl;
#endif
geo_ = cached_geo;
}else{
#if GEO_CACHE_BENCHMARK != 0
std::cout << "u: " << ++grid_ref.geo_uncached
<< ", e: " << grid_ref.geo_cached_external
<< ", i: " << grid_ref.geo_cached_internal << std::endl;
#endif
CoordProvider coords( hostElement(), subEntity_, grid().coordFunction() );
geo_ = new GeometryImpl( grid(), type(), coords );
cached_geo = geo_;
}
}else{
#if GEO_CACHE_BENCHMARK != 0
std::cout << "u: " << ++grid_ref.geo_uncached
<< ", e: " << grid_ref.geo_cached_external
<< ", i: " << grid_ref.geo_cached_internal << std::endl;
#endif
CoordProvider coords( hostElement(), subEntity_, grid().coordFunction() );
geo_ = new GeometryImpl( grid(), type(), coords );
}
}
return Geometry( geo_ );
#if GEO_CACHE_BENCHMARK != 0
else{
std::cout << "u: " << grid_->geo_uncached
<< ", e: " << grid_->geo_cached_external
<< ", i: " << ++grid_->geo_cached_internal << std::endl;
}
#endif
return Geometry( *geo_ );
}
unsigned int subEntities ( unsigned int cc ) const
......@@ -681,7 +772,7 @@ namespace Dune
HostElement hostElement_;
unsigned int subEntity_;
const Grid *grid_;
mutable GeometryImpl geo_;
mutable GeometryImpl *geo_;
};
......
......@@ -61,21 +61,23 @@ namespace Dune
* \nosubgrouping
*/
template< class HostGrid, class CoordFunction = DefaultCoordFunction< HostGrid >,