Skip to content

Commit

Permalink
Merge pull request #167 from cgogn/develop
Browse files Browse the repository at this point in the history
Develop
  • Loading branch information
pierrekraemer committed Mar 24, 2016
2 parents 60ff8e7 + 8c3ba0f commit 18c18c3
Show file tree
Hide file tree
Showing 583 changed files with 81,284 additions and 4,198 deletions.
74 changes: 56 additions & 18 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ project(CGoGN
LANGUAGES CXX C
)

enable_testing()

#### Default build type
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()


#### CGoGN PATH
set(CGOGN_PATH "${CMAKE_CURRENT_SOURCE_DIR}")
#### Here are located the FindPackages that we need
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")

Expand All @@ -27,7 +30,7 @@ include(cmake/EnableCoverageReport.cmake)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib)
set(CGOGN_SOURCE_DIR ${CMAKE_SOURCE_DIR}/cgogn)
set(CGOGN_SOURCE_DIR ${CGOGN_PATH}/cgogn)

### External Templates
option(CGOGN_EXTERNAL_TEMPLATES "Use external templates to reduce compile time" OFF)
Expand All @@ -36,17 +39,30 @@ if(${CGOGN_EXTERNAL_TEMPLATES})
endif()

#### ThirdParty options
set(CGOGN_THIRDPARTY_DIR ${CMAKE_SOURCE_DIR}/thirdparty)
option(CGOGN_PROVIDE_EIGEN "Use the version of eigen that is packaged with CGoGN" ON)
option(CGOGN_PROVIDE_TINYXML2 "Use the version of tinyxml2 that is packaged with CGoGN" ON)
option(CGOGN_BUILD_TESTS "build cgogn unit tests using google test framework" ON)
option(CGOGN_USE_OPENMP "activate openMP directives" OFF)
option(CGOGN_USE_PARALLEL_GLIBCXX "highly experimental : compiles using the parallel mode" OFF)
set(CGOGN_THIRDPARTY_DIR ${CGOGN_PATH}/thirdparty)
option(CGOGN_PROVIDE_EIGEN "Use the version of eigen that is packaged with CGoGN." ON)
option(CGOGN_PROVIDE_TINYXML2 "Use the version of tinyxml2 that is packaged with CGoGN." ON)
option(CGOGN_BUILD_TESTS "Build cgogn unit tests using google test framework." ON)
option(CGOGN_BUILD_BENCHS "Build the benchmarks using google benchmark framework." ON)
option(CGOGN_USE_OPENMP "Activate openMP directives." OFF)
if (NOT MSVC)
option(CGOGN_USE_GLIBCXX_DEBUG "Use the debug version of STL (useful for bounds checking)." OFF)
option(CGOGN_USE_GLIBCXX_DEBUG_PEDANTIC "Use an extremely picky debug version of STL." OFF)
option(CGOGN_USE_PARALLEL_GLIBCXX "Highly experimental : compiles using the parallel mode." OFF)
if (${CGOGN_USE_GLIBCXX_DEBUG_PEDANTIC})
set(CGOGN_USE_GLIBCXX_DEBUG "ON")
endif(${CGOGN_USE_GLIBCXX_DEBUG_PEDANTIC})
option(CGOGN_USE_CXX11_ABI "use the CXX11 ABI." ON)
endif(NOT MSVC)
if (${CGOGN_USE_PARALLEL_GLIBCXX})
set(CGOGN_USE_OPENMP "ON")
endif()
option(CGOGN_USE_QT "use Qt (5.4 min) for interface & rendering" ON)

option(CGOGN_WITH_CGAL_EXAMPLES "Build the examples using cgal for mesh generation." OFF)
if ((NOT MSVC) AND CGOGN_WITH_CGAL_EXAMPLES)
set(CGOGN_USE_GLIBCXX_DEBUG OFF)
set(CGOGN_USE_GLIBCXX_DEBUG_PEDANTIC OFF)
endif()

#### Continuous integration options
option(CGOGN_WITH_GPROF "Builds the project for performance analysis with gprof" OFF)
Expand Down Expand Up @@ -80,8 +96,15 @@ deduce_build_type()

if(${CGOGN_USE_OPENMP})
find_package(OpenMP)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
if(${OPENMP_FOUND})
add_flags(CMAKE_C_FLAGS ${OpenMP_C_FLAGS})
add_flags(CMAKE_CXX_FLAGS ${OpenMP_CXX_FLAGS})
else()
if ((${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") AND (NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.7")))
add_flags(CMAKE_C_FLAGS "-fopenmp")
add_flags(CMAKE_CXX_FLAGS "-fopenmp")
endif()
endif()
endif()

