Add a benchmark

This commit is contained in:
Clement Jamin 2014-12-18 20:26:02 +01:00
parent 26b312938e
commit b11c4cc8ff
5 changed files with 545 additions and 0 deletions

View File

@ -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()

View File

@ -0,0 +1,2 @@
// Build the precompiled headers.
#include "StdAfx.h"

View File

@ -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

View File

@ -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;
};

View File

@ -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;
}