mirror of https://github.com/CGAL/cgal
Add a benchmark
This commit is contained in:
parent
26b312938e
commit
b11c4cc8ff
|
|
@ -0,0 +1,77 @@
|
|||
# Created by the script cgal_create_cmake_script
|
||||
# This is the CMake script for compiling a CGAL application.
|
||||
|
||||
|
||||
project( Tangential_complex_benchmark )
|
||||
|
||||
cmake_minimum_required(VERSION 2.6.2)
|
||||
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_GREATER 2.6)
|
||||
if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_GREATER 2.8.3)
|
||||
cmake_policy(VERSION 2.8.4)
|
||||
else()
|
||||
cmake_policy(VERSION 2.6)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Creates a new CMake option, turned ON by default
|
||||
option(ACTIVATE_MSVC_PRECOMPILED_HEADERS
|
||||
"Activate precompiled headers in MSVC"
|
||||
OFF)
|
||||
|
||||
# Macro to add precompiled headers for MSVC
|
||||
# This function does two things:
|
||||
# 1. Enable precompiled headers on each file which is listed in "SourcesVar".
|
||||
# 2. Add the content of "PrecompiledSource" (e.g. "StdAfx.cpp") to "SourcesVar".
|
||||
MACRO(ADD_MSVC_PRECOMPILED_HEADER PrecompiledHeader PrecompiledSource SourcesVar)
|
||||
IF(MSVC AND ACTIVATE_MSVC_PRECOMPILED_HEADERS)
|
||||
GET_FILENAME_COMPONENT(PrecompiledBasename ${PrecompiledHeader} NAME_WE)
|
||||
SET(Sources ${${SourcesVar}})
|
||||
|
||||
SET_SOURCE_FILES_PROPERTIES(${PrecompiledSource}
|
||||
PROPERTIES COMPILE_FLAGS "/Yc\"${PrecompiledHeader}\"")
|
||||
SET_SOURCE_FILES_PROPERTIES(${Sources}
|
||||
PROPERTIES COMPILE_FLAGS "/Yu\"${PrecompiledHeaders}\" /FI\"${PrecompiledHeader}\"")
|
||||
# Add precompiled header to SourcesVar
|
||||
LIST(APPEND ${SourcesVar} ${PrecompiledSource})
|
||||
ENDIF(MSVC AND ACTIVATE_MSVC_PRECOMPILED_HEADERS)
|
||||
ENDMACRO(ADD_MSVC_PRECOMPILED_HEADER)
|
||||
|
||||
# The compiler might need more memory because of precompiled headers
|
||||
if(MSVC AND ACTIVATE_MSVC_PRECOMPILED_HEADERS AND NOT(MSVC_VERSION LESS 1310))
|
||||
set(CGAL_C_FLAGS "${CGAL_C_FLAGS} /Zm1000")
|
||||
set(CGAL_CXX_FLAGS "${CGAL_CXX_FLAGS} /Zm1000")
|
||||
endif()
|
||||
|
||||
find_package(CGAL QUIET COMPONENTS Core )
|
||||
|
||||
if ( CGAL_FOUND )
|
||||
include( ${CGAL_USE_FILE} )
|
||||
|
||||
find_package( TBB QUIET )
|
||||
|
||||
if( TBB_FOUND )
|
||||
include(${TBB_USE_FILE})
|
||||
list(APPEND CGAL_3RD_PARTY_LIBRARIES ${TBB_LIBRARIES})
|
||||
endif()
|
||||
|
||||
|
||||
include( CGAL_CreateSingleSourceCGALProgram )
|
||||
|
||||
find_package(Eigen3 3.1.0)
|
||||
if (EIGEN3_FOUND)
|
||||
include( ${EIGEN3_USE_FILE} )
|
||||
include_directories (BEFORE "../../include")
|
||||
include_directories (BEFORE "include")
|
||||
|
||||
set (SOURCE_FILES "benchmark_tc.cpp")
|
||||
ADD_MSVC_PRECOMPILED_HEADER("StdAfx.h" "StdAfx.cpp" SOURCE_FILES)
|
||||
create_single_source_cgal_program( ${SOURCE_FILES} )
|
||||
|
||||
else()
|
||||
message(STATUS "NOTICE: Some of the executables in this directory need Eigen 3.1 (or greater) and will not be compiled.")
|
||||
endif()
|
||||
|
||||
else()
|
||||
message(STATUS "This program requires the CGAL library, and will not be compiled.")
|
||||
endif()
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
// Build the precompiled headers.
|
||||
#include "StdAfx.h"
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
#ifndef STDAFX_H
|
||||
#define STDAFX_H
|
||||
|
||||
// CGAL
|
||||
#include <CGAL/Tangential_complex/config.h>
|
||||
#include <CGAL/Epick_d.h>
|
||||
//#include <CGAL/Regular_triangulation_euclidean_traits.h>
|
||||
//#include <CGAL/Regular_triangulation.h>
|
||||
//#include <CGAL/Delaunay_triangulation.h>
|
||||
//#include <CGAL/Tangential_complex/utilities.h>
|
||||
//#include <CGAL/Tangential_complex/Point_cloud.h>
|
||||
#include <CGAL/Combination_enumerator.h>
|
||||
|
||||
#endif //STDAFX_H
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
// Copyright (c) 2012 INRIA Sophia-Antipolis (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
// You can redistribute it and/or modify it under the terms of the GNU
|
||||
// General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL: $
|
||||
// $Id: $
|
||||
//
|
||||
//
|
||||
// Author(s) : Clement Jamin
|
||||
//
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <ctime>
|
||||
|
||||
template<typename value_type = std::string>
|
||||
class Simple_XML_exporter
|
||||
{
|
||||
public:
|
||||
typedef value_type Value_type;
|
||||
typedef std::vector<value_type> Element;
|
||||
typedef std::map<std::string, value_type> Element_with_map;
|
||||
typedef std::vector<Element> List_of_elements;
|
||||
|
||||
Simple_XML_exporter(
|
||||
const std::string &list_name,
|
||||
const std::string &element_name,
|
||||
const std::vector<std::string> &subelement_names,
|
||||
bool add_timestamp = true)
|
||||
: m_list_name(list_name),
|
||||
m_element_name(element_name),
|
||||
m_subelement_names(subelement_names),
|
||||
m_add_timestamp(add_timestamp)
|
||||
{}
|
||||
|
||||
bool add_element(const Element &element)
|
||||
{
|
||||
if (element.size() == m_subelement_names.size())
|
||||
{
|
||||
m_list_of_elements.push_back(element);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "ERROR: element.size() == m_subelement_names.size()" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool add_element(Element_with_map &element)
|
||||
{
|
||||
Element elt;
|
||||
|
||||
std::vector<std::string>::const_iterator
|
||||
it_subelement_name = m_subelement_names.begin();
|
||||
std::vector<std::string>::const_iterator
|
||||
it_subelement_name_end = m_subelement_names.end();
|
||||
for ( ; it_subelement_name != it_subelement_name_end ; ++it_subelement_name)
|
||||
{
|
||||
elt.push_back(element[*it_subelement_name]);
|
||||
}
|
||||
|
||||
return add_element(elt);
|
||||
}
|
||||
|
||||
bool export_to_xml(const std::string &filename) const
|
||||
{
|
||||
std::ofstream xmlfile;
|
||||
xmlfile.open(filename.c_str());
|
||||
xmlfile << "<?xml version='1.0'?>" << std::endl;
|
||||
xmlfile << "<" << m_list_name << ">" << std::endl;
|
||||
|
||||
typename List_of_elements::const_iterator it_element = m_list_of_elements.begin();
|
||||
typename List_of_elements::const_iterator it_element_end = m_list_of_elements.end();
|
||||
for (int id = 1 ; it_element != it_element_end ; ++it_element, ++id)
|
||||
{
|
||||
xmlfile << " <" << m_element_name << ">" << std::endl;
|
||||
std::vector<std::string>::const_iterator
|
||||
it_subelement_name = m_subelement_names.begin();
|
||||
std::vector<std::string>::const_iterator
|
||||
it_subelement_name_end = m_subelement_names.end();
|
||||
|
||||
if (m_add_timestamp)
|
||||
xmlfile << " <id> " << time(NULL) << " </id>" << std::endl;
|
||||
|
||||
for (int i = 0 ;
|
||||
it_subelement_name != it_subelement_name_end ;
|
||||
++it_subelement_name, ++i)
|
||||
{
|
||||
xmlfile
|
||||
<< " <" << *it_subelement_name << "> "
|
||||
<< (*it_element)[i]
|
||||
<< " </" << *it_subelement_name << ">" << std::endl;
|
||||
}
|
||||
xmlfile << " </" << m_element_name << ">" << std::endl;
|
||||
}
|
||||
|
||||
xmlfile << "</" << m_list_name << ">" << std::endl;
|
||||
xmlfile.close();
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
protected:
|
||||
std::string m_list_name;
|
||||
std::string m_element_name;
|
||||
std::vector<std::string> m_subelement_names;
|
||||
List_of_elements m_list_of_elements;
|
||||
bool m_add_timestamp;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
template<typename value_type = std::string>
|
||||
class Streaming_XML_exporter
|
||||
{
|
||||
public:
|
||||
typedef value_type Value_type;
|
||||
typedef std::vector<value_type> Element;
|
||||
typedef std::map<std::string, value_type> Element_with_map;
|
||||
typedef std::vector<Element> List_of_elements;
|
||||
|
||||
Streaming_XML_exporter(
|
||||
const std::string &filename,
|
||||
const std::string &list_name,
|
||||
const std::string &element_name,
|
||||
const std::vector<std::string> &subelement_names,
|
||||
bool add_timestamp = true)
|
||||
: m_list_name(list_name),
|
||||
m_element_name(element_name),
|
||||
m_subelement_names(subelement_names),
|
||||
m_add_timestamp(add_timestamp)
|
||||
{
|
||||
m_xml_fstream.open(filename.c_str());
|
||||
if (m_xml_fstream.good())
|
||||
{
|
||||
m_xml_fstream << "<?xml version='1.0'?>" << std::endl;
|
||||
m_xml_fstream << "<" << m_list_name << ">" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "Could not open file '" << filename << "'." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
virtual ~Streaming_XML_exporter()
|
||||
{
|
||||
close_file();
|
||||
}
|
||||
|
||||
void close_file()
|
||||
{
|
||||
m_xml_fstream.close();
|
||||
}
|
||||
|
||||
bool add_element(const Element &element)
|
||||
{
|
||||
if (element.size() == m_subelement_names.size())
|
||||
{
|
||||
m_xml_fstream << " <" << m_element_name << ">" << std::endl;
|
||||
std::vector<std::string>::const_iterator
|
||||
it_subelement_name = m_subelement_names.begin();
|
||||
std::vector<std::string>::const_iterator
|
||||
it_subelement_name_end = m_subelement_names.end();
|
||||
|
||||
if (m_add_timestamp)
|
||||
{
|
||||
m_xml_fstream << " <id> " << time(NULL) << " </id>" << std::endl;
|
||||
}
|
||||
|
||||
for (int i = 0 ;
|
||||
it_subelement_name != it_subelement_name_end ;
|
||||
++it_subelement_name, ++i)
|
||||
{
|
||||
m_xml_fstream
|
||||
<< " <" << *it_subelement_name << "> "
|
||||
<< element[i]
|
||||
<< " </" << *it_subelement_name << ">" << std::endl;
|
||||
}
|
||||
m_xml_fstream << " </" << m_element_name << ">" << std::endl;
|
||||
|
||||
// Save current pointer position
|
||||
std::ofstream::streampos pos = m_xml_fstream.tellp();
|
||||
// Close the XML file (temporarily) so that the XML file is always correct
|
||||
m_xml_fstream << "</" << m_list_name << ">" << std::endl;
|
||||
// Restore the pointer position so that the next "add_element" will overwrite
|
||||
// the end of the file
|
||||
m_xml_fstream.seekp(pos);
|
||||
|
||||
m_xml_fstream.flush();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << "ERROR: element.size() == m_subelement_names.size()" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool add_element(Element_with_map &element)
|
||||
{
|
||||
Element elt;
|
||||
|
||||
std::vector<std::string>::const_iterator
|
||||
it_subelement_name = m_subelement_names.begin();
|
||||
std::vector<std::string>::const_iterator
|
||||
it_subelement_name_end = m_subelement_names.end();
|
||||
for ( ; it_subelement_name != it_subelement_name_end ; ++it_subelement_name)
|
||||
{
|
||||
elt.push_back(element[*it_subelement_name]);
|
||||
}
|
||||
|
||||
return add_element(elt);
|
||||
}
|
||||
|
||||
protected:
|
||||
std::ofstream m_xml_fstream;
|
||||
std::string m_list_name;
|
||||
std::string m_element_name;
|
||||
std::vector<std::string> m_subelement_names;
|
||||
bool m_add_timestamp;
|
||||
};
|
||||
|
|
@ -0,0 +1,216 @@
|
|||
#include <CGAL/Epick_d.h>
|
||||
#include <CGAL/Tangential_complex.h>
|
||||
#include <CGAL/Random.h>
|
||||
#include <CGAL/Mesh_3/Profiling_tools.h>
|
||||
|
||||
#include "../../test/Tangential_complex/test_utilities.h"
|
||||
|
||||
|
||||
#include <fstream>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef CGAL_LINKED_WITH_TBB
|
||||
# include <tbb/task_scheduler_init.h>
|
||||
#endif
|
||||
#include "XML_exporter.h"
|
||||
#define CGAL_TC_EXPORT_PERFORMANCE_DATA
|
||||
#define CGAL_TC_SET_PERFORMANCE_DATA(value_name, value) \
|
||||
XML_perf_data::set(value_name, value);
|
||||
|
||||
class XML_perf_data
|
||||
{
|
||||
public:
|
||||
typedef Streaming_XML_exporter<std::string> XML_exporter;
|
||||
|
||||
XML_perf_data(const std::string &filename)
|
||||
: m_xml(filename, "ContainerPerformance", "Perf",
|
||||
construct_subelements_names())
|
||||
{}
|
||||
|
||||
virtual ~XML_perf_data()
|
||||
{
|
||||
}
|
||||
|
||||
static XML_perf_data &get()
|
||||
{
|
||||
static XML_perf_data singleton(build_filename());
|
||||
return singleton;
|
||||
}
|
||||
|
||||
template <typename Value_type>
|
||||
static void set(const std::string &name, Value_type value)
|
||||
{
|
||||
get().set_data(name, value);
|
||||
}
|
||||
|
||||
static void commit()
|
||||
{
|
||||
get().commit_current_element();
|
||||
}
|
||||
|
||||
protected:
|
||||
static std::string build_filename()
|
||||
{
|
||||
std::stringstream sstr;
|
||||
sstr << "Performance_log_" << time(0) << ".xml";
|
||||
return sstr.str();
|
||||
}
|
||||
|
||||
static std::vector<std::string> construct_subelements_names()
|
||||
{
|
||||
std::vector<std::string> subelements;
|
||||
subelements.push_back("Name");
|
||||
subelements.push_back("Intrinsic_dim");
|
||||
subelements.push_back("Ambient_dim");
|
||||
subelements.push_back("Num_points");
|
||||
subelements.push_back("Noise");
|
||||
subelements.push_back("Init_time");
|
||||
subelements.push_back("Comput_time");
|
||||
subelements.push_back("Fix_time");
|
||||
|
||||
return subelements;
|
||||
}
|
||||
|
||||
void set_data(const std::string &name, const std::string &value)
|
||||
{
|
||||
m_current_element[name] = value;
|
||||
}
|
||||
|
||||
template <typename Value_type>
|
||||
void set_data(const std::string &name, Value_type value)
|
||||
{
|
||||
std::stringstream sstr;
|
||||
sstr << value;
|
||||
set_data(name, sstr.str());
|
||||
}
|
||||
|
||||
void commit_current_element()
|
||||
{
|
||||
m_xml.add_element(m_current_element);
|
||||
m_current_element.clear();
|
||||
}
|
||||
|
||||
XML_exporter m_xml;
|
||||
XML_exporter::Element_with_map m_current_element;
|
||||
};
|
||||
|
||||
#ifdef _DEBUG
|
||||
const int NUM_POINTS = 50;
|
||||
#else
|
||||
const int NUM_POINTS = 30000;
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifdef CGAL_LINKED_WITH_TBB
|
||||
# ifdef _DEBUG
|
||||
tbb::task_scheduler_init init(1);
|
||||
# else
|
||||
tbb::task_scheduler_init init(10);
|
||||
# endif
|
||||
#endif
|
||||
|
||||
const int INTRINSIC_DIMENSION = 2;
|
||||
const int AMBIENT_DIMENSION = 4;
|
||||
|
||||
typedef CGAL::Epick_d<CGAL::Dimension_tag<AMBIENT_DIMENSION> > Kernel;
|
||||
typedef Kernel::FT FT;
|
||||
typedef Kernel::Point_d Point;
|
||||
|
||||
int i = 0;
|
||||
bool stop = false;
|
||||
//for ( ; !stop ; ++i)
|
||||
{
|
||||
Kernel k;
|
||||
Wall_clock_timer t;
|
||||
CGAL::default_random = CGAL::Random(i);
|
||||
std::cerr << "Random seed = " << i << std::endl;
|
||||
|
||||
#ifdef CGAL_TC_PROFILING
|
||||
Wall_clock_timer t_gen;
|
||||
#endif
|
||||
//std::vector<Point> points;
|
||||
//load_points_from_file<Point>(
|
||||
// "data/points_10_10k.cin", std::back_inserter(points)/*, 600*/);
|
||||
|
||||
std::vector<Point> points =
|
||||
//generate_points_on_circle_2<Kernel>(NUM_POINTS, 3.);
|
||||
//generate_points_on_moment_curve<Kernel>(NUM_POINTS, AMBIENT_DIMENSION, 0., 1.);
|
||||
//generate_points_on_plane<Kernel>(NUM_POINTS);
|
||||
//generate_points_on_sphere_3<Kernel>(NUM_POINTS, 3.0);
|
||||
//generate_points_on_sphere_d<Kernel>(NUM_POINTS, AMBIENT_DIMENSION, 3.0);
|
||||
//generate_points_on_klein_bottle_3D<Kernel>(NUM_POINTS, 4., 3.);
|
||||
generate_points_on_klein_bottle_4D<Kernel>(NUM_POINTS, 4., 3.);
|
||||
//generate_points_on_klein_bottle_variant_5D<Kernel>(NUM_POINTS, 4., 3.);
|
||||
|
||||
|
||||
CGAL_TC_SET_PERFORMANCE_DATA("Name", "Klein bottle 4D");
|
||||
CGAL_TC_SET_PERFORMANCE_DATA("Intrinsic_dim", INTRINSIC_DIMENSION);
|
||||
CGAL_TC_SET_PERFORMANCE_DATA("Ambient_dim", AMBIENT_DIMENSION);
|
||||
CGAL_TC_SET_PERFORMANCE_DATA("Noise", 0.01);
|
||||
|
||||
#ifdef CGAL_TC_PROFILING
|
||||
std::cerr << "Point set generated in " << t_gen.elapsed()
|
||||
<< " seconds." << std::endl;
|
||||
#endif
|
||||
|
||||
std::cerr << "Number of points before sparsification: "
|
||||
<< points.size() << std::endl;
|
||||
//points = sparsify_point_set(
|
||||
// k, points, FT(INPUT_SPARSITY)*FT(INPUT_SPARSITY));
|
||||
std::cerr << "Number of points after sparsification: "
|
||||
<< points.size() << std::endl;
|
||||
|
||||
CGAL::Tangential_complex<
|
||||
Kernel,
|
||||
INTRINSIC_DIMENSION,
|
||||
CGAL::Parallel_tag> tc(points.begin(), points.end(), k);
|
||||
double init_time = t.elapsed(); t.reset();
|
||||
|
||||
//tc.estimate_intrinsic_dimension();
|
||||
tc.compute_tangential_complex();
|
||||
double computation_time = t.elapsed(); t.reset();
|
||||
|
||||
std::set<std::set<std::size_t> > incorrect_simplices;
|
||||
//stop = !tc.check_if_all_simplices_are_in_the_ambient_delaunay(&incorrect_simplices);
|
||||
|
||||
t.reset();
|
||||
tc.fix_inconsistencies();
|
||||
double fix_time = t.elapsed(); t.reset();
|
||||
|
||||
double export_time = -1.;
|
||||
if (INTRINSIC_DIMENSION <= 3)
|
||||
{
|
||||
t.reset();
|
||||
std::stringstream output_filename;
|
||||
output_filename << "data/test_tc_" << INTRINSIC_DIMENSION
|
||||
<< "_in_R" << AMBIENT_DIMENSION << ".off";
|
||||
std::ofstream off_stream(output_filename.str().c_str());
|
||||
tc.export_to_off(off_stream, true, &incorrect_simplices, true);
|
||||
double export_time = t.elapsed(); t.reset();
|
||||
}
|
||||
/*else
|
||||
tc.number_of_inconsistent_simplices();*/
|
||||
|
||||
|
||||
std::cerr << std::endl
|
||||
<< "================================================" << std::endl
|
||||
<< "Number of vertices: " << tc.number_of_vertices() << std::endl
|
||||
<< "Computation times (seconds): " << std::endl
|
||||
<< " * Tangential complex: " << init_time + computation_time
|
||||
<< std::endl
|
||||
<< " - Init + kd-tree = " << init_time << std::endl
|
||||
<< " - TC computation = " << computation_time << std::endl
|
||||
<< " * Fix inconsistencies: " << fix_time << std::endl
|
||||
<< " * Export to OFF: " << export_time << std::endl
|
||||
<< "================================================" << std::endl
|
||||
<< std::endl;
|
||||
|
||||
CGAL_TC_SET_PERFORMANCE_DATA("Num_points", tc.number_of_vertices());
|
||||
CGAL_TC_SET_PERFORMANCE_DATA("Init_time", init_time);
|
||||
CGAL_TC_SET_PERFORMANCE_DATA("Comput_time", computation_time);
|
||||
CGAL_TC_SET_PERFORMANCE_DATA("Fix_time", fix_time);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in New Issue