if(CGOGN_BUILD_TESTS)
Expand All @@ -91,9 +114,24 @@ if(CGOGN_BUILD_TESTS)
endif()
endif(CGOGN_BUILD_TESTS)

#### Endianness detection
include (TestBigEndian)
test_big_endian(CGOGN_TEST_BIG_ENDIAN)
add_definitions("-DCGOGN_LITTLE_ENDIAN=1234")
add_definitions("-DCGOGN_BIG_ENDIAN=4321")
if(${CGOGN_TEST_BIG_ENDIAN})
add_definitions("-DCGOGN_ENDIANNESS=CGOGN_BIG_ENDIAN")
else()
add_definitions("-DCGOGN_ENDIANNESS=CGOGN_LITTLE_ENDIAN")
endif()


add_subdirectory(${CGOGN_THIRDPARTY_DIR})
add_subdirectory(${CGOGN_SOURCE_DIR})

if(${CGOGN_BUILD_BENCHS})
add_subdirectory(benchmarks)
endif(${CGOGN_BUILD_BENCHS})


## TODO a mettre dans un fichier cmake particulier
Expand All @@ -102,10 +140,10 @@ add_subdirectory(${CGOGN_SOURCE_DIR})
ENABLE_COVERAGE_REPORT(TARGETS ${CGOGN_SOURCE_DIR})

# --- CPPCheck ---
GENERATE_CPPCHECK( SOURCES ${CGOGN_SOURCE_DIR}
ENABLE_IDS all
INCLUDES ${CGOGN_SOURCE_DIR}
PLATFORM_FLAGS "-UNDEBUG -UWIN32 -U__func__ -U__FUNCTION__ -U__GNUG__ -U__clang__ -U_MSC_VER"
SYSTEM_INCLUDE_WARNING_SUPPRESSION
INLINE_SUPPRESSION
HTML_REPORT)
GENERATE_CPPCHECK( SOURCES ${CGOGN_SOURCE_DIR}
ENABLE_IDS all
INCLUDES ${CGOGN_SOURCE_DIR}
PLATFORM_FLAGS "-UNDEBUG -UWIN32 -U__func__ -U__FUNCTION__ -U__GNUG__ -U__clang__ -U_MSC_VER"
SYSTEM_INCLUDE_WARNING_SUPPRESSION
INLINE_SUPPRESSION
HTML_REPORT)
1 change: 1 addition & 0 deletions benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_subdirectory(multithreading)
12 changes: 12 additions & 0 deletions benchmarks/multithreading/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)

project(bench_multithreading
LANGUAGES CXX
)

set(CGOGN_TEST_MESHES_PATH "${CMAKE_SOURCE_DIR}/data/meshes/")
add_definitions("-DCGOGN_TEST_MESHES_PATH=${CGOGN_TEST_MESHES_PATH}")

add_executable(${PROJECT_NAME} bench_multithreading.cpp)
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/thirdparty/google-benchmark/include)
target_link_libraries(${PROJECT_NAME} cgogn_core cgogn_io cgogn_geometry benchmark)
244 changes: 244 additions & 0 deletions benchmarks/multithreading/bench_multithreading.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* Copyright (C) 2015, IGG Group, ICube, University of Strasbourg, France *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of 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. *
* *
* 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 GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: http://cgogn.unistra.fr/ *
* Contact information: [email protected] *
* *
*******************************************************************************/

#include <chrono>
#include <vector>

#include <core/cmap/cmap2.h>
#include <io/map_import.h>
#include <geometry/algos/normal.h>

#include <benchmark/benchmark.h>

#define DEFAULT_MESH_PATH CGOGN_STR(CGOGN_TEST_MESHES_PATH)

using namespace cgogn::numerics;


using Map2 = cgogn::CMap2<cgogn::DefaultMapTraits>;
Map2 bench_map;

using Vertex = Map2::Vertex;
const cgogn::Orbit VERTEX = Vertex::ORBIT;

using Face = Map2::Face;
const cgogn::Orbit FACE = Face::ORBIT;

const uint32 ITERATIONS = 1u;

//using Vec3 = Eigen::Vector3d;
using Vec3 = cgogn::geometry::Vec_T<std::array<float64,3>>;

template <typename T>
using VertexAttributeHandler = Map2::VertexAttributeHandler<T>;
template <typename T>
using FaceAttributeHandler = Map2::FaceAttributeHandler<T>;

static void BENCH_Dart_count_single_threaded(benchmark::State& state)
{
while (state.KeepRunning())
{
unsigned nb_darts = 0u;
bench_map.foreach_dart([&nb_darts] (cgogn::Dart) { nb_darts++; });
}
}

static void BENCH_Dart_count_multi_threaded(benchmark::State& state)
{
while (state.KeepRunning())
{
uint32 nb_darts_2 = 0u;
std::vector<uint32> nb_darts_per_thread(cgogn::get_nb_threads()+2);
for (auto& n : nb_darts_per_thread)
n = 0u;
nb_darts_2 = 0u;
bench_map.parallel_foreach_dart([&nb_darts_per_thread] (cgogn::Dart, uint32 thread_index)
{
nb_darts_per_thread[thread_index]++;
});
for (uint32 n : nb_darts_per_thread)
nb_darts_2 += n;

cgogn_assert(nb_darts_2 == bench_map.nb_darts());
}
}

template<cgogn::TraversalStrategy STRATEGY>
static void BENCH_faces_normals_single_threaded(benchmark::State& state)
{
while(state.KeepRunning())
{
state.PauseTiming();
VertexAttributeHandler<Vec3> vertex_position = bench_map.get_attribute<Vec3, VERTEX>("position");
cgogn_assert(vertex_position.is_valid());
FaceAttributeHandler<Vec3> face_normal = bench_map.get_attribute<Vec3, FACE>("normal");
cgogn_assert(face_normal.is_valid());
state.ResumeTiming();

bench_map.template foreach_cell<STRATEGY>([&] (Face f)
{
face_normal[f] = cgogn::geometry::face_normal<Vec3>(bench_map, f, vertex_position);
});
}
}

template<cgogn::TraversalStrategy STRATEGY>
static void BENCH_faces_normals_multi_threaded(benchmark::State& state)
{
while(state.KeepRunning())
{
state.PauseTiming();
VertexAttributeHandler<Vec3> vertex_position = bench_map.get_attribute<Vec3, VERTEX>("position");
cgogn_assert(vertex_position.is_valid());
FaceAttributeHandler<Vec3> face_normal_mt = bench_map.get_attribute<Vec3, FACE>("normal_mt");
cgogn_assert(face_normal_mt.is_valid());
state.ResumeTiming();

bench_map.template parallel_foreach_cell<STRATEGY>([&] (Face f,uint32)
{
face_normal_mt[f] = cgogn::geometry::face_normal<Vec3>(bench_map, f, vertex_position);
});

{
state.PauseTiming();

FaceAttributeHandler<Vec3> face_normal = bench_map.get_attribute<Vec3, FACE>("normal");
bench_map.template foreach_cell<cgogn::TraversalStrategy::FORCE_DART_MARKING>([&] (Face f)
{
Vec3 error = face_normal[f] - face_normal_mt[f];
if (!cgogn::almost_equal_absolute(error.squaredNorm(), 0., 1e-9 ))
{
std::cerr << __FILE__ << ":" << __LINE__ << " : there was an error during computation of normals" << std::endl;
// std::cerr << "face_normal " << face_normal[f] << std::endl;
// std::cerr << "face_normal_mt " << face_normal_mt[f] << std::endl;
}

});
state.ResumeTiming();
}

}
}


template<cgogn::TraversalStrategy STRATEGY>
static void BENCH_vertices_normals_single_threaded(benchmark::State& state)
{
while(state.KeepRunning())
{
state.PauseTiming();
VertexAttributeHandler<Vec3> vertex_position = bench_map.get_attribute<Vec3, VERTEX>("position");
cgogn_assert(vertex_position.is_valid());
VertexAttributeHandler<Vec3> vartices_normal = bench_map.get_attribute<Vec3, VERTEX>("normal");
cgogn_assert(vartices_normal.is_valid());
state.ResumeTiming();

bench_map.template foreach_cell<STRATEGY>([&] (Vertex v)
{
vartices_normal[v] = cgogn::geometry::vertex_normal<Vec3>(bench_map, v, vertex_position);
});
}
}

template<cgogn::TraversalStrategy STRATEGY>
static void BENCH_vertices_normals_multi_threaded(benchmark::State& state)
{
while(state.KeepRunning())
{
state.PauseTiming();
VertexAttributeHandler<Vec3> vertex_position = bench_map.get_attribute<Vec3, VERTEX>("position");
cgogn_assert(vertex_position.is_valid());
VertexAttributeHandler<Vec3> vertices_normal_mt = bench_map.get_attribute<Vec3, VERTEX>("normal_mt");
cgogn_assert(vertices_normal_mt.is_valid());
state.ResumeTiming();

bench_map.template parallel_foreach_cell<STRATEGY>([&] (Vertex v, uint32)
{
vertices_normal_mt[v] = cgogn::geometry::vertex_normal<Vec3>(bench_map, v, vertex_position);
});

{
state.PauseTiming();

VertexAttributeHandler<Vec3> vertices_normal = bench_map.get_attribute<Vec3, VERTEX>("normal");
bench_map.template foreach_cell<cgogn::TraversalStrategy::FORCE_DART_MARKING>([&] (Vertex v)
{
Vec3 error = vertices_normal[v] - vertices_normal_mt[v];
if (!cgogn::almost_equal_absolute(error.squaredNorm(), 0., 1e-9 ))
{
std::cerr << __FILE__ << ":" << __LINE__ << " : there was an error during computation of vertices normals" << std::endl;
// std::cerr << "vertices_normal " << vertices_normal[v] << std::endl;
// std::cerr << "vertices_normal_mt " << vertices_normal_mt[v] << std::endl;
}

});
state.ResumeTiming();
}
}
}

BENCHMARK(BENCH_Dart_count_single_threaded);
BENCHMARK(BENCH_Dart_count_multi_threaded)->UseRealTime();

BENCHMARK_TEMPLATE(BENCH_faces_normals_single_threaded, cgogn::TraversalStrategy::FORCE_DART_MARKING)->UseRealTime();
BENCHMARK_TEMPLATE(BENCH_faces_normals_multi_threaded, cgogn::TraversalStrategy::FORCE_DART_MARKING)->UseRealTime();
BENCHMARK_TEMPLATE(BENCH_faces_normals_single_threaded, cgogn::TraversalStrategy::FORCE_CELL_MARKING)->UseRealTime();
BENCHMARK_TEMPLATE(BENCH_faces_normals_multi_threaded, cgogn::TraversalStrategy::FORCE_CELL_MARKING)->UseRealTime();
BENCHMARK_TEMPLATE(BENCH_faces_normals_single_threaded, cgogn::TraversalStrategy::FORCE_TOPO_CACHE)->UseRealTime();
BENCHMARK_TEMPLATE(BENCH_faces_normals_multi_threaded, cgogn::TraversalStrategy::FORCE_TOPO_CACHE)->UseRealTime();

BENCHMARK_TEMPLATE(BENCH_vertices_normals_single_threaded, cgogn::TraversalStrategy::FORCE_DART_MARKING)->UseRealTime();
BENCHMARK_TEMPLATE(BENCH_vertices_normals_multi_threaded, cgogn::TraversalStrategy::FORCE_DART_MARKING)->UseRealTime();
BENCHMARK_TEMPLATE(BENCH_vertices_normals_single_threaded, cgogn::TraversalStrategy::FORCE_CELL_MARKING)->UseRealTime();
BENCHMARK_TEMPLATE(BENCH_vertices_normals_multi_threaded, cgogn::TraversalStrategy::FORCE_CELL_MARKING)->UseRealTime();
BENCHMARK_TEMPLATE(BENCH_vertices_normals_single_threaded, cgogn::TraversalStrategy::FORCE_TOPO_CACHE)->UseRealTime();
BENCHMARK_TEMPLATE(BENCH_vertices_normals_multi_threaded, cgogn::TraversalStrategy::FORCE_TOPO_CACHE)->UseRealTime();


int main(int argc, char** argv)
{
::benchmark::Initialize(&argc, argv);
std::string surfaceMesh;

if (argc < 2)
{
std::cout << "USAGE: " << argv[0] << " [filename]" << std::endl;
surfaceMesh = std::string(DEFAULT_MESH_PATH) + std::string("aneurysm3D_1.off");
std::cout << "Using default mesh : " << surfaceMesh << std::endl;
}
else
surfaceMesh = std::string(argv[1]);

cgogn::io::import_surface<Vec3>(bench_map, surfaceMesh);

bench_map.add_attribute<Vec3, FACE>("normal");
bench_map.add_attribute<Vec3, FACE>("normal_mt");
bench_map.add_attribute<Vec3, VERTEX>("normal");
bench_map.add_attribute<Vec3, VERTEX>("normal_mt");
bench_map.enable_topo_cache<FACE>();
bench_map.enable_topo_cache<VERTEX>();

::benchmark::RunSpecifiedBenchmarks();
return 0;
}

1 change: 1 addition & 0 deletions cgogn/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ if(CGOGN_USE_QT)
add_subdirectory(rendering)
endif(CGOGN_USE_QT)

add_subdirectory(multiresolution)
Loading

0 comments on commit 18c18c3

Please sign in to comment.