diff --git a/Mesh_3/benchmark/Mesh_3/CMakeLists.txt b/Mesh_3/benchmark/Mesh_3/CMakeLists.txt index 50b7730178e6..e7cbc4e5b585 100644 --- a/Mesh_3/benchmark/Mesh_3/CMakeLists.txt +++ b/Mesh_3/benchmark/Mesh_3/CMakeLists.txt @@ -4,52 +4,18 @@ cmake_minimum_required(VERSION 3.1...3.23) project(Mesh_3_benchmark) -# 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 REQUIRED COMPONENTS ImageIO) -include_directories(../../../Triangulation_3/include) -include_directories(../../../STL_Extension/include) -include_directories(../../../AABB_tree/include) add_definitions(-DCGAL_MESH_3_NO_DEPRECATED_SURFACE_INDEX -DCGAL_MESH_3_NO_DEPRECATED_C3T3_ITERATORS) +# Activate verbose mode? (turned OFF by default) +option(CGAL_ACTIVATE_CONCURRENT_MESH_3 "Activate verbose mode in Mesh_3" OFF) if(MESH_3_VERBOSE) add_definitions(-DCGAL_MESH_3_VERBOSE) endif() -find_package(CGAL REQUIRED COMPONENTS ImageIO) - -# Activate concurrency ? (turned OFF by default) +# Activate concurrency? (turned OFF by default) option(CGAL_ACTIVATE_CONCURRENT_MESH_3 "Activate parallelism in Mesh_3" OFF) # And add -DCGAL_CONCURRENT_MESH_3 if that option is ON @@ -58,8 +24,7 @@ if(CGAL_ACTIVATE_CONCURRENT_MESH_3) find_package(TBB REQUIRED) include(CGAL_TBB_support) else() - option(LINK_WITH_TBB - "Link with TBB anyway so we can use TBB timers for profiling" ON) + option(LINK_WITH_TBB "Link with TBB anyway so we can use TBB timers for profiling" ON) if(LINK_WITH_TBB) find_package(TBB) include(CGAL_TBB_support) @@ -67,19 +32,18 @@ else() endif() # Compilable benchmark -set(BENCHMARK_SOURCE_FILES "concurrency.cpp") -add_msvc_precompiled_header("StdAfx.h" "StdAfx.cpp" BENCHMARK_SOURCE_FILES) -create_single_source_cgal_program(${BENCHMARK_SOURCE_FILES}) +create_single_source_cgal_program("benchmark_mesh_3.cpp") + if(TARGET CGAL::TBB_support) - target_link_libraries(concurrency PUBLIC CGAL::TBB_support) + target_link_libraries(benchmark_mesh_3 PUBLIC CGAL::TBB_support) endif() # Link with Boost.ProgramOptions (optional) find_package(Boost QUIET COMPONENTS program_options) if(Boost_PROGRAM_OPTIONS_FOUND) if(TARGET Boost::program_options) - target_link_libraries(concurrency PRIVATE Boost::program_options) + target_link_libraries(benchmark_mesh_3 PRIVATE Boost::program_options) else() - target_link_libraries(concurrency PRIVATE ${Boost_PROGRAM_OPTIONS_LIBRARY}) + target_link_libraries(benchmark_mesh_3 PRIVATE ${Boost_PROGRAM_OPTIONS_LIBRARY}) endif() endif() diff --git a/Mesh_3/benchmark/Mesh_3/Charting/Performance/generate_performance_benchmark_charts.py b/Mesh_3/benchmark/Mesh_3/Charting/Performance/generate_performance_benchmark_charts.py new file mode 100644 index 000000000000..ad7fdba11922 --- /dev/null +++ b/Mesh_3/benchmark/Mesh_3/Charting/Performance/generate_performance_benchmark_charts.py @@ -0,0 +1,161 @@ +#!/usr/bin/python + +import os, sys, subprocess, datetime, time, signal, getopt +import numpy as np +import matplotlib.pyplot as plt + +def main(argv): + + inputdir="" + outputdir="" + commit_hash="" + do_diff=False + diffdir="" + diff_hash="" + try: + opts, args = getopt.getopt(sys.argv[1:], 'i:a:o:c:d:p:') + except getopt.GetoptError: + sys.exit(2) + for opt, arg in opts: + if opt == "-i": + inputdir = arg + elif opt == "-o": + outputdir = arg + elif opt == "-c": + commit_hash = arg + elif opt == "-d": + diff_hash = arg + do_diff = True + elif opt == "-p": + diffdir = arg + + print("Generating performance charts for inputdir =", inputdir) + print("Outputdir =", outputdir) + print("Commit hash =", commit_hash) + print("Do diff =", do_diff) + print("Diff hash =", diff_hash) + print("Diffdir =", diffdir) + + all_metric = { + "Facet_Scan_Time_(second)" : {}, + "Facet_Refine_Time_(second)" : {}, + "Cell_Scan_Time_(second)" : {}, + "Cell_Refine_Time_(second)" : {}, + "Lloyd_Time_(second)" : {}, + "ODT_Time_(second)" : {}, + "Perturber_Time_(second)" : {}, + "Exuder_Time_(second)" : {}, + "Total_Time_(second)" : {}, + "Memory_Peak_(mbytes)" : {}} + + num_input = 0 + for filename in os.listdir(inputdir) : + mesh_id = str(filename.split('.')[0]) + print("perf charting, filename", filename) + new_path = os.path.join(inputdir,filename) + new_file = open(new_path) + is_empty_new = os.path.getsize(new_path) <= 1 + if do_diff : + old_path = os.path.join(diffdir,filename) + old_file = open(old_path) + is_empty_old = os.path.getsize(old_path) <= 1 + for key in all_metric: + if is_empty_new or is_empty_old : + new_val = 0. + old_val = 0. + else : + new_entry = new_file.readline().strip() + old_entry = old_file.readline().strip() + new_val = float(new_entry) if new_entry else 0. + old_val = float(old_entry) if old_entry else 0. + all_metric[key][mesh_id] = [new_val, old_val] + else : + for key in all_metric: + if is_empty_new : + new_val = 0. + else : + new_entry = new_file.readline().strip() + new_val = float(new_entry) if new_entry else 0. + all_metric[key][mesh_id] = [new_val, new_val] + num_input = num_input+1 + + if num_input == 0 : + sys.exit(0) + + # update .pdf chart + date_now = datetime.datetime.now() + date_for_filename = str(date_now.year) +"_"+ str(date_now.month) +"_"+ str(date_now.day) +"_"+ str(date_now.hour) +"h"+ str(date_now.minute) +"mn" + for key in all_metric: + goal = 0 + num_el = range(len(all_metric[key])) + avg_diff_to_goal = 0. + avg = 0. + x1 = [] + x2 = [] + for value in all_metric[key].values() : + avg += value[0] + diff_to_goal = abs(value[1]-goal) - abs(value[0]-goal) + avg_diff_to_goal += diff_to_goal + x1.append(value[0]) + x2.append(value[1]) + avg_diff_to_goal /= float(len(all_metric[key])) + avg /= float(len(all_metric[key])) + + plt.figure(figsize=(8,8)) + if do_diff : + plt.hist(x2, bins=100, color='tab:green', alpha=0.5) + plt.hist(x1, bins=100, color='tab:blue', alpha=0.5) + plt.vlines(x = goal, ymin=plt.ylim()[0], ymax=plt.ylim()[1], linestyles='dashed') + + title = "" + if do_diff : + title += "Diff between " + commit_hash + " and " + diff_hash + " on " + str(num_input) + " meshes" + else : + title += "Benchmarking on " + str(num_input) + " meshes" + + avg_str = str(format(abs(avg), '.4f')) + if key == "Memory_Peak_(mbytes)" : + title += "\nIn average we use up to " + avg_str + " mbytes" + else : + title += "\nIn average we spend " + avg_str + " seconds" + + if do_diff and avg_diff_to_goal == 0. : + title += "\nNo change between the two commits" + elif do_diff : + avg_diff_str = str(format(abs(avg_diff_to_goal), '.4f')) + if key == "Memory_Peak_(mbytes)" : + if avg_diff_to_goal < 0 : + title += "\nIn average we use " + avg_diff_str + " more" + else : + title += "\nIn average we use " + avg_diff_str + " less" + title += " mbytes" + else : + if avg_diff_to_goal < 0 : + title += "\nIn average we get slower by " + else : + title += "\nIn average we get faster " + title += avg_diff_str + " seconds" + + plt.title(title, fontsize=15) + plt.xlabel(key.replace("_"," "), fontsize=14) + plt.ylabel("# of meshes", fontsize=14) + plt.tick_params(axis="x", labelsize=9) + plt.tick_params(axis="y", labelsize=9) + + chart_filename = "" + if do_diff : + chart_filename += "diff_"+commit_hash+"_"+diff_hash+"_"+key+"_"+date_for_filename+".pdf" + else : + chart_filename += "results_"+commit_hash+"_"+key+"_"+date_for_filename+".pdf" + chart_path = os.path.join(outputdir+"/charts",chart_filename) + if os.path.isfile(chart_path) : + os.remove(chart_path) + plt.savefig(chart_path, bbox_inches="tight") + plt.close() + + print("Performance charts have been generated") + + sys.exit() + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/Mesh_3/benchmark/Mesh_3/Charting/Quality/generate_quality_benchmark_charts.py b/Mesh_3/benchmark/Mesh_3/Charting/Quality/generate_quality_benchmark_charts.py new file mode 100644 index 000000000000..1c76c31f1fad --- /dev/null +++ b/Mesh_3/benchmark/Mesh_3/Charting/Quality/generate_quality_benchmark_charts.py @@ -0,0 +1,244 @@ +# Copyright (c) 2019-2023 Google LLC (USA). +# All rights reserved. +# +# This file is part of CGAL (www.cgal.org). +# +# $URL$ +# $Id$ +# SPDX-License-Identifier: GPL-3.0-or-later +# +# +# Author(s) : Pierre Alliez +# Michael Hemmer +# Cedric Portaneri +# +#!/usr/bin/python + +import os, sys, subprocess, datetime, time, signal, getopt +import numpy as np +import matplotlib.pyplot as plt + +def main(argv): + + inputdir="" + outputdir="" + commit_hash="" + do_diff=False + diffdir="" + diff_hash="" + try: + opts, args = getopt.getopt(sys.argv[1:], 'i:a:o:c:d:p:') + except getopt.GetoptError: + sys.exit(2) + for opt, arg in opts: + if opt == "-i": + inputdir = arg + elif opt == "-o": + outputdir = arg + elif opt == "-c": + commit_hash = arg + elif opt == "-d": + diff_hash = arg + do_diff = True + elif opt == "-p": + diffdir = arg + + print("Generating quality charts for inputdir =", inputdir) + print("Outputdir =", outputdir) + print("Commit hash =", commit_hash) + print("Do diff =", do_diff) + print("Diff hash =", diff_hash) + print("Diffdir =", diffdir) + + all_metric = { + "Complexity_(#_of_Vertices)" : {}, + "Complexity_(#_of_Facets)" : {}, + "Complexity_(#_of_Cells)" : {}, + "Minimum_Edge_Length_" : {}, + "Mean_Edge_Length_" : {}, + "Maximum_Edge_Length_" : {}, + "Minimum_Facet_Area_" : {}, + "Mean_Facet_Area_" : {}, + "Maximum_Facet_Area_" : {}, + "Total_Area_" : {}, + "Minimum_Facet_Angle_(degree)" : {}, + "Maximum_Facet_Angle_(degree)" : {}, + "Minimum_Cell_Volume_" : {}, + "Mean_Cell_Volume_" : {}, + "Maximum_Cell_Volume_" : {}, + "Total_Volume_" : {}, + "Minimum_Cell_Angle_(degree)" : {}, + "Mean_Cell_Angle_(degree)" : {}, + "Maximum_Cell_Angle_(degree)" : {}, + "Smallest_edge_radius_ratio" : {}, + "Smallest_radius_radius_ratio" : {}, + "Bigget_V_SMA" : {}} + + num_input = 0 + for filename in os.listdir(inputdir) : + mesh_id = str(filename.split('.')[0]) + new_path = os.path.join(inputdir,filename) + print("new_path?", new_path) + new_file = open(new_path) + is_empty_new = os.path.getsize(new_path) <= 1 + print("is_empty_new?", is_empty_new) + if do_diff : + old_path = os.path.join(diffdir,filename) + old_file = open(old_path) + is_empty_old = os.path.getsize(old_path) <= 1 + print("is_empty_old?", is_empty_old) + for key in all_metric : + if is_empty_new or is_empty_old : + new_val = 0. + old_val = 0. + else : + new_entry = new_file.readline().strip() + old_entry = old_file.readline().strip() + new_val = float(new_entry) if new_entry else 0. + old_val = float(old_entry) if old_entry else 0. + print("new entry, val", new_entry, new_val) + print("old entry, val", new_entry, new_val) + all_metric[key][mesh_id] = [new_val, old_val] + else : + for key in all_metric : + if is_empty_new : + new_val = 0. + else : + new_entry = new_file.readline().strip() + new_val = float(new_entry) if new_entry else 0. + all_metric[key][mesh_id] = [new_val, new_val] + num_input = num_input+1 + + if num_input == 0 : + sys.exit(0) + + # update .pdf chart + date_now = datetime.datetime.now() + date_for_filename = str(date_now.year) +"_"+ str(date_now.month) +"_"+ str(date_now.day) +"_"+ str(date_now.hour) +"h"+ str(date_now.minute) +"mn" + for key in all_metric: + goal = 0 + if key == "Minimum_Facet_Angle_(degree)" or key == "Maximum_Facet_Angle_(degree)" : + goal = 60. + elif key == "Minimum_Cell_Angle_(degree)" or key == "Mean_Cell_Angle_(degree)" or key == "Maximum_Cell_Angle_(degree)" : + goal = 70.5 # for a regular tetrahedron + + num_el = range(len(all_metric[key])) + avg_diff_to_goal = 0. + avg = 0. + x1 = [] + x2 = [] + + for value in all_metric[key].values() : + avg += value[0] + diff_to_goal = abs(value[1]-goal) - abs(value[0]-goal) + avg_diff_to_goal += diff_to_goal + x1.append(value[0]) + x2.append(value[1]) + avg_diff_to_goal /= float(len(all_metric[key])) + avg /= float(len(all_metric[key])) + + plt.figure(figsize=(8,8)) + if do_diff : + plt.hist(x2, bins=100, color='tab:green', alpha=0.5) + plt.hist(x1, bins=100, color='tab:blue', alpha=0.5) + plt.vlines(x = goal, ymin=plt.ylim()[0], ymax=plt.ylim()[1], linestyles='dashed') + + title = "" + if do_diff : + title += "Diff between " + commit_hash + " and " + diff_hash + " on " + str(num_input) + " meshes" + else : + title += "Benchmarking on " + str(num_input) + " meshes" + + avg_str = str(format(abs(avg), '.4f')) + + if key == "Complexity_(#_of_Vertices)": + title += "\nIn average we have " + avg_str + " vertices" + elif key == "Complexity_(#_of_Facets)": + title += "\nIn average we have " + avg_str + " facets" + elif key == "Complexity_(#_of_Cells)": + title += "\nIn average we have " + avg_str + " cells" + elif key == "Minimum_Edge_Length_": + title += "\nIn average we have a minimum edge length of " + avg_str + elif key == "Mean_Edge_Length_": + title += "\nIn average we have an average edge length of " + avg_str + elif key == "Maximum_Edge_Length_": + title += "\nIn average we have a maximum edge of length " + avg_str + elif key == "Minimum_Facet_Area_": + title += "\nIn average we have a minimum facet area of " + avg_str + elif key == "Mean_Facet_Area_": + title += "\nIn average we have an average facet area of " + avg_str + elif key == "Maximum_Facet_Area_": + title += "\nIn average we have a maximum facet area of " + avg_str + elif key == "Total_Area_": + title += "\nIn average we have a total area of " + avg_str + elif key == "Minimum_Facet_Angle_(degree)": + title += "\nIn average we have a minimum facet angle of " + avg_str + "°" + elif key == "Maximum_Facet_Angle_(degree)": + title += "\nIn average we have a maximum facet angle of " + avg_str + "°" + elif key == "Minimum_Cell_Volume_": + title += "\nIn average we have a minimum cell volume of " + avg_str + elif key == "Mean_Cell_Volume_": + title += "\nIn average we have an average cell volume of " + avg_str + elif key == "Maximum_Cell_Volume_": + title += "\nIn average we have a maximum cell volume " + avg_str + elif key == "Total_Volume_": + title += "\nIn average we have a total volume of " + avg_str + elif key == "Minimum_Cell_Angle_(degree)": + title += "\nIn average we have a minimum dihedral angle of " + avg_str + "°" + elif key == "Mean_Cell_Angle_(degree)": + title += "\nIn average we have an average dihedral angle of " + avg_str + "°" + elif key == "Maximum_Cell_Angle_(degree)": + title += "\nIn average we have a maximum dihedral angle of " + avg_str + "°" + elif key == "Smallest_edge_radius_ratio": + title += "\nIn average we have a minimum edge radius ratio of " + avg_str + elif key == "Smallest_radius_radius_ratio": + title += "\nIn average we have a minimum radius radius ratio of " + avg_str + elif key == "Bigget_V_SMA": + title += "\nIn average we have a maximum V_SMA of " + avg_str + + if do_diff and avg_diff_to_goal == 0. : + title += "\nNo change between the two commits" + elif do_diff : + avg_diff_str = str(format(abs(avg_diff_to_goal), '.4f')) + if key == "Minimum_Facet_Angle_(degree)" or key == "Maximum_Facet_Angle_(degree)": + if avg_diff_to_goal < 0 : + title += "\nIn average we lose " + else : + title += "\nIn average we gain " + title += avg_diff_str + "° toward 60°" + elif key == "Minimum_Cell_Angle_(degree)" or key == "Mean_Cell_Angle_(degree)" or key == "Maximum_Cell_Angle_(degree)": + if avg_diff_to_goal < 0 : + title += "\nIn average we lose " + else : + title += "\nIn average we gain " + title += avg_diff_str + "° toward 70.5°" + else : + if avg_diff_to_goal < 0 : + title += "\nIn average we get " + avg_diff_str + " more" + else : + title += "\nIn average we get " + avg_diff_str + " less" + title += " " + key.replace("_"," ") + + plt.title(title, fontsize=15) + plt.xlabel(key.replace("_"," "), fontsize=14) + plt.ylabel("# of meshes", fontsize=14) + plt.tick_params(axis="x", labelsize=9) + plt.tick_params(axis="y", labelsize=9) + + chart_filename = "" + if do_diff : + chart_filename += "diff_"+commit_hash+"_"+diff_hash+"_"+key+"_"+date_for_filename+".pdf" + else : + chart_filename += "results_"+commit_hash+"_"+key+"_"+date_for_filename+".pdf" + chart_path = os.path.join(outputdir+"/charts",chart_filename) + if os.path.isfile(chart_path) : + os.remove(chart_path) + plt.savefig(chart_path, bbox_inches="tight") + plt.close() + + print("Quality charts have been generated") + + sys.exit() + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/Mesh_3/benchmark/Mesh_3/Charting/Robustness/generate_robustness_benchmark_charts.py b/Mesh_3/benchmark/Mesh_3/Charting/Robustness/generate_robustness_benchmark_charts.py new file mode 100644 index 000000000000..754ea0da1699 --- /dev/null +++ b/Mesh_3/benchmark/Mesh_3/Charting/Robustness/generate_robustness_benchmark_charts.py @@ -0,0 +1,127 @@ +#!/usr/bin/python + +import os, sys, subprocess, datetime, time, signal, getopt +import numpy as np +import matplotlib.pyplot as plt + +def main(argv): + + inputdir="" + outputdir="" + commit_hash="" + try: + opts, args = getopt.getopt(sys.argv[1:], 'i:o:c:') + except getopt.GetoptError: + sys.exit(2) + for opt, arg in opts: + if opt == "-i": + inputdir = arg + elif opt == "-o": + outputdir = arg + elif opt == "-c": + commit_hash = arg + + print("Generating performance charts for inputdir =", inputdir) + print("Outputdir =", outputdir) + print("Commit hash =", commit_hash) + + exit_codes = { + 0 : "VALID_SOLID_OUTPUT", + 1 : "INPUT_IS_INVALID", + 2 : "OUTPUT_IS_INVALID", + 3 : "SIGSEGV", + 4 : "SIGABRT", + 5 : "SIGFPE", + 6 : "TIMEOUT" + } + + current_run_data = { + "VALID_SOLID_OUTPUT" : 0, + "INPUT_IS_INVALID" : 0, + "OUTPUT_IS_INVALID" : 0, + "SIGSEGV" : 0, + "SIGABRT" : 0, + "SIGFPE" : 0, + "TIMEOUT" : 0 + } + + filenames_per_codes = {} + for key in current_run_data : + filenames_per_codes[key] = [] + + num_input = 0 + for filename in os.listdir(inputdir) : + print("filename = ", filename) + + f = open(os.path.join(inputdir,filename)) + status = f.readline().strip(); + current_run_data[status] += 1 + filenames_per_codes[status].append(filename.rstrip('.log')) + num_input = num_input+1 + + # sort current_run_data by value + current_run_data = {k: v for k, v in sorted(current_run_data.items(), key=lambda item: item[1], reverse=True)} + + # update chart data files + date_now = datetime.datetime.now() + date = str(date_now.year) +"-"+ str(date_now.month) +"-"+ str(date_now.day) +" "+ str(date_now.hour) +"h"+ str(date_now.minute) +"mn" + + for key_filename in current_run_data: + f = open(os.path.join(outputdir+"/charts_data", key_filename+".txt"), "a+") + f.write(str(current_run_data[key_filename]) + " " + commit_hash + " " + date + "\n") + + print("chart data updated") + + # update .pdf chart + chart = plt.figure(figsize=(10, 7)) + colormap = ["tab:blue","tab:orange","tab:green","tab:red","tab:purple","tab:brown","tab:pink","tab:gray","tab:olive","tab:cyan","b","palegreen", "peachpuff"] + plt.gca().set_prop_cycle('color', colormap) + plt.style.use('tableau-colorblind10') + for key_filename in current_run_data: + + f = open(os.path.join(outputdir+"/charts_data", key_filename+".txt"), "r") + lines = f.readlines() + x_number_values = [] + y_number_values = [] + i = 0 + for line in lines : + if i < (len(lines) - 10) : + i=i+1 + continue + + i=i+1 + words = line.strip().split() + x_number_values.append(words[1]+"\n"+words[2]+"\n"+words[3]) + y_number_values.append(int(words[0])) + plt.plot(x_number_values, y_number_values, marker='o', label=key_filename+": "+str(current_run_data[key_filename])) + + plt.xlabel("Version", fontsize=14) + plt.ylabel("# of mesh", fontsize=14) + plt.tick_params(axis="both", labelsize=9) + plt.title("Benchmarking on " + str(num_input) + " meshes", fontsize=15) + plt.legend(loc='lower left', bbox_to_anchor= (1.01, 0.58), ncol=1, + borderaxespad=0, frameon=False) + + date_for_filename = str(date_now.year) +"-"+ str(date_now.month) +"-"+ str(date_now.day) +"-"+ str(date_now.hour) +"h"+ str(date_now.minute) +"mn" + chart_filename = os.path.join(outputdir+"/charts","benchmarking_version_"+commit_hash+"-"+date_for_filename+".pdf") + if os.path.isfile(chart_filename) : + os.remove(chart_filename) + chart.savefig(chart_filename, bbox_inches="tight") + plt.close(chart) + + print("Robustness charts have been generated") + + # dump filenames per codes + log_dirname = os.path.join(outputdir, "logs/"+commit_hash+"-"+date_for_filename) + if not os.path.exists(log_dirname): + os.mkdir(log_dirname) + for key in filenames_per_codes : + file = open(os.path.join(log_dirname, key+".txt"), "w+") + for filename in filenames_per_codes[key] : + file.write(filename + "\n") + file.close() + + sys.exit() + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/Mesh_3/benchmark/Mesh_3/Charting/benchmarking.sh b/Mesh_3/benchmark/Mesh_3/Charting/benchmarking.sh new file mode 100755 index 000000000000..f52649fe9f1a --- /dev/null +++ b/Mesh_3/benchmark/Mesh_3/Charting/benchmarking.sh @@ -0,0 +1,192 @@ +#!/bin/bash + +# ################################################################################################### +# # INTRODUCTION +# ################################################################################################### + +# This script is meant to benchmark Mesh_3 over a directory of data files (e.g. Thingi10k/raw_meshes) +# with unique names. It checks a number of metrics in 3 categories: Robustness (did it finish without +# errors, and did it produce a valid result?), Performance (how long did it take to run?), and Quality +# (how good is the result mesh?). +# +# This script gives access to the mesh criteria for convenience, but all the other parameters +# are fixed and chosen two configuration files. +# +# If `benchmark_mesh_3.cpp` is in parallel mode, you should use a single thread. +# You also probably don't want to use "BENCHMARK_WITH_1_TO_MAX_THREADS", so be sure it's off. +# +# ################################################################################################### +# # QUICK START +# ################################################################################################### +# +# Set up your preferences in the files: +# - CGAL_root/Mesh_3/benchmark/Mesh_3/benchmarking_config.h (Mesh_3 options) +# - CGAL_root/Mesh_3/benchmark/Mesh_3/concurrent_mesher_config.cfg (parallel options) +# +# Compile benchmark_mesh_3.cpp in a folder called `build-release` +# Go to Mesh_3/benchmark/Mesh_3/Charting +# +# Call: +# sh benchmarking.sh $1 ... $12 +# Arguments: +# $1: directory containing the Mesh_3 project (i.e. CGAL_root) +# $2: directory containing the input data folder (e.g. "~/Data/Thingi10k/raw_meshes") +# $3: directory containing the output results (recommended to be CGAL_root/Mesh_3/benchmark/Mesh_3/Charting) +# $4: facet size +# $5: facet distance +# $6: facet angle +# $7: cell size +# $8: cell radius-edge ratio +# $9: timeout value (in seconds) +# $10: number of threads used (runs multiple data in parallel. Do NOT use if benching parallel mode!!) +# $11: test identifier (e.g. hash of the last commit) +# $12: test identifier of a previous test, to perform the difference with ${11} [optional] +# +# Find the result in the output_dir/charts. +# +# ################################################################################################### +# # SCRIPT DETAILS +# ################################################################################################### + +# The script generates data by calling `run_benchmark.py`, which runs `benchmark_mesh_3.cpp`. +# The data is written in an XML file (see the macro CGAL_MESH_3_SET_PERFORMANCE_DATA +# and the file benchmark.xml). One XML file per input data. +# The XML file is parsed by the scripts `generate_[robustness|performance|quality]_benchmark_charts.py` +# to generate individual charts for each metric, which are then merged together at the end +# of this script. +# +# To add a new metric to the benchmark, one must: +# - Add it into the benchmark.xml +# - Measure it (either in Mesh_3/include, or in benchmark_mesh_3.cpp) and log it with the macro +# CGAL_MESH_3_SET_PERFORMANCE_DATA. +# - Parse it and plot it in the corresponding script (e.g. generate_robustness_benchmark_charts.py) +# - change the "tail -n" at the end of this file, and the "3x10" (layout of the final chart) + +# ################################################################################################### +# # TODO +# ################################################################################################### + +# - Make it work for other OS +# - Other metrics (edge radius ratio, Hausdorff distance) + +# -------------------------------------------------------------------------------------------------- +# -------------------------------------------------------------------------------------------------- +# -------------------------------------------------------------------------------------------------- + +# $1: directory containing the Mesh_3 project +# $2: directory containing the output results +# $3: facet size +# $4: facet distance +# $5: facet angle +# $6: cell size +# $7: cell radius-edge ratio +# $8: timeout value (in seconds) +# $9: test identifier (e.g. hash of the last commit) +# $10: the input file path +function compute_benchmark_data() { + filename=$(basename -- "${10}") + filename="${filename%.*}" + + # print filename: + echo "param #1 (directory containing the Mesh_3 project): " $1 + echo "param #2 (directory containing the output results): " $2 + echo "param #3 (facet size): " $3 + echo "param #4 (facet distance): " $4 + echo "param #5 (facet angle): " $5 + echo "param #6 (cell size): " $6 + echo "param #7 (cell radius-edge ratio): " $7 + echo "param #8 (timeout value): " $8 + echo "param #9 (test ID): " $9 + echo "param #10 (the input file path): " ${10} + + python3 $1/Mesh_3/benchmark/Mesh_3/Charting/run_benchmark.py \ + --exec $1/Mesh_3/benchmark/Mesh_3/build-release/benchmark_mesh_3 \ + -i ${10} \ + --facet_size $3 --facet_approx $4 --facet_angle $5 \ + --cell_size $6 --cell_shape $7 -t $8 \ + --out $2 \ + --test_ID $9 \ + > $2/logs/$9/$filename.log + +} +export -f compute_benchmark_data + +echo "param #1 (directory containing the Mesh_3 project): " $1 +echo "param #2 (directory containing the input data folder): " $2 +echo "param #3 (directory containing the output results): " $3 +echo "param #4 (facet size): " $4 +echo "param #5 (facet distance): " $5 +echo "param #6 (facet angle): " $6 +echo "param #7 (cell size): " $7 +echo "param #8 (cell radius-edge ratio): " $8 +echo "param #9 (timeout value): " $9 +echo "param #10 (number of threads used): " ${10} +echo "param #11 (test ID): " ${11} +echo "param #12 (another test ID, to perform the difference with ${11}): " ${12} + +echo "---------------------------------" + +echo $# "argument(s) provided." + +if [[ $# -lt 11 ]]; then + echo "Expected 12 arguments, see list above." + exit 1 +fi + +# just for convenience: remove everything +# rm $3/*.mesh +# rm -rf $3/Robustness/logs +# rm -rf $3/Robustness/results +# rm -rf $3/Robustness/charts_data +# rm -rf $3/Robustness/charts +# rm -rf $3/Quality/logs +# rm -rf $3/Quality/results +# rm -rf $3/Quality/charts +# rm -rf $3/Performance/logs +# rm -rf $3/Performance/results +# rm -rf $3/Performance/charts +# rm -rf $3/logs +# rm -rf $3/charts +# exit + +rm -rf $3/Robustness/logs/${11} +rm -rf $3/Robustness/results/${11} +rm -rf $3/Quality/logs/${11} +rm -rf $3/Quality/results/${11} +rm -rf $3/Performance/logs/${11} +rm -rf $3/Performance/results/${11} + +mkdir -p $3/Robustness/logs/${11} +mkdir -p $3/Robustness/results/${11} +mkdir -p $3/Robustness/charts_data +mkdir -p $3/Robustness/charts +mkdir -p $3/Quality/logs/${11} +mkdir -p $3/Quality/results/${11} +mkdir -p $3/Quality/charts +mkdir -p $3/Performance/logs/${11} +mkdir -p $3/Performance/results/${11} +mkdir -p $3/Performance/charts +mkdir -p $3/logs/${11} +mkdir -p $3/charts + +rm $3/Robustness/results/${11}/* # only for that one, others need to keep their results in case of diff + +find $2 -mindepth 1 | parallel -j${10} compute_benchmark_data $1 $3 $4 $5 $6 $7 $8 $9 ${11} ::: + +python3 $1/Mesh_3/benchmark/Mesh_3/Charting/Robustness/generate_robustness_benchmark_charts.py -i $3/Robustness/results/${11} -o $3/Robustness -c ${11} + +if [ -z "${12}" ]; then + python3 $1/Mesh_3/benchmark/Mesh_3/Charting/Performance/generate_performance_benchmark_charts.py -i $3/Performance/results/${11} -o $3/Performance -c ${11}; +else + python3 $1/Mesh_3/benchmark/Mesh_3/Charting/Performance/generate_performance_benchmark_charts.py -i $3/Performance/results/${11} -o $3/Performance -c ${11} -p $3/Performance/results/${12} -d ${12}; +fi + +if [ -z "${12}" ]; then + python3 $1/Mesh_3/benchmark/Mesh_3/Charting/Quality/generate_quality_benchmark_charts.py -i $3/Quality/results/${11} -o $3/Quality -c ${11}; +else + python3 $1/Mesh_3/benchmark/Mesh_3/Charting/Quality/generate_quality_benchmark_charts.py -i $3/Quality/results/${11} -o $3/Quality -c ${11} -p $3/Quality/results/${12} -d ${12}; +fi + +charts_path="$(ls "$3/Robustness/charts"/* -dArt | tail -n 1) $(ls "$3/Performance/charts"/* -dArt | tail -n 10) $(ls "$3/Quality/charts"/* -dArt | tail -n 22)" + +pdfjam --nup 3x11 $charts_path --outfile $3/charts/results_${11}_${12}_$(date '+%Y-%m-%d_%H:%M:%S').pdf diff --git a/Mesh_3/benchmark/Mesh_3/Charting/run_benchmark.py b/Mesh_3/benchmark/Mesh_3/Charting/run_benchmark.py new file mode 100755 index 000000000000..de6721d43fad --- /dev/null +++ b/Mesh_3/benchmark/Mesh_3/Charting/run_benchmark.py @@ -0,0 +1,269 @@ +#!/usr/bin/python + +import os, sys, subprocess, datetime, time, signal, getopt + +import xml.etree.ElementTree as ET +from xml.etree.ElementTree import XMLParser + +#################################################################################################### +def signal_handler(signum, frame): + raise Exception("Timed out!") + +#################################################################################################### +def run_benchmark(execname, filename, facet_size, facet_approx, facet_angle, cell_size, cell_shape, max_time, test_ID, outpath): + + exit_codes = { + 0 : "VALID_SOLID_OUTPUT", + 1 : "INPUT_IS_INVALID", + 2 : "OUTPUT_IS_INVALID", + 3 : "SIGSEGV", + 4 : "SIGABRT", + 5 : "SIGFPE", + 6 : "TIMEOUT" + } + + raw_filename = os.path.splitext(os.path.basename(filename))[0] + xml_filename = outpath + "/logs/" + test_ID + "/" + raw_filename + ".xml" + print("xml_filename = ", xml_filename) + + exit_code = 0 + output = "" + cmd = ("/usr/bin/time", "-v", execname, xml_filename, filename, facet_size, facet_approx, facet_angle, cell_size, cell_shape) + + print("cmd = ", cmd) + + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, start_new_session=True) + + try: + outs, errs = proc.communicate(timeout=int(max_time)) + exit_code = proc.returncode + output = outs.decode("utf-8") + errs.decode("utf-8") + + print("output = ", output) + + for output_line in output.split("\n"): + if output_line == "Command terminated by signal 11": + exit_code = 3 + continue + elif output_line == "Command terminated by signal 6": + exit_code = 4 + continue + elif output_line == "Command terminated by signal 8": + exit_code = 5 + continue + + except subprocess.TimeoutExpired: + os.killpg(os.getpgid(proc.pid), signal.SIGTERM) + exit_code = 6 + output = "process ran too long" + + print("EXIT CODE: ", exit_codes[exit_code]) + + outfile = outpath + "/Robustness/results/" + test_ID + "/" + raw_filename + ".txt" + print("writing to", outfile) + file = open(outfile, "w") + file.write(exit_codes[exit_code]) + file.close() + + return exit_code + +#################################################################################################### +def parse_xml_file(filename, tag): + tree = ET.parse(filename) + root = tree.getroot() + + elems = root.findall(f'.//{tag}') + if len(elems) == 0: + print("Error: no elements found for ", tag) + return sys.exit(1) + + elem = elems[0] # take the first + return elem.text.strip() + +#################################################################################################### +def main(argv): + execname="" + filename="" + facet_size="" + facet_approx="" + facet_angle="" + cell_size="" + cell_shape="" + max_time="" + test_ID="" + outpath="" + try: + opts, args = getopt.getopt(sys.argv[1:], 'i:t:', ["exec=", "facet_size=", "facet_approx=", "facet_angle=", "cell_size=", "cell_shape=", "test_ID=", "out="]) + except getopt.GetoptError: + sys.exit(2) + for opt, arg in opts: + if opt == "--exec": # executable + execname = arg + elif opt == "-i": # filename + filename = arg + elif opt == "--facet_size": + facet_size = arg + elif opt == "--facet_approx": + facet_approx = arg + elif opt == "--facet_angle": + facet_angle = arg + elif opt == "--cell_size": + cell_size = arg + elif opt == "--cell_shape": + cell_shape = arg + elif opt == "-t": + max_time = arg + elif opt == "--test_ID": + test_ID = arg + elif opt == "--out": # output file + outpath = arg + + print("execname = ", execname) + print("filename = ", filename) + print("facet_size = ", facet_size) + print("facet_approx = ", facet_approx) + print("facet_angle = ", facet_angle) + print("cell_size = ", cell_size) + print("cell_shape = ", cell_shape) + print("max_time = ", max_time) + print("test_ID = ", test_ID) + print("outpath = ", outpath) + + exit_code = run_benchmark(execname, filename, facet_size, facet_approx, facet_angle, cell_size, cell_shape, max_time, test_ID, outpath) + + # if the exit code is different from 0, then there is nothing to analyze + if exit_code != 0: + sys.exit(exit_code) + + raw_filename = os.path.splitext(os.path.basename(filename))[0] + xml_filename = outpath + "/logs/" + test_ID + "/" + raw_filename + ".xml" + + # Parse the XML output to extract performance and quality metrics + print("parsing", xml_filename) + + parser = XMLParser(encoding="utf-8") + try: + ET.parse(xml_filename, parser) + print("XML is valid") + except Exception as e: + print("XML is invalid -", e) + + # --- Performance + perf_results_filename = outpath + "/Performance/results/" + test_ID + "/" + raw_filename + ".txt" + perf_results = open(perf_results_filename, "w") + + # Refinement + facet_scan_time = parse_xml_file(xml_filename, "Facets_scan_time") + facet_refine_time = parse_xml_file(xml_filename, "Facets_refine_time") + cell_scan_time = parse_xml_file(xml_filename, "Cells_scan_time") + cell_refine_time = parse_xml_file(xml_filename, "Cells_refine_time") + + # Optimisation + lloyd_optim_time = parse_xml_file(xml_filename, "Lloyd_optim_time") + odt_optim_time = parse_xml_file(xml_filename, "Odt_optim_time") + perturber_optim_time = parse_xml_file(xml_filename, "Perturber_optim_time") + exuder_optim_time = parse_xml_file(xml_filename, "Exuder_optim_time") + + # Total + total_time = parse_xml_file(xml_filename, "Total_time") + + # Memory + memory = parse_xml_file(xml_filename, "Mem") + + perf_results.write(facet_scan_time + "\n") + perf_results.write(facet_refine_time + "\n") + perf_results.write(cell_scan_time + "\n") + perf_results.write(cell_refine_time + "\n") + perf_results.write(lloyd_optim_time + "\n") + perf_results.write(odt_optim_time + "\n") + perf_results.write(perturber_optim_time + "\n") + perf_results.write(exuder_optim_time + "\n") + perf_results.write(total_time + "\n") + perf_results.write(memory + "\n") + + perf_results.close() + + # --- Quality + qual_results_filename = outpath + "/Quality/results/" + test_ID + "/" + raw_filename + ".txt" + qual_results = open(qual_results_filename, "w") + + number_of_vertices = parse_xml_file(xml_filename, "V") + number_of_facets = parse_xml_file(xml_filename, "F") + number_of_cells = parse_xml_file(xml_filename, "C") + + min_edge_size = parse_xml_file(xml_filename, "Minimum_edge_length") + mean_edge_size = parse_xml_file(xml_filename, "Mean_edge_length") + max_edge_size = parse_xml_file(xml_filename, "Maximum_edge_length") + min_facet_size = parse_xml_file(xml_filename, "Minimum_facet_area") + mean_facet_size = parse_xml_file(xml_filename, "Mean_facet_area") + max_facet_size = parse_xml_file(xml_filename, "Maximum_facet_area") + total_area = parse_xml_file(xml_filename, "Total_area") + # min_facet_distance = parse_xml_file(xml_filename, "Min_facet_distance") + # mean_facet_distance = parse_xml_file(xml_filename, "Mean_facet_distance") + # max_facet_distance = parse_xml_file(xml_filename, "Mean_facet_distance") + min_facet_angle = parse_xml_file(xml_filename, "Minimum_facet_angle") + max_facet_angle = parse_xml_file(xml_filename, "Maximum_facet_angle") + min_cell_size = parse_xml_file(xml_filename, "Minimum_cell_volume") + mean_cell_size = parse_xml_file(xml_filename, "Mean_cell_volume") + max_cell_size = parse_xml_file(xml_filename, "Maximum_cell_volume") + total_volume = parse_xml_file(xml_filename, "Total_volume") + min_cell_shape = parse_xml_file(xml_filename, "Minimum_dihedral_angle") + mean_cell_shape = parse_xml_file(xml_filename, "Mean_dihedral_angle") + max_cell_shape = parse_xml_file(xml_filename, "Maximum_dihedral_angle") + smallest_edge_radius_ratio = parse_xml_file(xml_filename, "Smallest_edge_radius_ratio") + smallest_radius_radius_ratio = parse_xml_file(xml_filename, "Smallest_radius_radius_ratio") + biggest_v_sma = parse_xml_file(xml_filename, "Biggest_V_SMA") + + print("number_of_vertices = ", number_of_vertices) + print("number_of_facets = ", number_of_facets) + print("number_of_cells = ", number_of_cells) + print("min_edge_size = ", min_edge_size) + print("mean_edge_size = ", mean_edge_size) + print("max_edge_size = ", max_edge_size) + print("min_facet_size = ", min_facet_size) + print("mean_facet_size = ", mean_facet_size) + print("max_facet_size = ", max_facet_size) + print("total_area = ", total_area) + # print("min_facet_distance = ", min_facet_distance) + # print("mean_facet_distance = ", mean_facet_distance) + # print("max_facet_distance = ", max_facet_distance) + print("min_facet_angle = ", min_facet_angle) + print("max_facet_angle = ", max_facet_angle) + print("min_cell_size = ", min_cell_size) + print("mean_cell_size = ", mean_cell_size) + print("max_cell_size = ", max_cell_size) + print("total_volume = ", total_volume) + print("min_cell_shape = ", min_cell_shape) + print("mean_cell_shape = ", mean_cell_shape) + print("max_cell_shape = ", max_cell_shape) + print("smallest_edge_radius_ratio = ", smallest_edge_radius_ratio) + print("smallest_radius_radius_ratio = ", smallest_radius_radius_ratio) + print("biggest_v_sma = ", biggest_v_sma) + + qual_results.write(number_of_vertices + "\n") + qual_results.write(number_of_facets + "\n") + qual_results.write(number_of_cells + "\n") + qual_results.write(min_edge_size + "\n") + qual_results.write(mean_edge_size + "\n") + qual_results.write(max_edge_size + "\n") + qual_results.write(min_facet_size + "\n") + qual_results.write(mean_facet_size + "\n") + qual_results.write(max_facet_size + "\n") + qual_results.write(total_area + "\n") + qual_results.write(min_facet_angle + "\n") + qual_results.write(max_facet_angle + "\n") + qual_results.write(min_cell_size + "\n") + qual_results.write(mean_cell_size + "\n") + qual_results.write(max_cell_size + "\n") + qual_results.write(total_volume + "\n") + qual_results.write(min_cell_shape + "\n") + qual_results.write(mean_cell_shape + "\n") + qual_results.write(max_cell_shape + "\n") + qual_results.write(smallest_edge_radius_ratio + "\n") + qual_results.write(smallest_radius_radius_ratio + "\n") + qual_results.write(biggest_v_sma + "\n") + + qual_results.close() + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/Mesh_3/benchmark/Mesh_3/StdAfx.cpp b/Mesh_3/benchmark/Mesh_3/StdAfx.cpp deleted file mode 100644 index 15668dcadeff..000000000000 --- a/Mesh_3/benchmark/Mesh_3/StdAfx.cpp +++ /dev/null @@ -1,2 +0,0 @@ -// Build the precompiled headers. -#include "StdAfx.h" \ No newline at end of file diff --git a/Mesh_3/benchmark/Mesh_3/StdAfx.h b/Mesh_3/benchmark/Mesh_3/StdAfx.h deleted file mode 100644 index e7ee9da0a034..000000000000 --- a/Mesh_3/benchmark/Mesh_3/StdAfx.h +++ /dev/null @@ -1,273 +0,0 @@ -#ifndef STDAFX_H -#define STDAFX_H - -#include -#include -#include - -// STL -#include -#include -#include -#include -#include -#include -#include -#include - -// Windows -#include - -// Boost -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// CGAL -//#include -//#include -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include -#include -//#include -#include -#include -//#include -//#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include -#include -#include -//#include -#include -#include -//#include -//#include -//#include -//#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -//#include -#include -#include -#include -//#include - -// Mesh_3 -/*#include -#include -#include -#include -#include -#include -#include */ - -#endif //STDAFX_H diff --git a/Mesh_3/benchmark/Mesh_3/benchmark_config.h b/Mesh_3/benchmark/Mesh_3/benchmark_config.h new file mode 100644 index 000000000000..0416e8abf930 --- /dev/null +++ b/Mesh_3/benchmark/Mesh_3/benchmark_config.h @@ -0,0 +1,123 @@ +//#define CHECK_MEMORY_LEAKS_ON_MSVC +#if defined(CHECK_MEMORY_LEAKS_ON_MSVC) && defined(_MSC_VER) + #define _CRTDBG_MAP_ALLOC + #include + #include +#endif + +// Without TBB_USE_THREADING_TOOL Intel Inspector XE will report false positives in Intel TBB +// (https://www.intel.com/content/www/us/en/developer/articles/technical/compiler-settings-for-threading-error-analysis-in-intel-inspector-xe.html) +#ifdef _DEBUG +# define TBB_USE_THREADING_TOOL +#endif + +#include +#include + +// ========================================================================== +// BENCHMARK GENERAL PARAMETERS +// ========================================================================== + +// #define CGAL_MESH_3_BENCHMARK_EXPORT_TO_MAYA +#define CGAL_MESH_3_BENCHMARK_EXPORT_TO_MESH + +// ========================================================================== +// MESH_3 GENERAL PARAMETERS +// ========================================================================== + +// #define CGAL_MESH_3_POLYHEDRON_WITH_FEATURES +// #define CGAL_MESH_3_IMPLICIT_WITH_FEATURES + +// #define CGAL_MESH_3_USE_OLD_SURFACE_RESTRICTED_DELAUNAY_UPDATE // WARNING: VERY SLOW +#define CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING + +// #define CGAL_MESH_3_BENCHMARK_LLOYD +// #define CGAL_MESH_3_BENCHMARK_ODT +// #define CGAL_MESH_3_BENCHMARK_PERTURB +// #define CGAL_MESH_3_BENCHMARK_EXUDE +// #define CGAL_MESH_3_MANIFOLD + +// #define CGAL_MESH_3_VERBOSE +// #define CGAL_MESH_3_PERTURBER_VERBOSE +// #define CGAL_MESH_3_PERTURBER_HIGH_VERBOSITY +// #define CGAL_MESH_3_EXUDER_VERBOSE +// #define CGAL_MESH_3_EXUDER_HIGH_VERBOSITY +// #define CGAL_MESH_3_VERY_VERBOSE +// #define CGAL_MESHES_DEBUG_REFINEMENT_POINTS +// #define CGAL_MESH_3_OPTIMIZER_VERBOSE + +#define CGAL_MESH_3_PROFILING +// #define CHECK_AND_DISPLAY_THE_NUMBER_OF_BAD_ELEMENTS_IN_THE_END + +// ========================================================================== +// INPUTS +// ========================================================================== + +const char* const BENCHMARK_INPUTS_FILENAME = "benchmark_inputs.txt"; + +const bool USE_RELATIVE_CRITERIA_VALUES = true; // relative to the bbox's diagonal +const double DEFAULT_FACE_SIZE = 100; // can be relative +const double DEFAULT_FACE_APPROX = 200; // can be relative +const double DEFAULT_FACE_ANGLE = 25; // cannot be relative +const double DEFAULT_CELL_SIZE = 100; // can be relative +const double DEFAULT_CELL_RADIUS_RATIO = 3; // cannot be relative + +// ========================================================================== +// CONCURRENCY +// ========================================================================== + +#ifdef CGAL_CONCURRENT_MESH_3 + +# include + +# ifndef CGAL_LINKED_WITH_TBB +# pragma message(" : Warning: CGAL_LINKED_WITH_TBB not defined: EVERYTHING WILL BE SEQUENTIAL.") +# endif + +// # define BENCHMARK_WITH_1_TO_MAX_THREADS + +// # define CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE // default behavior +// # define CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE +// # define CGAL_MESH_3_IF_UNSORTED_QUEUE_JUST_SORT_AFTER_SCAN // recommended +// # define CGAL_PARALLEL_MESH_3_DO_NOT_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE // not recommended + + // ========================================================================== + // Verbose + // ========================================================================== + +# define CGAL_CONCURRENT_MESH_3_VERBOSE +# define CGAL_CONCURRENT_MESH_3_VERY_VERBOSE + + // ========================================================================== + // Concurrency config + // ========================================================================== + + const char* const CONCURRENT_MESHER_CONFIG_FILENAME = "concurrent_mesher_config.cfg"; + + // ===================== + // Worksharing strategy + // ===================== + +// #define CGAL_MESH_3_LOAD_BASED_WORKSHARING // Not recommended + + // ========================================================================== + // Profiling + // ========================================================================== + + // For profiling, etc. +# define CGAL_CONCURRENT_MESH_3_PROFILING +// # define CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT + +#include + +// ========================================================================== +// SEQUENTIAL +// ========================================================================== + +#else // !CGAL_CONCURRENT_MESH_3 + +// # define CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE // default behavior +// # define CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE +// # define CGAL_MESH_3_IF_UNSORTED_QUEUE_JUST_SORT_AFTER_SCAN // recommended + +#endif // CGAL_CONCURRENT_MESH_3 \ No newline at end of file diff --git a/Mesh_3/benchmark/Mesh_3/benchmark_inputs.txt b/Mesh_3/benchmark/Mesh_3/benchmark_inputs.txt new file mode 100644 index 000000000000..e1af7cfed3d5 --- /dev/null +++ b/Mesh_3/benchmark/Mesh_3/benchmark_inputs.txt @@ -0,0 +1,267 @@ +# Input: +# Filename - facet_size - facet_approx - face_angle - cell_size - cell_shape - iterations + +######################################################### +##### Benchmark MAX (warning: requires a lot of RAM!) +######################################################### +#meshes/elephant.off 0.0068 0.002 25 0.002 3 1 +#meshes/fandisk.off 0.0068 0.003 25 0.003 3 1 +#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.0015 25 0.0015 3 1 +#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.002 25 0.003 3 1 +#Klein_function 0.0068 0.01 25 0.03 3 1 +#Tanglecube_function 0.0068 0.005 25 0.025 3 1 +#Sphere_function 0.0068 0.003 25 0.01 3 1 +#Thin_cylinder_function 0.0068 0.001 25 0.002 3 1 +#Pancake_function 0.0068 0.007 25 0.01 3 1 +#meshes/elephant.off 0.0068 0.002 25 0.002 3 2 +#meshes/fandisk.off 0.0068 0.003 25 0.003 3 2 +#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.0015 25 0.0015 3 2 +#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.002 25 0.003 3 2 +#Klein_function 0.0068 0.01 25 0.03 3 2 +#Tanglecube_function 0.0068 0.005 25 0.025 3 2 +#meshes/cheese.off 0.0068 0.002 25 0.002 3 1 + +######################################################### +##### Benchmark for refinement + optimization +######################################################### +#meshes/elephant.off 0.05 0.04 25 0.04 3 100 +#meshes/elephant.off 0.01 0.004 25 0.004 3 1000 +#meshes/elephant.off 0.0068 0.002 25 0.0025 3 10 # typical timing (11 thr): 4.4 2.3 9.9 +#meshes/elephant.off 0.0068 0.002 25 0.0025 3 10000 +#meshes/fandisk.off 0.0068 0.003 25 0.006 3 1 # typical timing (11 thr): 2.4 1.0 2.9 +#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.0015 25 0.003 3 1 +#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.003 25 0.006 3 1 +#meshes/cheese.off 0.0068 0.002 25 0.002 3 1 +#Klein_function 0.0068 0.01 25 0.06 3 1 +#Pancake_function 0.0068 0.02 25 0.02 3 1 +#Tanglecube_function 0.0068 0.007 25 0.035 3 1 +#Sphere_function 0.0068 0.006 25 0.02 3 1 +#Thin_cylinder_function 0.0068 0.002 25 0.004 3 1 + +######################################################### +##### Benchmark according to number of elements +######################################################### +#meshes/elephant.off 0.0068 0.006 25 0.006 3 10 +#meshes/elephant.off 0.0068 0.005 25 0.005 3 10 + +######################################################### +##### Middle class +######################################################### +#Klein_function 0.0068 0.005 25 2.02 3 1 +#meshes/elephant.off 0.0068 0.005 25 0.005 3 1 + +######################################################### +##### A few seconds +######################################################### +Klein_function 0.0068 0.02 25 0.05 3 10 +meshes/elephant.off 0.0068 0.003 25 0.003 3 1 +meshes/elephant.off 0.0068 0.008 25 0.008 3 2 +meshes/cheese.off 0.0068 0.005 25 0.005 3 1 + +######################################################### +##### Instant +######################################################### +Klein_function 0.0068 0.2 25 0.5 3 1 +meshes/elephant.off 0.0068 0.03 25 0.03 3 5 +meshes/elephant.off 0.0068 0.05 25 0.05 3 5 +meshes/elephant.off 0.0068 0.068 25 0.068 3 1500 +meshes/elephant.off 0.0068 2.68 25 2.68 3 150 +meshes/elephant.off 0.0068 1.68 25 1.68 3 150 +meshes/fandisk.off 0.0068 2.68 25 2.68 3 150 +meshes/fandisk.off 0.0068 1.68 25 1.68 3 150 +meshes/fandisk.off 0.0068 0.05 25 0.05 3 1 +meshes/elephant.off 0.0200 0.05 25 0.25 3 2 + +######################################################### +##### Benchmark for TOMS article +######################################################### +meshes/elephant.off 0.0068 0.002 25 0.002 3 1 +meshes/elephant.off 0.0068 0.003 25 0.003 3 1 +meshes/elephant.off 0.0068 0.004 25 0.004 3 1 +meshes/elephant.off 0.0068 0.005 25 0.005 3 1 +meshes/elephant.off 0.0068 0.006 25 0.006 3 1 +meshes/elephant.off 0.0068 0.007 25 0.007 3 1 +meshes/elephant.off 0.0068 0.008 25 0.008 3 1 +meshes/elephant.off 0.0068 0.010 25 0.010 3 1 +meshes/fandisk.off 0.0068 0.003 25 0.003 3 1 +meshes/fandisk.off 0.0068 0.0035 25 0.0035 3 1 +meshes/fandisk.off 0.0068 0.004 25 0.004 3 1 +meshes/fandisk.off 0.0068 0.005 25 0.005 3 1 +meshes/fandisk.off 0.0068 0.006 25 0.006 3 1 +meshes/fandisk.off 0.0068 0.007 25 0.007 3 1 +meshes/fandisk.off 0.0068 0.008 25 0.008 3 1 +meshes/fandisk.off 0.0068 0.010 25 0.010 3 1 + +#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.0015 25 0.0015 3 1 +#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.002 25 0.002 3 1 +#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.003 25 0.003 3 1 +#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.004 25 0.004 3 1 +#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.005 25 0.005 3 1 +#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.006 25 0.006 3 1 +#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.007 25 0.007 3 1 +#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.008 25 0.008 3 1 +#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.010 25 0.010 3 1 + +#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.003 25 0.003 3 1 +#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.004 25 0.004 3 1 +#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.005 25 0.005 3 1 +#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.006 25 0.006 3 1 +#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.007 25 0.007 3 1 +#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.008 25 0.008 3 1 +#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.010 25 0.010 3 1 + +#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.0015 25 0.0015 3 1 +#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.0017 25 0.0017 3 1 +#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.002 25 0.002 3 1 +#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.0025 25 0.0025 3 1 +#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.003 25 0.003 3 1 +#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.004 25 0.004 3 1 +#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.005 25 0.005 3 1 +#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.006 25 0.006 3 1 +#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.007 25 0.007 3 1 +#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.008 25 0.008 3 1 +#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.010 25 0.010 3 1 + +#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.003 25 0.003 3 1 +#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.004 25 0.004 3 1 +#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.005 25 0.005 3 1 +#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.006 25 0.006 3 1 +#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.007 25 0.007 3 1 +#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.008 25 0.008 3 1 +#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.010 25 0.010 3 1 + +meshes/turbine.off 0.0068 0.002 25 0.002 3 1 +meshes/turbine.off 0.0068 0.003 25 0.003 3 1 +meshes/turbine.off 0.0068 0.004 25 0.004 3 1 +meshes/turbine.off 0.0068 0.005 25 0.005 3 1 +meshes/turbine.off 0.0068 0.006 25 0.006 3 1 +meshes/turbine.off 0.0068 0.007 25 0.007 3 1 +meshes/turbine.off 0.0068 0.008 25 0.008 3 1 +meshes/turbine.off 0.0068 0.010 25 0.010 3 1 + +meshes/cheese.off 0.0068 0.0004 25 0.0004 3 1 +meshes/cheese.off 0.0068 0.0005 25 0.0005 3 1 +meshes/cheese.off 0.0068 0.0007 25 0.0007 3 1 +meshes/cheese.off 0.0068 0.001 25 0.001 3 1 +meshes/cheese.off 0.0068 0.002 25 0.002 3 1 +meshes/cheese.off 0.0068 0.004 25 0.004 3 1 +meshes/cheese.off 0.0068 0.005 25 0.005 3 1 +meshes/cheese.off 0.0068 0.007 25 0.007 3 1 +meshes/cheese.off 0.0068 0.010 25 0.010 3 1 + +#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.002 25 0.002 3 1 +#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.003 25 0.003 3 1 +#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.004 25 0.004 3 1 +#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.005 25 0.005 3 1 +#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.006 25 0.006 3 1 +#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.007 25 0.007 3 1 +#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.008 25 0.008 3 1 +#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.010 25 0.010 3 1 + +Thin_cylinder_function 0.0068 0.001 25 0.003 3 1 +Thin_cylinder_function 0.0068 0.002 25 0.006 3 1 +Thin_cylinder_function 0.0068 0.003 25 0.01 3 1 +Thin_cylinder_function 0.0068 0.006 25 0.02 3 1 +Thin_cylinder_function 0.0068 0.01 25 0.03 3 1 +Thin_cylinder_function 0.0068 0.012 25 0.035 3 1 +Thin_cylinder_function 0.0068 0.013 25 0.04 3 1 +Thin_cylinder_function 0.0068 0.017 25 0.05 3 1 +Thin_cylinder_function 0.0068 0.02 25 0.06 3 1 +Thin_cylinder_function 0.0068 0.023 25 0.07 3 1 +Thin_cylinder_function 0.0068 0.027 25 0.08 3 1 +Thin_cylinder_function 0.0068 0.033 25 0.10 3 1 + +Pancake_function 0.0068 0.004 25 0.013 3 1 +Pancake_function 0.0068 0.006 25 0.02 3 1 +Pancake_function 0.0068 0.01 25 0.03 3 1 +Pancake_function 0.0068 0.012 25 0.035 3 1 +Pancake_function 0.0068 0.013 25 0.04 3 1 +Pancake_function 0.0068 0.017 25 0.05 3 1 +Pancake_function 0.0068 0.02 25 0.06 3 1 +Pancake_function 0.0068 0.023 25 0.07 3 1 +Pancake_function 0.0068 0.027 25 0.08 3 1 +Pancake_function 0.0068 0.033 25 0.10 3 1 + +Klein_function 0.0068 0.01 25 0.03 3 1 +Klein_function 0.0068 0.012 25 0.035 3 1 +Klein_function 0.0068 0.013 25 0.04 3 1 +Klein_function 0.0068 0.017 25 0.05 3 1 +Klein_function 0.0068 0.02 25 0.06 3 1 +Klein_function 0.0068 0.023 25 0.07 3 1 +Klein_function 0.0068 0.027 25 0.08 3 1 +Klein_function 0.0068 0.033 25 0.10 3 1 + +Tanglecube_function 0.0068 0.01 25 0.03 3 1 +Tanglecube_function 0.0068 0.012 25 0.035 3 1 +Tanglecube_function 0.0068 0.013 25 0.04 3 1 +Tanglecube_function 0.0068 0.017 25 0.05 3 1 +Tanglecube_function 0.0068 0.02 25 0.06 3 1 +Tanglecube_function 0.0068 0.023 25 0.07 3 1 +Tanglecube_function 0.0068 0.027 25 0.08 3 1 +Tanglecube_function 0.0068 0.033 25 0.10 3 1 + +Sphere_function 0.0068 0.003 25 0.01 3 1 +Sphere_function 0.0068 0.006 25 0.02 3 1 +Sphere_function 0.0068 0.01 25 0.03 3 1 +Sphere_function 0.0068 0.012 25 0.035 3 1 +Sphere_function 0.0068 0.013 25 0.04 3 1 +Sphere_function 0.0068 0.017 25 0.05 3 1 +Sphere_function 0.0068 0.02 25 0.06 3 1 +Sphere_function 0.0068 0.023 25 0.07 3 1 +Sphere_function 0.0068 0.027 25 0.08 3 1 +Sphere_function 0.0068 0.033 25 0.10 3 1 + +images/liver.inr.gz 0.5 5 25 5 3 1 +images/liver.inr.gz 0.5 2 25 2 3 1 +images/liver.inr.gz 0.5 1.5 25 1.5 3 1 +images/liver.inr.gz 0.5 1 25 1 3 1 +images/liver.inr.gz 0.5 0.8 25 0.8 3 1 +images/liver.inr.gz 0.5 0.65 25 0.65 3 1 + +#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 1.5 25 1.5 3 1 +#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 1 25 1 3 1 +#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 0.8 25 0.8 3 1 +#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 0.65 25 0.65 3 1 +#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 0.40 25 0.40 3 1 +#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 0.30 25 0.30 3 1 + +########### Bug maya ########## +Klein_function 0.0068 0.2 25 0.5 3 1 +meshes/fandisk.off 0.0068 0.5 25 0.5 3 1 + +####### Divers ####### +Klein_function 0.0068 1.1 25 1.1 3 10 +Klein_function 0.0068 0.4 25 0.8 3 1 +Klein_function 0.0068 0.04 25 0.1 3 1 +Klein_function 0.0068 0.01 25 0.03 3 1 +Klein_function 0.0068 0.01 25 0.03 3 1 +meshes/elephant.off 0.0068 0.2 25 0.002 3 1000 +meshes/elephant.off 0.0068 0.007 25 0.007 3 150 +meshes/elephant.off 0.0068 0.02 25 0.02 3 15 +meshes/elephant.off 0.0068 0.2 25 0.2 3 2 +Tanglecube_function 0.0068 0.01 25 0.03 3 1000 + +####### Crash compact cell: SOLVED! ######## +meshes/elephant.off 0.0068 0.005 25 0.005 3 100000 + +####### Test crash "A facet is not in conflict with its refinement point!" - SOLVED ######## +meshes/elephant.off 0.0068 0.002 25 10 3 100000 + +####### Parallel optimizers ######## +meshes/elephant.off 0.0068 0.005 25 0.005 3 1000 +meshes/elephant.off 0.0068 0.002 25 0.003 3 100 +meshes/elephant.off 0.0010 0.068 25 0.068 3 10000 +meshes/elephant.off 0.0020 0.068 25 0.068 3 10000 +meshes/elephant.off 0.0068 0.068 25 0.068 3 10000 +meshes/fandisk.off 0.0068 0.006 25 0.006 3 10 +#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.003 25 0.003 3 10 +#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.005 25 0.006 3 10 +Klein_function 0.0068 0.02 25 0.06 3 10 +Tanglecube_function 0.0068 0.01 25 0.05 3 10 +Sphere_function 0.0068 0.006 25 0.02 3 10 +Thin_cylinder_function 0.0068 0.002 25 0.004 3 10 +Pancake_function 0.0068 0.02 25 0.02 3 10 +meshes/cheese.off 0.0068 0.002 25 0.002 3 10 +Klein_function 0.068 0.04 25 0.15 3 1 +meshes/cheese.off 0.0001 0.004 25 0.0086 3 100 +#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0061 0.061 25 0.061 3 10 diff --git a/Mesh_3/benchmark/Mesh_3/benchmark_mesh_3.cpp b/Mesh_3/benchmark/Mesh_3/benchmark_mesh_3.cpp new file mode 100644 index 000000000000..f8be26f174ac --- /dev/null +++ b/Mesh_3/benchmark/Mesh_3/benchmark_mesh_3.cpp @@ -0,0 +1,681 @@ +#include "benchmark_config.h" +#include "benchmark_xml.h" +#include "mesh_quality.h" + +std::string XML_perf_data::default_filename; + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#ifdef CGAL_LINKED_WITH_TBB +# include +# define TBB_PREVIEW_GLOBAL_CONTROL 1 +# include +#endif + + +#include +#include +#include +#include +#include +#include + +namespace PMP = CGAL::Polygon_mesh_processing; + +// basic types from kernel +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef K::FT FT; +typedef K::Point_3 Point; +typedef K::Sphere_3 Sphere; + +// To avoid verbose function and named parameters call +using namespace CGAL::parameters; + +#include "implicit_functions.h" + +std::string get_output_filename(const std::string& input_name) +{ + std::string filename = std::string(input_name); + filename = filename.substr(filename.find_last_of("/") + 1, filename.length() - 1); + filename = filename.substr(0, filename.find_last_of(".")); + return filename; +} + +std::string get_technique() +{ + std::string tech; +#ifdef CGAL_CONCURRENT_MESH_3 + + tech += "Task-scheduler (auto"; +# ifdef CGAL_MESH_3_LOAD_BASED_WORKSHARING + tech += ", load-based worksharing"; +#endif + tech += ")"; + +#else // !CGAL_CONCURRENT_MESH_3 + + tech += "Sequential "; +# if defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE) +# ifdef CGAL_MESH_3_IF_UNSORTED_QUEUE_JUST_SORT_AFTER_SCAN + tech += "(sort after scan only"; +# else + tech += "(unsorted"; +# endif +# elif defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) + tech += "(sorted"; +# else + tech += "(NOT LAZY, sorted"; +# endif + +#ifdef CGAL_SEQUENTIAL_MESH_3_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE + tech += ", points on far sphere)"; +#else + tech += ")"; +#endif + +#endif // CGAL_CONCURRENT_MESH_3 + + return tech; +} + +void display_info(int num_threads) +{ + std::cout << get_technique() << std::endl; + +#ifdef CGAL_CONCURRENT_MESH_3 + + if(num_threads != -1) + std::cout << "Num threads = " << num_threads << std::endl; + else + std::cout << "Num threads = AUTO" << std::endl; + +#else // !CGAL_CONCURRENT_MESH_3 + +# ifdef CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING + std::cout << "NO random shooting)" << std::endl; +# else + std::cout << "WITH random shooting)" << std::endl; +# endif + +#endif // CGAL_CONCURRENT_MESH_3 +} + +void xml_perf_set_technique() +{ + CGAL_MESH_3_SET_PERFORMANCE_DATA("Technique", get_technique()); +} + +#ifdef CGAL_MESH_3_IMPLICIT_WITH_FEATURES +// To add a crease (feature) to some implicit function +typedef std::vector Crease; +typedef std::list Creases; + +void add_crease(const Point& a, + const Point& b, + Creases& creases) +{ + Crease crease; + crease.push_back(a); + crease.push_back(b); + creases.push_back(crease); +} +#endif + +enum Exit_code +{ + // Success + VALID_OUTPUT = 0, + + // Failure + INPUT_IS_INVALID = 1, + OUTPUT_IS_INVALID = 2 +}; + +// the call to Mesh_3 happens here +template +Exit_code make_mesh(const Domain& domain, + const CGAL::Mesh_criteria_3& criteria, + const std::string& output_filename) +{ +#ifdef _DEBUG + double timelimit = 10; + double sliverbound = 2; +#else + double timelimit = 0; // when making charts, we run this executable a timeout + double sliverbound = 2; +#endif + + CGAL::Real_timer t; + t.start(); + + C3t3 c3t3 = CGAL::make_mesh_3(domain + , criteria +# ifdef CGAL_MESH_3_BENCHMARK_LLOYD + , lloyd(time_limit=timelimit) +# else + , no_lloyd() +# endif +# ifdef CGAL_MESH_3_BENCHMARK_ODT + , odt(time_limit=timelimit) +# else + , no_odt() +#endif +# ifdef CGAL_MESH_3_BENCHMARK_PERTURB + , perturb(time_limit = timelimit, + sliver_bound = sliverbound) +# else + , no_perturb() +#endif +#ifdef CGAL_MESH_3_BENCHMARK_EXUDE + , exude(time_limit = timelimit, + sliver_bound = sliverbound) +#else + , no_exude() +#endif +#ifdef CGAL_MESH_3_MANIFOLD + , manifold() +#else + , non_manifold() +#endif + ); + t.stop(); + + CGAL_MESH_3_SET_PERFORMANCE_DATA("V", c3t3.triangulation().number_of_vertices()); + CGAL_MESH_3_SET_PERFORMANCE_DATA("F", c3t3.number_of_facets_in_complex()); + CGAL_MESH_3_SET_PERFORMANCE_DATA("C", c3t3.number_of_cells_in_complex()); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Mem", CGAL::Memory_sizer().virtual_size() >> 20); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Total_time", t.time()); + +#ifdef CGAL_MESH_3_BENCHMARK_EXPORT_TO_MAYA + std::cout << "Exporting to " << output_filename + ".maya (Maya)... "; + std::ofstream out_maya(output_filename + ".maya"); + c3t3.output_to_maya(out_maya, true); + std::cout << "done." << std::endl; +#endif + +#ifdef CGAL_MESH_3_BENCHMARK_EXPORT_TO_MESH + std::cout << "Exporting to " << output_filename + ".mesh (Medit)... "; + // std::cout << "std::filesystem::current_path() = " << std::filesystem::current_path() << std::endl; + std::ofstream out_medit(output_filename + ".mesh"); + c3t3.output_to_medit(out_medit, true); + std::cout << "done." << std::endl; +#endif + + if(!c3t3.triangulation().is_valid() || !c3t3.is_valid()) + { + std::cerr << "Error: invalid output" << std::endl; + return OUTPUT_IS_INVALID; + } + + if(c3t3.number_of_facets_in_complex() == 0) + { + std::cerr << "Error: no facets in output" << std::endl; + return OUTPUT_IS_INVALID; + } + + if(c3t3.number_of_cells_in_complex() == 0) + { + std::cerr << "Error: no cells in output" << std::endl; + return OUTPUT_IS_INVALID; + } + + generate_quality_metrics(c3t3); + + return VALID_OUTPUT; +} + +template +Exit_code make_mesh(const Domain& domain, + double facet_sizing, double facet_approx, double facet_ang, + double cell_sizing, double cell_shape, + const std::string& output_filename) +{ + typedef CGAL::Mesh_criteria_3 Mesh_criteria; + + const CGAL::Bbox_3 bbox = domain.bbox(); + + const double diag_length = std::sqrt(CGAL::square(bbox.xmax() - bbox.xmin()) + + CGAL::square(bbox.ymax() - bbox.ymin()) + + CGAL::square(bbox.zmax() - bbox.zmin())); + + if(USE_RELATIVE_CRITERIA_VALUES) + { + facet_sizing = diag_length / facet_sizing; + facet_approx = diag_length / facet_approx; + cell_sizing = diag_length / cell_sizing; + } + + Mesh_criteria criteria(edge_size = facet_sizing, + facet_angle = facet_ang, + facet_size = facet_sizing, + facet_distance = facet_approx, + cell_size = cell_sizing, + cell_radius_edge_ratio = cell_shape); + + std::cout << " * edge max size: " << facet_sizing << std::endl + << " * facet max size: " << facet_sizing << std::endl + << " * facet approx error: " << facet_approx << std::endl + << " * facet min angle: " << facet_ang << std::endl + << " * cell max size: " << cell_sizing << std::endl + << " * cell shape (radius-edge): " << cell_shape << std::endl; + + return make_mesh(domain, criteria, output_filename); +} + +Exit_code make_mesh_polyhedron(const std::string& input_filename, + double facet_sizing, double facet_approx, double facet_angle, + double cell_sizing, double cell_shape) +{ + std::cout << "make_mesh_polyhedron(" << input_filename << ")" << std::endl; + + // Domain +#ifdef CGAL_MESH_3_POLYHEDRON_WITH_FEATURES + typedef CGAL::Mesh_polyhedron_3::type Polyhedron; + typedef CGAL::Polyhedral_mesh_domain_with_features_3 Mesh_domain; +#else + typedef CGAL::Polyhedron_3 Polyhedron; + typedef CGAL::Polyhedral_mesh_domain_3 Mesh_domain; +#endif + + // Triangulation +#ifdef CGAL_CONCURRENT_MESH_3 + typedef CGAL::Mesh_triangulation_3::Kernel, + CGAL::Parallel_tag>::type Tr; +#else + typedef CGAL::Mesh_triangulation_3::type Tr; +#endif + + // C3t3 + typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; + + // Create input polyhedron + Polyhedron polyhedron; + if(!CGAL::IO::read_polygon_mesh(input_filename, polyhedron)) + { + std::cerr << "Error: Could not read '" << input_filename << "'" << std::endl; + return INPUT_IS_INVALID; + } + + if(is_empty(polyhedron) || + !is_triangle_mesh(polyhedron) || + !is_closed(polyhedron) || + has_degenerate_faces(polyhedron) || + PMP::does_self_intersect(polyhedron)) + { + std::cerr << "Error: input has defects" << std::endl; + return INPUT_IS_INVALID; + } + + std::cout << "Building AABB tree... " << std::endl; + // Create domain + Mesh_domain domain(polyhedron); + std::cout << "done." << std::endl; + +#ifdef CGAL_MESH_3_POLYHEDRON_WITH_FEATURES + std::cout << "Detecting features..." << std::endl; + domain.detect_features(); + std::cout << "done." << std::endl; +#endif + + return make_mesh(domain, + facet_sizing, facet_approx, facet_angle, + cell_sizing, cell_shape, + get_output_filename(input_filename)); +} + +Exit_code make_mesh_3D_images(const std::string& input_filename, + double facet_sizing, double facet_approx, double facet_angle, + double cell_sizing, double cell_shape) +{ + std::cout << "make_mesh_3D_images(" << input_filename << ")" << std::endl; + + // Domain + typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; + + // Triangulation +#ifdef CGAL_CONCURRENT_MESH_3 + typedef CGAL::Mesh_triangulation_3::Kernel, + CGAL::Parallel_tag>::type Tr; +#else + typedef CGAL::Mesh_triangulation_3::type Tr; +#endif + + // C3t3 + typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; + + // Load image + CGAL::Image_3 image; + image.read(input_filename.c_str()); + + // Create domain + Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); + std::cout << "done." << std::endl; + + return make_mesh(domain, + facet_sizing, facet_approx, facet_angle, + cell_sizing, cell_shape, + get_output_filename(input_filename)); +} + +template +Exit_code make_mesh_implicit(const std::string& function_name, + ImplicitFunction func, + double facet_sizing, double facet_approx, double facet_angle, + double cell_sizing, double cell_shape) +{ + std::cout << "make_mesh_implicit(" << function_name << ")" << std::endl; + + // Domain +#ifdef CGAL_MESH_3_IMPLICIT_WITH_FEATURES + typedef CGAL::Labeled_mesh_domain_3 Implicit_domain; + typedef CGAL::Mesh_domain_with_polyline_features_3 Mesh_domain; +#else + typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; +#endif + + // Triangulation +#ifdef CGAL_CONCURRENT_MESH_3 + typedef typename CGAL::Mesh_triangulation_3::Kernel, + CGAL::Parallel_tag>::type Tr; +#else + typedef typename CGAL::Mesh_triangulation_3::type Tr; +#endif + + // C3t3 + typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; + + // Create domain + Sphere bounding_sphere(CGAL::ORIGIN, 10.0 * 10.0); + + namespace p = CGAL::parameters; + Mesh_domain domain = Mesh_domain::create_implicit_mesh_domain(p::function = func, + p::bounding_object = bounding_sphere + /*, p::relative_error_bound = 1e-7*/); + +#ifdef CGAL_MESH_3_IMPLICIT_WITH_FEATURES + // Add 12 feature creases + Creases creases; + Point p1(-1.0, -1.0, -1.0); + Point p2(-1.0, -1.0, 1.0); + Point p3(-1.0, 1.0, 1.0); + Point p4(-1.0, 1.0, -1.0); + Point p5( 1.0, -1.0, -1.0); + Point p6( 1.0, -1.0, 1.0); + Point p7( 1.0, 1.0, 1.0); + Point p8( 1.0, 1.0, -1.0); + + add_crease(p1, p2, creases); + add_crease(p2, p3, creases); + add_crease(p3, p4, creases); + add_crease(p4, p1, creases); + + add_crease(p5, p6, creases); + add_crease(p6, p7, creases); + add_crease(p7, p8, creases); + add_crease(p8, p5, creases); + + add_crease(p5, p1, creases); + add_crease(p6, p2, creases); + add_crease(p7, p3, creases); + add_crease(p8, p4, creases); + + domain.add_features(creases.begin(), creases.end()); +#endif + + return make_mesh(domain, + facet_sizing, facet_approx, facet_angle, + cell_sizing, cell_shape, + function_name); +} + +// logs the parameters, and dispatch to polyhedral, implicit or image domain +Exit_code run(const std::string& input, + double facet_approx, double facet_sizing, double facet_angle, + double cell_sizing, double cell_shape, + int num_iteration) +{ + std::string domain = input; + size_t slash_index = domain.find_last_of('/'); + if(slash_index == std::string::npos) + slash_index = domain.find_last_of('\\'); + if(slash_index == std::string::npos) + slash_index = 0; + else + ++slash_index; + + domain = domain.substr(slash_index, domain.find_last_of('.') - slash_index); + + CGAL_MESH_3_SET_PERFORMANCE_DATA("Domain", domain); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Facet_size", facet_sizing); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Facet_approx", facet_approx); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Facet_angle", facet_angle); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Cell_size", cell_sizing); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Cell_shape", cell_shape); + xml_perf_set_technique(); + + Exit_code res; + for(int j=0; j 1) + XML_perf_data::default_filename = argv[1]; + +#if defined(CHECK_MEMORY_LEAKS_ON_MSVC) && defined(_MSC_VER) + _CrtSetDbgFlag ( _CRTDtbbBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); +#endif + +#ifdef CGAL_CONCURRENT_MESH_3 + Concurrent_mesher_config::load_config_file(CONCURRENT_MESHER_CONFIG_FILENAME, true); + + int max_nb_threads = Concurrent_mesher_config::get().num_threads; + if(max_nb_threads == -1) // if not set in the config file, take the max available + max_nb_threads = tbb::this_task_arena::max_concurrency(); +#endif + + Exit_code res; + +#ifdef CGAL_CONCURRENT_MESH_3 + #ifdef BENCHMARK_WITH_1_TO_MAX_THREADS + for(int num_threads=1; num_threads<=max_nb_threads; ++num_threads) + #else + int num_threads = max_nb_threads; + #endif // BENCHMARK_WITH_1_TO_MAX_THREADS +#endif // CGAL_CONCURRENT_MESH_3 + { +#ifdef CGAL_CONCURRENT_MESH_3 + std::cout << "-- Parallel Mesh_3 --" << std::endl; + tbb::global_control control(tbb::global_control::max_allowed_parallelism, num_threads); + display_info(num_threads); + + CGAL_MESH_3_SET_PERFORMANCE_DATA("Num_threads", num_threads); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Lockgrid_size", Concurrent_mesher_config::get().locking_grid_num_cells_per_axis); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Lock_radius", Concurrent_mesher_config::get().first_grid_lock_radius); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Statgrid_size", Concurrent_mesher_config::get().work_stats_grid_num_cells_per_axis); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Num_work_items_per_batch", Concurrent_mesher_config::get().num_work_items_per_batch); +#else + std::cout << "-- Sequential Mesh_3 --" << std::endl; + + CGAL_MESH_3_SET_PERFORMANCE_DATA("Num_threads", "N/A"); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Lockgrid_size", "N/A"); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Lock_radius", "N/A"); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Statgrid_size", "N/A"); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Num_work_items_per_batch", "N/A"); +#endif + + // Script file format: each line gives + // - Filename (polyhedron and image) or "XXX_function" (implicit) + // - Facet and cell criteria + // - Number of iterations with these parameters + std::ifstream script_file; + script_file.open(BENCHMARK_INPUTS_FILENAME); + if(script_file.is_open()) + { + std::cout << "Found inputs file '" << BENCHMARK_INPUTS_FILENAME << "'" << std::endl; + + std::string line; + while(std::getline(script_file, line)) + { + if(line.empty() || line[0] == '#') // lines starting with '#' are ignored + continue; + + std::cout << std::endl << std::endl; + std::cout << "*****************************************" << std::endl; + std::cout << "******* " << line << std::endl; + std::cout << "*****************************************" << std::endl; + + std::stringstream sstr(line); + + std::string input; + double facet_approx, facet_sizing, facet_angle; + double cell_sizing, cell_shape; + int num_iteration; + if(!(sstr >> input + >> facet_approx + >> facet_sizing + >> facet_angle + >> cell_sizing + >> cell_shape + >> num_iteration)) + { + std::cerr << "Error: failed to read input" << std::endl; + return INPUT_IS_INVALID; + } + + res = run(input, + facet_approx, facet_sizing, facet_angle, + cell_sizing, cell_shape, + num_iteration); + } + } + else // no script + { + std::cout << "Inputs file '" << BENCHMARK_INPUTS_FILENAME << "' NOT found." << std::endl; + + // If the script is empty, use the command line arguments: + // [this_program] + // - filename + // - facet_sizing + // - facet_approx + // - facet_angle + // - cell_sizing + // - cell_shape + // - num_iteration + + std::string input = (argc > 2) ? argv[2] : "Sphere_function"; // @fixme klein assertion? + double facet_sizing = (argc > 3) ? std::stod(argv[3]) : DEFAULT_FACE_SIZE; + double facet_approx = (argc > 4) ? std::stod(argv[4]) : DEFAULT_FACE_APPROX; + double facet_angle = (argc > 5) ? std::stod(argv[5]) : DEFAULT_FACE_ANGLE; // 25° + double cell_sizing = (argc > 6) ? std::stod(argv[6]) : DEFAULT_CELL_SIZE; + double cell_shape = (argc > 7) ? std::stod(argv[7]) : DEFAULT_CELL_RADIUS_RATIO; // 3 + + if(facet_sizing <= 0) + facet_sizing = DEFAULT_FACE_SIZE; + if(facet_approx <= 0) + facet_approx = DEFAULT_FACE_APPROX; + if(facet_angle <= 0) + facet_angle = DEFAULT_FACE_ANGLE; + if(cell_sizing <= 0) + cell_sizing = DEFAULT_CELL_SIZE; + if(cell_shape <= 0) + cell_shape = DEFAULT_CELL_RADIUS_RATIO; + + res = run(input, + facet_approx, facet_sizing, facet_angle, + cell_sizing, cell_shape, + 1 /*num_iteration*/); + } + } + + return res; +} diff --git a/Mesh_3/benchmark/Mesh_3/benchmark_xml.h b/Mesh_3/benchmark/Mesh_3/benchmark_xml.h new file mode 100644 index 000000000000..b859776cdec5 --- /dev/null +++ b/Mesh_3/benchmark/Mesh_3/benchmark_xml.h @@ -0,0 +1,139 @@ +#ifndef CGAL_MESH_3_BENCHMARK_BENCHMARK_XML_H +#define CGAL_MESH_3_BENCHMARK_BENCHMARK_XML_H + +#include "../../test/Mesh_3/XML_exporter.h" + +#define CGAL_MESH_3_EXPORT_PERFORMANCE_DATA +#define CGAL_MESH_3_SET_PERFORMANCE_DATA(value_name, value) \ + XML_perf_data::set(value_name, value); + +class XML_perf_data +{ +public: + typedef Streaming_XML_exporter XML_exporter; + +private: + XML_exporter m_xml; + XML_exporter::Element_with_map m_current_element; + +public: + static std::string default_filename; + + 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 + 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() + { + if(default_filename != "") + return default_filename; + + std::stringstream sstr; + sstr << "Performance_log_" << time(0) << ".xml"; + return sstr.str(); + } + + static std::vector construct_subelements_names() + { + std::vector subelements; + subelements.push_back("Domain"); + + subelements.push_back("Facet_angle"); + subelements.push_back("Facet_size"); + subelements.push_back("Facet_approx"); + subelements.push_back("Cell_size"); + subelements.push_back("Cell_shape"); + + subelements.push_back("Technique"); + subelements.push_back("Num_threads"); + subelements.push_back("Lockgrid_size"); + subelements.push_back("Lock_radius"); + subelements.push_back("Statgrid_size"); + subelements.push_back("Num_work_items_per_batch"); + + subelements.push_back("V"); + subelements.push_back("F"); + subelements.push_back("C"); + + subelements.push_back("Facets_scan_time"); + subelements.push_back("Facets_refine_time"); + subelements.push_back("Cells_scan_time"); + subelements.push_back("Cells_refine_time"); + subelements.push_back("Lloyd_optim_time"); + subelements.push_back("Odt_optim_time"); + subelements.push_back("Perturber_optim_time"); + subelements.push_back("Exuder_optim_time"); + subelements.push_back("Total_time"); + + subelements.push_back("Mem"); + + subelements.push_back("Minimum_edge_length"); + subelements.push_back("Mean_edge_length"); + subelements.push_back("Maximum_edge_length"); + + subelements.push_back("Minimum_facet_area"); + subelements.push_back("Mean_facet_area"); + subelements.push_back("Maximum_facet_area"); + subelements.push_back("Total_area"); + + subelements.push_back("Minimum_facet_angle"); + subelements.push_back("Maximum_facet_angle"); + + subelements.push_back("Minimum_cell_volume"); + subelements.push_back("Mean_cell_volume"); + subelements.push_back("Maximum_cell_volume"); + subelements.push_back("Total_volume"); + + subelements.push_back("Minimum_dihedral_angle"); + subelements.push_back("Mean_dihedral_angle"); + subelements.push_back("Maximum_dihedral_angle"); + + subelements.push_back("Smallest_edge_radius_ratio"); + subelements.push_back("Smallest_radius_radius_ratio"); + subelements.push_back("Biggest_V_SMA"); + + return subelements; + } + + void set_data(const std::string& name, const std::string& value) + { + m_current_element[name] = value; + } + + template + 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(); + } +}; + +#endif // CGAL_MESH_3_BENCHMARK_BENCHMARK_XML_H diff --git a/Mesh_3/benchmark/Mesh_3/concurrency.cpp b/Mesh_3/benchmark/Mesh_3/concurrency.cpp deleted file mode 100644 index 153f235d2b8e..000000000000 --- a/Mesh_3/benchmark/Mesh_3/concurrency.cpp +++ /dev/null @@ -1,1022 +0,0 @@ -//#define CHECK_MEMORY_LEAKS_ON_MSVC - -#if defined(CHECK_MEMORY_LEAKS_ON_MSVC) && defined(_MSC_VER) - #define _CRTDBG_MAP_ALLOC - #include - #include -#endif - -// Without TBB_USE_THREADING_TOOL Intel Inspector XE will report false positives in Intel TBB -// (https://www.intel.com/content/www/us/en/developer/articles/technical/compiler-settings-for-threading-error-analysis-in-intel-inspector-xe.html) -#ifdef _DEBUG -# define TBB_USE_THREADING_TOOL -#endif - -#include -#include -#include -#include -#include - -#ifdef CGAL_USE_BOOST_PROGRAM_OPTIONS -# include - namespace po = boost::program_options; -#endif - -#include -#include - -const char * const BENCHMARK_CONFIG_FILENAME = "concurrency_config.cfg"; -const char * const BENCHMARK_SCRIPT_FILENAME = "concurrency_script.txt"; - -// ========================================================================== -// BENCHMARK GENERAL PARAMETERS -// ========================================================================== - -//#define BENCHMARK_WITH_1_TO_MAX_THREADS -//#define CGAL_MESH_3_POLYHEDRON_WITH_FEATURES -//#define CGAL_MESH_3_IMPLICIT_WITH_FEATURES -//#define CGAL_MESH_3_BENCHMARK_EXPORT_TO_MAYA -//#define CGAL_MESH_3_BENCHMARK_EXPORT_TO_MESH -//#define CGAL_MESH_3_BENCHMARK_LLOYD -//#define CGAL_MESH_3_BENCHMARK_PERTURB -//#define CGAL_MESH_3_BENCHMARK_EXUDE - -// ========================================================================== -// MESH_3 GENERAL PARAMETERS -// ========================================================================== - -//#define CGAL_MESH_3_USE_OLD_SURFACE_RESTRICTED_DELAUNAY_UPDATE // WARNING: VERY SLOW -//#define CGAL_MESH_3_VERBOSE -//#define CGAL_MESH_3_PERTURBER_VERBOSE -//#define CGAL_MESH_3_PERTURBER_HIGH_VERBOSITY -//#define CGAL_MESH_3_EXUDER_VERBOSE -//#define CGAL_MESH_3_EXUDER_HIGH_VERBOSITY -//#define CGAL_MESH_3_VERY_VERBOSE -//#define CGAL_MESHES_DEBUG_REFINEMENT_POINTS -//#define CGAL_MESH_3_OPTIMIZER_VERBOSE -#define CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING - -#define CGAL_MESH_3_PROFILING -//#define CHECK_AND_DISPLAY_THE_NUMBER_OF_BAD_ELEMENTS_IN_THE_END - -const int FACET_ANGLE = 25; -const int TET_SHAPE = 3; - -// ========================================================================== -// CONCURRENCY -// ========================================================================== - -#ifdef CGAL_CONCURRENT_MESH_3 - -# ifndef CGAL_LINKED_WITH_TBB -# pragma message(" : Warning: CGAL_LINKED_WITH_TBB not defined: EVERYTHING WILL BE SEQUENTIAL.") -# endif - -//# define CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE // default behavior -//# define CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE -//# define CGAL_MESH_3_IF_UNSORTED_QUEUE_JUST_SORT_AFTER_SCAN // recommended -//#define CGAL_PARALLEL_MESH_3_DO_NOT_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE // not recommended - - // ========================================================================== - // Verbose - // ========================================================================== - -# define CGAL_CONCURRENT_MESH_3_VERBOSE -//# define CGAL_CONCURRENT_MESH_3_VERY_VERBOSE - - // ========================================================================== - // Concurrency config - // ========================================================================== - - const char * const CONFIG_FILENAME = "concurrent_mesher_config.cfg"; - - // ===================== - // Worksharing strategy - // ===================== - -//# define CGAL_MESH_3_LOAD_BASED_WORKSHARING // Not recommended - - // ========================================================================== - // Profiling - // ========================================================================== - - // For profiling, etc. -# define CGAL_CONCURRENT_MESH_3_PROFILING -//# define CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT - -#include - -// ========================================================================== -// SEQUENTIAL -// ========================================================================== - -#else // !CGAL_CONCURRENT_MESH_3 - -//# define CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE // default behavior -//# define CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE -//# define CGAL_MESH_3_IF_UNSORTED_QUEUE_JUST_SORT_AFTER_SCAN // recommended - -#endif // CGAL_CONCURRENT_MESH_3 - -// ========================================================================== -// ========================================================================== - -const char * const DEFAULT_INPUT_FILE_NAME = "elephant.off"; - -// ========================================================================== -// ========================================================================== - -#include "../../test/Mesh_3/XML_exporter.h" -#define CGAL_MESH_3_EXPORT_PERFORMANCE_DATA -#define CGAL_MESH_3_SET_PERFORMANCE_DATA(value_name, value) \ - XML_perf_data::set(value_name, value); - -class XML_perf_data -{ -public: - typedef Streaming_XML_exporter 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 - 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 construct_subelements_names() - { - std::vector subelements; - subelements.push_back("Domain"); - subelements.push_back("Facet_angle"); - subelements.push_back("Facet_size"); - subelements.push_back("Facet_approx"); - subelements.push_back("Cell_size"); - subelements.push_back("Cell_shape"); - subelements.push_back("Technique"); - subelements.push_back("Num_threads"); - subelements.push_back("Lockgrid_size"); - subelements.push_back("Lock_radius"); - subelements.push_back("Statgrid_size"); - subelements.push_back("Num_work_items_per_batch"); - subelements.push_back("V"); - subelements.push_back("F"); - subelements.push_back("T"); - subelements.push_back("Facets_time"); - subelements.push_back("Cells_scan_time"); - subelements.push_back("Cells_refin_time"); - subelements.push_back("Lloyd_optim_time"); - subelements.push_back("Odt_optim_time"); - subelements.push_back("Perturber_optim_time"); - subelements.push_back("Exuder_optim_time"); - subelements.push_back("Mem"); - - return subelements; - } - - void set_data(const std::string &name, const std::string &value) - { - m_current_element[name] = value; - } - - template - 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; -}; - - -// ========================================================================== -// ========================================================================== - - - -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -#ifdef CGAL_MESH_3_POLYHEDRON_WITH_FEATURES -# include -#endif - -// basic types from kernel -typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; -typedef Kernel::FT FT; -typedef Kernel::Point_3 Point; -typedef Kernel::Sphere_3 Sphere; -// IO -#include - -// To avoid verbose function and named parameters call -using namespace CGAL::parameters; - -struct Mesh_parameters -{ - double facet_approx; - double facet_sizing; - double facet_angle; - - double tet_shape; - double tet_sizing; - - std::string log() const - { - std::stringstream sstr; - sstr - << " * facet approx error: " << facet_approx << std::endl - << " * facet max size: " << facet_sizing << std::endl - << " * facet min angle: " << facet_angle << std::endl - << " * tet shape (radius-edge): " << tet_shape << std::endl - << " * tet max size: " << tet_sizing << std::endl; - - return sstr.str(); - } -}; - -struct Klein_function -{ - typedef ::FT FT; - typedef ::Point Point; - - FT operator()(const Point& query) const - { - const FT x = query.x(); - const FT y = query.y(); - const FT z = query.z(); - - return (x*x+y*y+z*z+2*y-1) - * ( (x*x+y*y+z*z-2*y-1) *(x*x+y*y+z*z-2*y-1)-8*z*z) - + 16*x*z* (x*x+y*y+z*z-2*y-1); - } -}; - -struct Tanglecube_function -{ - typedef ::FT FT; - typedef ::Point Point; - - FT operator()(const Point& query) const - { - const FT x = query.x(); - const FT y = query.y(); - const FT z = query.z(); - - double x2=x*x, y2=y*y, z2=z*z; - double x4=x2*x2, y4=y2*y2, z4=z2*z2; - return x4 - 5*x2 + y4 - 5*y2 + z4 - 5*z2 + 11.8; - } -}; - -struct Sphere_function -{ - typedef ::FT FT; - typedef ::Point Point; - - Sphere_function(double radius = 1.) - : m_squared_radius(radius*radius) - {} - - FT operator()(const Point& query) const - { - const FT x = query.x(); - const FT y = query.y(); - const FT z = query.z(); - - return (x*x + y*y + z*z - m_squared_radius); - } - -protected: - FT m_squared_radius; -}; - -struct Cylinder_function -{ - typedef ::FT FT; - typedef ::Point Point; - - Cylinder_function(double radius = 0.5, double height = 2.) - : m_radius(radius), m_height(height) - {} - - FT operator()(const Point& query) const - { - const FT x = query.x(); - const FT y = query.y(); - const FT z = query.z(); - - if (z > 0.5*m_height) - return z - 0.5*m_height; - else if (z < -0.5*m_height) - return -z + 0.5*m_height; - else - return (x*x + y*y - m_radius*m_radius); - } - -protected: - FT m_radius; - FT m_height; -}; - - -std::string get_technique() -{ - std::string tech; -#ifdef CGAL_CONCURRENT_MESH_3 - - tech += "Task-scheduler (auto"; -# ifdef CGAL_MESH_3_LOAD_BASED_WORKSHARING - tech += ", load-based worksharing"; -#endif - tech += ")"; - -#else // !CGAL_CONCURRENT_MESH_3 - - tech += "Sequential "; -# if defined(CGAL_MESH_3_USE_LAZY_UNSORTED_REFINEMENT_QUEUE) -# ifdef CGAL_MESH_3_IF_UNSORTED_QUEUE_JUST_SORT_AFTER_SCAN - tech += "(sort after scan only"; -# else - tech += "(unsorted"; -# endif -# elif defined(CGAL_MESH_3_USE_LAZY_SORTED_REFINEMENT_QUEUE) - tech += "(sorted"; -# else - tech += "(NOT LAZY, sorted"; -# endif - -#ifdef CGAL_SEQUENTIAL_MESH_3_ADD_OUTSIDE_POINTS_ON_A_FAR_SPHERE - tech += ", points on far sphere)"; -#else - tech += ")"; -#endif - -#endif // CGAL_CONCURRENT_MESH_3 - - return tech; -} - -void xml_perf_set_technique() -{ - CGAL_MESH_3_SET_PERFORMANCE_DATA("Technique", get_technique()); -} - - -void display_info(int num_threads) -{ - std::cerr << get_technique() << std::endl; - -#ifdef CGAL_CONCURRENT_MESH_3 - - if (num_threads != -1) - std::cerr << "Num threads = " << num_threads << std::endl; - else - std::cerr << "Num threads = AUTO" << std::endl; - -#else // !CGAL_CONCURRENT_MESH_3 - -# ifdef CGAL_MESH_3_INITIAL_POINTS_NO_RANDOM_SHOOTING - std::cerr << "NO random shooting)" << std::endl; -# else - std::cerr << "WITH random shooting)" << std::endl; -# endif - -#endif // CGAL_CONCURRENT_MESH_3 -} - -// To add a crease (feature) -typedef std::vector Crease; -typedef std::list Creases; -void add_crease(const Point& a, - const Point& b, - Creases& creases) -{ - Crease crease; - crease.push_back(a); - crease.push_back(b); - creases.push_back(crease); -} - -bool make_mesh_polyhedron(const std::string &input_filename, - double facet_approx, - double facet_sizing, - double cell_sizing) -{ - // Domain - typedef Kernel K; - -#ifdef CGAL_MESH_3_POLYHEDRON_WITH_FEATURES - typedef CGAL::Mesh_polyhedron_3::type Polyhedron; - typedef CGAL::Polyhedral_mesh_domain_with_features_3 Mesh_domain; -#else - typedef CGAL::Polyhedron_3 Polyhedron; - typedef CGAL::Polyhedral_mesh_domain_3 Mesh_domain; -#endif - - // Triangulation -#ifdef CGAL_CONCURRENT_MESH_3 - typedef CGAL::Mesh_triangulation_3< - Mesh_domain, - CGAL::Kernel_traits::Kernel, - CGAL::Parallel_tag>::type Tr; -#else - typedef CGAL::Mesh_triangulation_3::type Tr; -#endif - // C3t3 - typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; - // Criteria - typedef CGAL::Mesh_criteria_3 Mesh_criteria; - - // Create input polyhedron - Polyhedron polyhedron; - std::ifstream input(input_filename.c_str()); - if (!input.is_open()) - { - std::cerr << "Could not open '" << input_filename << "'" << std::endl; - return false; - } - input >> polyhedron; - - std::cerr << "Building AABB tree... "; - // Create domain - Mesh_domain domain(polyhedron); - std::cerr << "done." << std::endl; - -#ifdef CGAL_MESH_3_POLYHEDRON_WITH_FEATURES - std::cerr << "Detecting features... "; - domain.detect_features(); - std::cerr << "done." << std::endl; -#endif - - Mesh_parameters params; - params.facet_approx = facet_approx; - params.facet_sizing = facet_sizing; - params.facet_angle = FACET_ANGLE; - params.tet_sizing = cell_sizing; - params.tet_shape = TET_SHAPE; - - std::cerr - << "File: " << input_filename << std::endl - << "Parameters: " << std::endl - << params.log() << std::endl; - - // Mesh criteria (no cell_size set) - Mesh_criteria criteria( - edge_size=params.facet_sizing, - facet_angle=params.facet_angle, - facet_size=params.facet_sizing, - facet_distance=params.facet_approx, - cell_size=params.tet_sizing, - cell_radius_edge_ratio=params.tet_shape - ); - - // Mesh generation -#ifdef _DEBUG - double timelimit = 10; - double sliverbound = 2; -#else - double timelimit = 0; - double sliverbound = 2; -#endif - - C3t3 c3t3 = CGAL::make_mesh_3( domain - , criteria -# ifdef CGAL_MESH_3_BENCHMARK_LLOYD - , lloyd(time_limit=timelimit) -# else - , no_lloyd() -# endif - , no_odt() -# ifdef CGAL_MESH_3_BENCHMARK_PERTURB - , perturb(time_limit = timelimit, - sliver_bound = sliverbound) -# else - , no_perturb() -#endif -#ifdef CGAL_MESH_3_BENCHMARK_EXUDE - , exude(time_limit = timelimit, - sliver_bound = sliverbound) -#else - , no_exude() -#endif - ); - - CGAL_MESH_3_SET_PERFORMANCE_DATA("V", c3t3.triangulation().number_of_vertices()); - CGAL_MESH_3_SET_PERFORMANCE_DATA("F", c3t3.number_of_facets_in_complex()); - CGAL_MESH_3_SET_PERFORMANCE_DATA("T", c3t3.number_of_cells_in_complex()); - CGAL_MESH_3_SET_PERFORMANCE_DATA("Mem", CGAL::Memory_sizer().virtual_size() >> 20); - -#ifdef CGAL_MESH_3_BENCHMARK_EXPORT_TO_MAYA - std::cerr << "Exporting to maya file format (*.maya)... "; - c3t3.output_to_maya(std::ofstream(input_filename + ".maya"), true); - std::cerr << "done." << std::endl; -#endif - -#ifdef CGAL_MESH_3_BENCHMARK_EXPORT_TO_MESH - std::cerr << "Exporting to Medit file format (*.mesh)... "; - c3t3.output_to_medit(std::ofstream(input_filename + ".mesh"), true); - std::cerr << "done." << std::endl; -#endif - - return true; -} - - -bool make_mesh_3D_images(const std::string &input_filename, - double facet_approx, - double facet_sizing, - double cell_sizing) -{ - // Domain - typedef Kernel K; - - typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; - - // Triangulation -#ifdef CGAL_CONCURRENT_MESH_3 - typedef CGAL::Mesh_triangulation_3< - Mesh_domain, - CGAL::Kernel_traits::Kernel, - CGAL::Parallel_tag>::type Tr; -#else - typedef CGAL::Mesh_triangulation_3::type Tr; -#endif - // C3t3 - typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; - // Criteria - typedef CGAL::Mesh_criteria_3 Mesh_criteria; - - // Load image - CGAL::Image_3 image; - image.read(input_filename.c_str()); - - // Create domain - Mesh_domain domain = Mesh_domain::create_labeled_image_mesh_domain(image); - std::cerr << "done." << std::endl; - - Mesh_parameters params; - params.facet_approx = facet_approx; - params.facet_sizing = facet_sizing; - params.facet_angle = FACET_ANGLE; - params.tet_sizing = cell_sizing; - params.tet_shape = TET_SHAPE; - - std::cerr - << "File: " << input_filename << std::endl - << "Parameters: " << std::endl - << params.log() << std::endl; - - // Mesh criteria (no cell_size set) - Mesh_criteria criteria( - edge_size=params.facet_sizing, - facet_angle=params.facet_angle, - facet_size=params.facet_sizing, - facet_distance=params.facet_approx, - cell_size=params.tet_sizing, - cell_radius_edge_ratio=params.tet_shape - ); - - // Mesh generation -#ifdef _DEBUG - double timelimit = 10; - double sliverbound = 2; -#else - double timelimit = 0; - double sliverbound = 2; -#endif - - C3t3 c3t3 = CGAL::make_mesh_3( domain - , criteria -# ifdef CGAL_MESH_3_BENCHMARK_LLOYD - , lloyd(time_limit=timelimit) -# else - , no_lloyd() -# endif - , no_odt() -# ifdef CGAL_MESH_3_BENCHMARK_PERTURB - , perturb(time_limit = timelimit, - sliver_bound = sliverbound) -# else - , no_perturb() -#endif -#ifdef CGAL_MESH_3_BENCHMARK_EXUDE - , exude(time_limit = timelimit, - sliver_bound = sliverbound) -#else - , no_exude() -#endif - ); - - CGAL_MESH_3_SET_PERFORMANCE_DATA("V", c3t3.triangulation().number_of_vertices()); - CGAL_MESH_3_SET_PERFORMANCE_DATA("F", c3t3.number_of_facets_in_complex()); - CGAL_MESH_3_SET_PERFORMANCE_DATA("T", c3t3.number_of_cells_in_complex()); - CGAL_MESH_3_SET_PERFORMANCE_DATA("Mem", CGAL::Memory_sizer().virtual_size() >> 20); - -#ifdef CGAL_MESH_3_BENCHMARK_EXPORT_TO_MAYA - std::cerr << "Exporting to maya file format (*.maya)... "; - c3t3.output_to_maya(std::ofstream(input_filename + ".maya"), true); - std::cerr << "done." << std::endl; -#endif - -#ifdef CGAL_MESH_3_BENCHMARK_EXPORT_TO_MESH - std::cerr << "Exporting to Medit file format (*.mesh)... "; - c3t3.output_to_medit(std::ofstream(input_filename + ".mesh"), true); - std::cerr << "done." << std::endl; -#endif - - return true; -} - - -template -bool make_mesh_implicit(double facet_approx, - double facet_sizing, - double cell_sizing, - ImplicitFunction func, - const std::string &function_name) -{ - // Domain -#ifdef CGAL_MESH_3_IMPLICIT_WITH_FEATURES - typedef CGAL::Labeled_mesh_domain_3 Implicit_domain; - typedef CGAL::Mesh_domain_with_polyline_features_3 Mesh_domain; -#else - typedef CGAL::Labeled_mesh_domain_3 Mesh_domain; -#endif - - // Triangulation -#ifdef CGAL_CONCURRENT_MESH_3 - typedef typename CGAL::Mesh_triangulation_3< - Mesh_domain, - typename CGAL::Kernel_traits::Kernel, - CGAL::Parallel_tag>::type Tr; -#else - typedef typename CGAL::Mesh_triangulation_3::type Tr; -#endif - // C3t3 - typedef CGAL::Mesh_complex_3_in_triangulation_3 C3t3; - // Criteria - typedef CGAL::Mesh_criteria_3 Mesh_criteria; - - // Create domain - Sphere bounding_sphere(CGAL::ORIGIN, 10.0 * 10.0); - - namespace p = CGAL::parameters; - Mesh_domain domain = Mesh_domain::create_implicit_mesh_domain(p::function = func, - p::bounding_object = bounding_sphere - /*, p::relative_error_bound = 1e-7*/); - -#ifdef CGAL_MESH_3_IMPLICIT_WITH_FEATURES - // Add 12 feature creases - Creases creases; - Point p1(-1.0, -1.0, -1.0); - Point p2(-1.0, -1.0, 1.0); - Point p3(-1.0, 1.0, 1.0); - Point p4(-1.0, 1.0, -1.0); - Point p5( 1.0, -1.0, -1.0); - Point p6( 1.0, -1.0, 1.0); - Point p7( 1.0, 1.0, 1.0); - Point p8( 1.0, 1.0, -1.0); - - add_crease(p1, p2, creases); - add_crease(p2, p3, creases); - add_crease(p3, p4, creases); - add_crease(p4, p1, creases); - - add_crease(p5, p6, creases); - add_crease(p6, p7, creases); - add_crease(p7, p8, creases); - add_crease(p8, p5, creases); - - add_crease(p5, p1, creases); - add_crease(p6, p2, creases); - add_crease(p7, p3, creases); - add_crease(p8, p4, creases); - - domain.add_features(creases.begin(), creases.end()); -#endif - - Mesh_parameters params; - params.facet_angle = FACET_ANGLE; - params.facet_sizing = facet_sizing; - params.facet_approx = facet_approx; - params.tet_sizing = cell_sizing; - params.tet_shape = TET_SHAPE; - - std::cerr - << "Implicit function" << std::endl - << "Parameters: " << std::endl - << params.log() << std::endl; - - // Mesh criteria (no cell_size set) - Mesh_criteria criteria( - edge_size=params.facet_sizing, - facet_angle=params.facet_angle, - facet_size=params.facet_sizing, - facet_distance=params.facet_approx, - cell_size=params.tet_sizing, - cell_radius_edge_ratio=params.tet_shape - ); - - // Mesh generation -#ifdef _DEBUG - double timelimit = 10; - double sliverbound = 2; -#else - double timelimit = 0; - double sliverbound = 2; -#endif - - C3t3 c3t3 = CGAL::make_mesh_3( domain - , criteria -# ifdef CGAL_MESH_3_BENCHMARK_LLOYD - , lloyd(time_limit=timelimit) -# else - , no_lloyd() -# endif - , no_odt() -# ifdef CGAL_MESH_3_BENCHMARK_PERTURB - , perturb(time_limit = timelimit, - sliver_bound = sliverbound) -# else - , no_perturb() -#endif -#ifdef CGAL_MESH_3_BENCHMARK_EXUDE - , exude(time_limit = timelimit, - sliver_bound = sliverbound) -#else - , no_exude() -#endif - ); - - CGAL_MESH_3_SET_PERFORMANCE_DATA("V", c3t3.triangulation().number_of_vertices()); - CGAL_MESH_3_SET_PERFORMANCE_DATA("F", c3t3.number_of_facets_in_complex()); - CGAL_MESH_3_SET_PERFORMANCE_DATA("T", c3t3.number_of_cells_in_complex()); - CGAL_MESH_3_SET_PERFORMANCE_DATA("Mem", CGAL::Memory_sizer().virtual_size() >> 20); - -#ifdef CGAL_MESH_3_BENCHMARK_EXPORT_TO_MAYA - std::cerr << "Exporting to maya file format (*.maya)... "; - c3t3.output_to_maya(std::ofstream(function_name + ".maya"), true); - std::cerr << "done." << std::endl; -#endif - -#ifdef CGAL_MESH_3_BENCHMARK_EXPORT_TO_MESH - std::cerr << "Exporting to Medit file format (*.mesh)... "; - c3t3.output_to_medit(std::ofstream(function_name + ".mesh"), true); - std::cerr << "done." << std::endl; -#endif - - return true; -} - -int main() -{ -#if defined(CHECK_MEMORY_LEAKS_ON_MSVC) && defined(_MSC_VER) - _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); -#endif - -#ifdef CGAL_USE_BOOST_PROGRAM_OPTIONS - // Program options - po::variables_map vm; - try - { - // Declare the supported options. - po::options_description desc("Allowed options"); - desc.add_options() - ("filename", po::value()->default_value(DEFAULT_INPUT_FILE_NAME), "") - ("facet_approx", po::value()->default_value(0.0068), "") - ("facet_sizing", po::value()->default_value(0.005), "") - ("cell_sizing", po::value()->default_value(0.005), "") - ("numthreads", po::value()->default_value(-1), ""); - - std::ifstream in(BENCHMARK_CONFIG_FILENAME); - po::store(po::parse_config_file(in, desc), vm); - po::notify(vm); - } - catch (std::exception &e) - { - std::cerr << "Config file error: " << e.what() << std::endl; - return false; - } - int num_threads = vm["numthreads"].as(); - double facet_approx = vm["facet_approx"].as(); - double facet_sizing = vm["facet_sizing"].as(); - double cell_sizing = vm["cell_sizing"].as(); - std::string filename = vm["filename"].as(); - -#else // no CGAL_USE_BOOST_PROGRAM_OPTIONS - int num_threads = -1; - double facet_approx = 0.0068; - double facet_sizing = 0.005; - double cell_sizing = 0.005; - std::string filename = DEFAULT_INPUT_FILE_NAME; - -#endif - -#ifdef CGAL_CONCURRENT_MESH_3 - Concurrent_mesher_config::load_config_file(CONFIG_FILENAME, true); -#endif - - std::ifstream script_file; - script_file.open(BENCHMARK_SCRIPT_FILENAME); - // Script? - // Script file format: each line gives - // - Filename (polyhedron) or "XXX_function" (implicit) - // - Facet sizing - // - Cell sizing - // - Number of iterations with these parameters - if (script_file.is_open()) - { - int i = 1; -#ifdef CGAL_CONCURRENT_MESH_3 -# ifdef BENCHMARK_WITH_1_TO_MAX_THREADS - for(num_threads = 1 ; - num_threads <= tbb::task_scheduler_init::default_num_threads() ; - ++num_threads) -# endif - /*for (Concurrent_mesher_config::get().num_work_items_per_batch = 5 ; - Concurrent_mesher_config::get().num_work_items_per_batch < 100 ; - Concurrent_mesher_config::get().num_work_items_per_batch += 5)*/ -#endif - { -#ifdef CGAL_CONCURRENT_MESH_3 - tbb::task_scheduler_init init( - num_threads > 0 ? num_threads : tbb::task_scheduler_init::automatic); -#endif - - std::cerr << "Script file '" << BENCHMARK_SCRIPT_FILENAME << "' found." << std::endl; - script_file.seekg(0); - while (script_file.good()) - { - std::string line; - std::getline(script_file, line); - if (line.size() > 1 && line[0] != '#') - { - std::cerr << std::endl << std::endl; - std::cerr << "*****************************************" << std::endl; - std::cerr << "******* " << line << std::endl; - std::cerr << "*****************************************" << std::endl; - std::stringstream sstr(line); - - std::string input; - double facet_approx; - double facet_sizing; - double cell_sizing; - int num_iteration; - sstr >> input; - sstr >> facet_approx; - sstr >> facet_sizing; - sstr >> cell_sizing; - sstr >> num_iteration; - - for (int j = 0 ; j < num_iteration ; ++j) - { - std::string domain = input; - size_t slash_index = domain.find_last_of('/'); - if (slash_index == std::string::npos) - slash_index = domain.find_last_of('\\'); - if (slash_index == std::string::npos) - slash_index = 0; - else - ++slash_index; - domain = domain.substr( - slash_index, domain.find_last_of('.') - slash_index); - - CGAL_MESH_3_SET_PERFORMANCE_DATA("Domain", domain); - CGAL_MESH_3_SET_PERFORMANCE_DATA("Facet_approx", facet_approx); - CGAL_MESH_3_SET_PERFORMANCE_DATA("Facet_size", facet_sizing); - CGAL_MESH_3_SET_PERFORMANCE_DATA("Facet_angle", FACET_ANGLE); - CGAL_MESH_3_SET_PERFORMANCE_DATA("Cell_size", cell_sizing); - CGAL_MESH_3_SET_PERFORMANCE_DATA("Cell_shape", TET_SHAPE); - xml_perf_set_technique(); -#ifdef CGAL_CONCURRENT_MESH_3 - CGAL_MESH_3_SET_PERFORMANCE_DATA( - "Num_threads", - (num_threads == -1 ? tbb::task_scheduler_init::default_num_threads() : num_threads)); - CGAL_MESH_3_SET_PERFORMANCE_DATA( - "Lockgrid_size", - Concurrent_mesher_config::get().locking_grid_num_cells_per_axis); - CGAL_MESH_3_SET_PERFORMANCE_DATA( - "Lock_radius", - Concurrent_mesher_config::get().first_grid_lock_radius); - CGAL_MESH_3_SET_PERFORMANCE_DATA( - "Statgrid_size", - Concurrent_mesher_config::get().work_stats_grid_num_cells_per_axis); - CGAL_MESH_3_SET_PERFORMANCE_DATA( - "Num_work_items_per_batch", - Concurrent_mesher_config::get().num_work_items_per_batch); -#else - CGAL_MESH_3_SET_PERFORMANCE_DATA("Num_threads", "N/A"); - CGAL_MESH_3_SET_PERFORMANCE_DATA("Lockgrid_size", "N/A"); - CGAL_MESH_3_SET_PERFORMANCE_DATA("Lock_radius", "N/A"); - CGAL_MESH_3_SET_PERFORMANCE_DATA("Statgrid_size", "N/A"); - CGAL_MESH_3_SET_PERFORMANCE_DATA("Num_work_items_per_batch", "N/A"); -#endif - - std::cerr << std::endl << "Refinement #" << i << "..." << std::endl; - - display_info(num_threads); - - if (input == "Klein_function") - make_mesh_implicit(facet_approx, facet_sizing, cell_sizing, Klein_function(), input); - /*else if (input == "Tanglecube_function") - make_mesh_implicit(facet_approx, facet_sizing, cell_sizing, Tanglecube_function(), input); - else if (input == "Sphere_function") - make_mesh_implicit(facet_approx, facet_sizing, cell_sizing, Sphere_function(1.), input); - else if (input == "Thin_cylinder_function") - { - Cylinder_function f(0.05, 3.); - make_mesh_implicit(facet_approx, facet_sizing, cell_sizing, f, input); - } - else if (input == "Pancake_function") - { - Cylinder_function f(3., 0.1); - make_mesh_implicit(facet_approx, facet_sizing, cell_sizing, f, input); - }*/ - else - { - size_t dot_position = input.find_last_of('.'); - std::string extension = input.substr(dot_position + 1); - if (extension == "off") - make_mesh_polyhedron(input, facet_approx, facet_sizing, cell_sizing); - else if (extension == "inr") - make_mesh_3D_images(input, facet_approx, facet_sizing, cell_sizing); - } - - std::cerr << "Refinement #" << i++ << " done." << std::endl; - std::cerr << std::endl << "---------------------------------" << std::endl << std::endl; - - XML_perf_data::commit(); - } - } - } - script_file.seekg(0); - script_file.clear(); - } - - script_file.close(); - } - // Or not script? - else - { - std::cerr << "Script file '" << BENCHMARK_SCRIPT_FILENAME << "' NOT found." << std::endl; - for(int i = 1 ; ; ++i) - { - std::cerr << "Refinement #" << i << "..." << std::endl; - display_info(num_threads); - make_mesh_polyhedron(filename, facet_approx, facet_sizing, cell_sizing); - //make_mesh_implicit(facet_approx, facet_sizing, cell_sizing, Klein_function(), "Klein_function"); - std::cerr << "Refinement #" << i << " done." << std::endl; - std::cerr << std::endl << "---------------------------------" << std::endl << std::endl; - } - } - - return 0; -} diff --git a/Mesh_3/benchmark/Mesh_3/concurrency_config.cfg b/Mesh_3/benchmark/Mesh_3/concurrency_config.cfg deleted file mode 100644 index 57d6a2329ad4..000000000000 --- a/Mesh_3/benchmark/Mesh_3/concurrency_config.cfg +++ /dev/null @@ -1,6 +0,0 @@ -#filename=D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off -filename=D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off -facet_sizing=0.01 -cell_sizing=0.03 -numthreads=11 # default = -1 (auto) - \ No newline at end of file diff --git a/Mesh_3/benchmark/Mesh_3/concurrency_script.txt b/Mesh_3/benchmark/Mesh_3/concurrency_script.txt deleted file mode 100644 index e236d6f0ba57..000000000000 --- a/Mesh_3/benchmark/Mesh_3/concurrency_script.txt +++ /dev/null @@ -1,266 +0,0 @@ -######################################################### -##### Benchmark MAX (warning: requires a lot of RAM!) -######################################################### -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.002 0.002 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.003 0.003 1 -#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.0015 0.0015 1 -#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.002 0.003 1 -#Klein_function 0.0068 0.01 0.03 1 -#Tanglecube_function 0.0068 0.005 0.025 1 -#Sphere_function 0.0068 0.003 0.01 1 -#Thin_cylinder_function 0.0068 0.001 0.002 1 -#Pancake_function 0.0068 0.007 0.01 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.002 0.002 2 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.003 0.003 2 -#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.0015 0.0015 2 -#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.002 0.003 2 -#Klein_function 0.0068 0.01 0.03 2 -#Tanglecube_function 0.0068 0.005 0.025 2 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/cheese.off 0.0068 0.002 0.002 1 - -######################################################### -##### Benchmark for refinement+optim -######################################################### -#../../examples/Mesh_3/data/elephant.off 0.05 0.04 0.04 10000 -#../../examples/Mesh_3/data/elephant.off 0.01 0.004 0.004 10000 -../../examples/Mesh_3/data/elephant.off 0.0068 0.002 0.0025 10000 # typical timing (11 thr): 4.4 2.3 9.9 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.002 0.0025 10000 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.003 0.006 1 # typical timing (11 thr): 2.4 1.0 2.9 -#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.0015 0.003 1 -#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.003 0.006 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/cheese.off 0.0068 0.002 0.002 1 -#Klein_function 0.0068 0.01 0.06 1 -#Pancake_function 0.0068 0.02 0.02 1 -#Tanglecube_function 0.0068 0.007 0.035 1 -#Sphere_function 0.0068 0.006 0.02 1 -#Thin_cylinder_function 0.0068 0.002 0.004 1 - -######################################################### -##### Benchmark according to number of elements -######################################################### -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.006 0.006 10 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.005 0.005 10 - -######################################################### -##### Middle class -######################################################### -#Klein_function 0.0068 0.005 2.02 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.005 0.005 1 - -######################################################### -##### A few seconds -######################################################### -#Klein_function 0.0068 0.02 0.05 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.003 0.003 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.008 0.008 2 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/cheese.off 0.0068 0.005 0.005 1 - -######################################################### -##### Instant -######################################################### -#Klein_function 0.0068 0.2 0.5 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.03 0.03 5 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.05 0.05 5 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.068 0.068 1500 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 2.68 2.68 150 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 1.68 1.68 150 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 2.68 2.68 150 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 1.68 1.68 150 -#D:/INRIA/CGAL/svn/cgal/trunk/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.05 0.05 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0200 0.05 0.25 2 - -######################################################### -##### Benchmark for TOMS article -######################################################### -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.002 0.002 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.003 0.003 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.004 0.004 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.005 0.005 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.006 0.006 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.007 0.007 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.008 0.008 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.010 0.010 1 - -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.003 0.003 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.0035 0.0035 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.004 0.004 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.005 0.005 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.006 0.006 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.007 0.007 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.008 0.008 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.010 0.010 1 - -#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.0015 0.0015 1 -#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.002 0.002 1 -#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.003 0.003 1 -#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.004 0.004 1 -#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.005 0.005 1 -#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.006 0.006 1 -#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.007 0.007 1 -#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.008 0.008 1 -#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.010 0.010 1 - -#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.003 0.003 1 -#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.004 0.004 1 -#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.005 0.005 1 -#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.006 0.006 1 -#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.007 0.007 1 -#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.008 0.008 1 -#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.010 0.010 1 - -#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.0015 0.0015 1 -#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.0017 0.0017 1 -#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.002 0.002 1 -#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.0025 0.0025 1 -#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.003 0.003 1 -#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.004 0.004 1 -#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.005 0.005 1 -#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.006 0.006 1 -#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.007 0.007 1 -#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.008 0.008 1 -#D:/INRIA/Data/_Models/BigOFF/david_200kv.off 0.0068 0.010 0.010 1 - -#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.003 0.003 1 -#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.004 0.004 1 -#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.005 0.005 1 -#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.006 0.006 1 -#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.007 0.007 1 -#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.008 0.008 1 -#D:/INRIA/Data/_Models/CAD/ecrou-larousse.off 0.0068 0.010 0.010 1 - -#D:/INRIA/Data/_Models/CAD/turbine.off 0.0068 0.002 0.002 1 -#D:/INRIA/Data/_Models/CAD/turbine.off 0.0068 0.003 0.003 1 -#D:/INRIA/Data/_Models/CAD/turbine.off 0.0068 0.004 0.004 1 -#D:/INRIA/Data/_Models/CAD/turbine.off 0.0068 0.005 0.005 1 -#D:/INRIA/Data/_Models/CAD/turbine.off 0.0068 0.006 0.006 1 -#D:/INRIA/Data/_Models/CAD/turbine.off 0.0068 0.007 0.007 1 -#D:/INRIA/Data/_Models/CAD/turbine.off 0.0068 0.008 0.008 1 -#D:/INRIA/Data/_Models/CAD/turbine.off 0.0068 0.010 0.010 1 - -#D:/INRIA/Data/_Models/CAD/cheese.off 0.0068 0.0004 0.0004 1 -#D:/INRIA/Data/_Models/CAD/cheese.off 0.0068 0.0005 0.0005 1 -#D:/INRIA/Data/_Models/CAD/cheese.off 0.0068 0.0007 0.0007 1 -#D:/INRIA/Data/_Models/CAD/cheese.off 0.0068 0.001 0.001 1 -#D:/INRIA/Data/_Models/CAD/cheese.off 0.0068 0.002 0.002 1 -#D:/INRIA/Data/_Models/CAD/cheese.off 0.0068 0.004 0.004 1 -#D:/INRIA/Data/_Models/CAD/cheese.off 0.0068 0.005 0.005 1 -#D:/INRIA/Data/_Models/CAD/cheese.off 0.0068 0.007 0.007 1 -#D:/INRIA/Data/_Models/CAD/cheese.off 0.0068 0.010 0.010 1 - -#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.002 0.002 1 -#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.003 0.003 1 -#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.004 0.004 1 -#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.005 0.005 1 -#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.006 0.006 1 -#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.007 0.007 1 -#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.008 0.008 1 -#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0068 0.010 0.010 1 - -#Thin_cylinder_function 0.0068 0.001 0.003 1 -#Thin_cylinder_function 0.0068 0.002 0.006 1 -#Thin_cylinder_function 0.0068 0.003 0.01 1 -#Thin_cylinder_function 0.0068 0.006 0.02 1 -#Thin_cylinder_function 0.0068 0.01 0.03 1 -#Thin_cylinder_function 0.0068 0.012 0.035 1 -#Thin_cylinder_function 0.0068 0.013 0.04 1 -#Thin_cylinder_function 0.0068 0.017 0.05 1 -#Thin_cylinder_function 0.0068 0.02 0.06 1 -#Thin_cylinder_function 0.0068 0.023 0.07 1 -#Thin_cylinder_function 0.0068 0.027 0.08 1 -#Thin_cylinder_function 0.0068 0.033 0.10 1 - -#Pancake_function 0.0068 0.004 0.013 1 -#Pancake_function 0.0068 0.006 0.02 1 -#Pancake_function 0.0068 0.01 0.03 1 -#Pancake_function 0.0068 0.012 0.035 1 -#Pancake_function 0.0068 0.013 0.04 1 -#Pancake_function 0.0068 0.017 0.05 1 -#Pancake_function 0.0068 0.02 0.06 1 -#Pancake_function 0.0068 0.023 0.07 1 -#Pancake_function 0.0068 0.027 0.08 1 -#Pancake_function 0.0068 0.033 0.10 1 - -#Klein_function 0.0068 0.01 0.03 1 -#Klein_function 0.0068 0.012 0.035 1 -#Klein_function 0.0068 0.013 0.04 1 -#Klein_function 0.0068 0.017 0.05 1 -#Klein_function 0.0068 0.02 0.06 1 -#Klein_function 0.0068 0.023 0.07 1 -#Klein_function 0.0068 0.027 0.08 1 -#Klein_function 0.0068 0.033 0.10 1 - -#Tanglecube_function 0.0068 0.01 0.03 1 -#Tanglecube_function 0.0068 0.012 0.035 1 -#Tanglecube_function 0.0068 0.013 0.04 1 -#Tanglecube_function 0.0068 0.017 0.05 1 -#Tanglecube_function 0.0068 0.02 0.06 1 -#Tanglecube_function 0.0068 0.023 0.07 1 -#Tanglecube_function 0.0068 0.027 0.08 1 -#Tanglecube_function 0.0068 0.033 0.10 1 - -#Sphere_function 0.0068 0.003 0.01 1 -#Sphere_function 0.0068 0.006 0.02 1 -#Sphere_function 0.0068 0.01 0.03 1 -#Sphere_function 0.0068 0.012 0.035 1 -#Sphere_function 0.0068 0.013 0.04 1 -#Sphere_function 0.0068 0.017 0.05 1 -#Sphere_function 0.0068 0.02 0.06 1 -#Sphere_function 0.0068 0.023 0.07 1 -#Sphere_function 0.0068 0.027 0.08 1 -#Sphere_function 0.0068 0.033 0.10 1 - -#D:/INRIA/Data/_Models/3D_images/liver_kidney_gallbladder.inr 0.5 5 5 1 -#D:/INRIA/Data/_Models/3D_images/liver_kidney_gallbladder.inr 0.5 2 2 1 -#D:/INRIA/Data/_Models/3D_images/liver_kidney_gallbladder.inr 0.5 1.5 1.5 1 -#D:/INRIA/Data/_Models/3D_images/liver_kidney_gallbladder.inr 0.5 1 1 1 -#D:/INRIA/Data/_Models/3D_images/liver_kidney_gallbladder.inr 0.5 0.8 0.8 1 -#D:/INRIA/Data/_Models/3D_images/liver_kidney_gallbladder.inr 0.5 0.65 0.65 1 - -#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 1.5 1.5 1 -#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 1 1 1 -#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 0.8 0.8 1 -#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 0.65 0.65 1 -#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 0.40 0.40 1 -#D:/INRIA/Data/_Models/3D_images/VisibleHuman1mm.inr 0.3 0.30 0.30 1 - - -########### Bug maya ########## -#Klein_function 0.0068 0.2 0.5 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.5 0.5 1 - -####### Divers ####### -#Klein_function 0.0068 1.1 1.1 10 -#Klein_function 0.0068 0.4 0.8 1 -#Klein_function 0.0068 0.04 0.1 1 -#Klein_function 0.0068 0.01 0.03 1 -#Klein_function 0.0068 0.01 0.03 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.2 0.002 1000 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.007 0.007 150 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.02 0.02 15 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.2 0.2 2 -#Tanglecube_function 0.0068 0.01 0.03 1000 - -####### Crash compact cell: SOLVED! ######## -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.005 0.005 100000 - -####### Test crash "A facet is not in conflict with its refinement point!" - SOLVED ######## -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.002 10 100000 - -####### Parallel optimizers ######## -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.005 0.005 1000 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.002 0.003 100 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0010 0.068 0.068 10000 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0020 0.068 0.068 10000 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/elephant.off 0.0068 0.068 0.068 10000 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/fandisk.off 0.0068 0.006 0.006 10 -#D:/INRIA/Data/_Models/BigOFF/lucy-100kt.off 0.0068 0.003 0.003 10 -#D:/INRIA/Data/_Models/BigOFF/bimba_400kf.off 0.0068 0.005 0.006 10 -#Klein_function 0.0068 0.02 0.06 10 -#Tanglecube_function 0.0068 0.01 0.05 10 -#Sphere_function 0.0068 0.006 0.02 10 -#Thin_cylinder_function 0.0068 0.002 0.004 10 -#Pancake_function 0.0068 0.02 0.02 10 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/cheese.off 0.0068 0.002 0.002 10 -#Klein_function 0.068 0.04 0.15 1 -#D:/INRIA/CGAL/workingcopy/Mesh_3/examples/Mesh_3/data/cheese.off 0.0001 0.004 0.0086 100 -#D:/INRIA/Data/_Models/CAD/pump_carter.off 0.0061 0.061 0.061 10 diff --git a/Mesh_3/benchmark/Mesh_3/concurrent_mesher_config.cfg b/Mesh_3/benchmark/Mesh_3/concurrent_mesher_config.cfg index 2ac949502da3..ed58c2d04f49 100644 --- a/Mesh_3/benchmark/Mesh_3/concurrent_mesher_config.cfg +++ b/Mesh_3/benchmark/Mesh_3/concurrent_mesher_config.cfg @@ -1,3 +1,9 @@ +#========================================== +#========== Number of threads ============= +#========================================== + +number_of_threads = -1 # default = -1 (all) + #========================================== #======== Worksharing strategy =========== #========================================== @@ -5,7 +11,6 @@ locking_grid_num_cells_per_axis = 50 first_grid_lock_radius = 0 - #========================================== #============= Brute-force ================ #========================================== @@ -13,7 +18,6 @@ first_grid_lock_radius = 0 #locking_grid_num_cells_per_axis = 30 #first_grid_lock_radius = 2 - #========================================== #=============== Other ==================== #========================================== @@ -21,7 +25,7 @@ first_grid_lock_radius = 0 refinement_grainsize = 10 # for parallel_for techniques refinement_batch_size = 10000 # for parallel_for technique work_stats_grid_num_cells_per_axis = 5 # for "task" technique -num_work_items_per_batch = 50 # for "task" technique +num_work_items_per_batch = 50 # for "task" technique min_num_vertices_of_coarse_mesh = 100 num_vertices_of_coarse_mesh_per_core = 3.5 -num_pseudo_infinite_vertices_per_core = 5.0 \ No newline at end of file +num_pseudo_infinite_vertices_per_core = 5.0 diff --git a/Mesh_3/benchmark/Mesh_3/implicit_functions.h b/Mesh_3/benchmark/Mesh_3/implicit_functions.h new file mode 100644 index 000000000000..b904bdcb0f4b --- /dev/null +++ b/Mesh_3/benchmark/Mesh_3/implicit_functions.h @@ -0,0 +1,83 @@ +struct Klein_function +{ + typedef ::FT FT; + typedef ::Point Point; + + FT operator()(const Point& query) const + { + const FT x = query.x(); + const FT y = query.y(); + const FT z = query.z(); + + return (x*x+y*y+z*z+2*y-1) + * ( (x*x+y*y+z*z-2*y-1) *(x*x+y*y+z*z-2*y-1)-8*z*z) + + 16*x*z* (x*x+y*y+z*z-2*y-1); + } +}; + +struct Tanglecube_function +{ + typedef ::FT FT; + typedef ::Point Point; + + FT operator()(const Point& query) const + { + const FT x = query.x(); + const FT y = query.y(); + const FT z = query.z(); + + double x2 = x*x, y2 = y*y, z2 = z*z; + double x4 = x2*x2, y4 = y2*y2, z4 = z2*z2; + return x4 - 5*x2 + y4 - 5*y2 + z4 - 5*z2 + 11.8; + } +}; + +struct Sphere_function +{ + typedef ::FT FT; + typedef ::Point Point; + + Sphere_function(double radius = 1.) + : m_squared_radius(radius*radius) + {} + + FT operator()(const Point& query) const + { + const FT x = query.x(); + const FT y = query.y(); + const FT z = query.z(); + + return (x*x + y*y + z*z - m_squared_radius); + } + +protected: + FT m_squared_radius; +}; + +struct Cylinder_function +{ + typedef ::FT FT; + typedef ::Point Point; + + Cylinder_function(double radius = 0.5, double height = 2.) + : m_radius(radius), m_height(height) + {} + + FT operator()(const Point& query) const + { + const FT x = query.x(); + const FT y = query.y(); + const FT z = query.z(); + + if(z > 0.5*m_height) + return z - 0.5*m_height; + else if(z < -0.5*m_height) + return -z + 0.5*m_height; + else + return (x*x + y*y - m_radius*m_radius); + } + +protected: + FT m_radius; + FT m_height; +}; \ No newline at end of file diff --git a/Mesh_3/benchmark/Mesh_3/mesh_quality.h b/Mesh_3/benchmark/Mesh_3/mesh_quality.h new file mode 100644 index 000000000000..16616123c1b7 --- /dev/null +++ b/Mesh_3/benchmark/Mesh_3/mesh_quality.h @@ -0,0 +1,328 @@ +#ifndef CGAL_MESH_3_BENCHMARK_MESH_3_MESH_QUALITY_H +#define CGAL_MESH_3_BENCHMARK_MESH_3_MESH_QUALITY_H + +#include "benchmark_xml.h" + +#include +#include +#include +#include +#include + +#include +#include + +template +bool has_degenerate_faces(const TriangleMesh& mesh, + const NamedParameters& np = CGAL::parameters::default_values()) +{ + namespace PMP = CGAL::Polygon_mesh_processing; + + for(auto f : faces(mesh)) + if(CGAL::Polygon_mesh_processing::is_degenerate_triangle_face(f, mesh, np)) + return true; + + return false; +} + +struct Surface_quality +{ + double minimum_edge_length; + double mean_edge_length; + double maximum_edge_length; + + double minimum_area; + double mean_area; + double maximum_area; + double total_area; + + double minimum_angle; + double maximum_angle; +}; + +struct Volume_quality +{ + double minimum_volume; + double mean_volume; + double maximum_volume; + double total_volume; + + double minimum_dihedral_angle; + double mean_dihedral_angle; + double maximum_dihedral_angle; + + double smallest_edge_radius_ratio; + double smallest_radius_radius_ratio; + double biggest_v_sma; +}; + +template +void generate_surface_qualitymetrics(const C3t3& c3t3, + Surface_quality& surface_quality) +{ + typedef typename C3t3::Triangulation Triangulation; + + surface_quality.minimum_edge_length = -1.; + surface_quality.mean_edge_length = -1.; + surface_quality.maximum_edge_length = -1.; + + surface_quality.minimum_area = -1.; + surface_quality.mean_area = -1.; + surface_quality.maximum_area = -1.; + + surface_quality.minimum_angle = -1.; + surface_quality.maximum_angle = -1.; + + surface_quality.total_area = -1.; + + // edge length + if(c3t3.number_of_edges_in_complex() > 0) + { + std::vector edge_lengths; + + auto edge_it = c3t3.edges_in_complex_begin(), + end = c3t3.edges_in_complex_end(); + for(; edge_it!=end; ++edge_it) + { + const typename Triangulation::Cell_handle c = edge_it->first; + const int i = edge_it->second; + const int j = edge_it->third; + const typename Triangulation::Bare_point& pi = c3t3.triangulation().point(c, i).point(); + const typename Triangulation::Bare_point& pj = c3t3.triangulation().point(c, j).point(); + + const double edge_length = CGAL::approximate_sqrt(CGAL::squared_distance(pi, pj)); + edge_lengths.push_back(edge_length); + } + + surface_quality.minimum_edge_length = *std::min_element(edge_lengths.begin(), edge_lengths.end()); + surface_quality.maximum_edge_length = *std::max_element(edge_lengths.begin(), edge_lengths.end()); + + surface_quality.mean_edge_length = std::accumulate(edge_lengths.begin(), edge_lengths.end(), 0.) / edge_lengths.size(); + } + + // area + if(c3t3.number_of_facets_in_complex() > 0) + { + std::vector areas; + + auto facet_it = c3t3.facets_in_complex_begin(), + end = c3t3.facets_in_complex_end(); + for(; facet_it!=end; ++facet_it) + { + const typename Triangulation::Cell_handle c = facet_it->first; + const int s = facet_it->second; + + const typename Triangulation::Bare_point& pi = c3t3.triangulation().point(c, (s+1)%4).point(); + const typename Triangulation::Bare_point& pj = c3t3.triangulation().point(c, (s+2)%4).point(); + const typename Triangulation::Bare_point& pk = c3t3.triangulation().point(c, (s+3)%4).point(); + + const double area = CGAL::approximate_sqrt(CGAL::squared_area(pi, pj, pk)); + areas.push_back(area); + } + + surface_quality.minimum_area = *std::min_element(areas.begin(), areas.end()); + surface_quality.maximum_area = *std::max_element(areas.begin(), areas.end()); + surface_quality.total_area = std::accumulate(areas.begin(), areas.end(), 0.); + surface_quality.mean_area = surface_quality.total_area / areas.size(); + } + + // angle + if(c3t3.number_of_facets_in_complex() > 0) + { + std::vector angles; + + auto facet_it = c3t3.facets_in_complex_begin(), + end = c3t3.facets_in_complex_end(); + for(; facet_it!=end; ++facet_it) + { + const typename Triangulation::Cell_handle c = facet_it->first; + const int s = facet_it->second; + std::array indices = {(s+1)%4, (s+2)%4, (s+3)%4}; + + for(int o=0; o<3; ++o) + { + const typename Triangulation::Bare_point& ei = c3t3.triangulation().point(c, indices[o]).point(); + const typename Triangulation::Bare_point& ej = c3t3.triangulation().point(c, indices[(o+1)%3]).point(); + const typename Triangulation::Bare_point& ek = c3t3.triangulation().point(c, indices[(o+2)%3]).point(); + + const double angle = CGAL::approximate_angle(ei, ej, ek); + angles.push_back(angle); + } + } + + surface_quality.minimum_angle = *std::min_element(angles.begin(), angles.end()); + surface_quality.maximum_angle = *std::max_element(angles.begin(), angles.end()); + } +} + +template +void generate_volume_quality_metrics(const C3t3& c3t3, + Volume_quality& volume_quality) +{ + typedef typename C3t3::Triangulation Triangulation; + + volume_quality.minimum_dihedral_angle = (std::numeric_limits::max)(); + volume_quality.mean_dihedral_angle = 0; + volume_quality.maximum_dihedral_angle = 0; + + volume_quality.minimum_volume = (std::numeric_limits::max)(); + volume_quality.mean_volume = 0; + volume_quality.maximum_volume = 0; + + volume_quality.total_volume = 0; + + volume_quality.smallest_edge_radius_ratio = (std::numeric_limits::max)(); + volume_quality.smallest_radius_radius_ratio = (std::numeric_limits::max)(); + volume_quality.biggest_v_sma = 0; + + // volume + if(c3t3.number_of_cells_in_complex() > 0) + { + std::vector volumes; + + auto cell_it = c3t3.cells_in_complex_begin(), + end = c3t3.cells_in_complex_end(); + for(; cell_it!=end; ++cell_it) + { + const typename Triangulation::Cell_handle c = cell_it; + const typename Triangulation::Bare_point& p0 = c3t3.triangulation().point(c, 0).point(); + const typename Triangulation::Bare_point& p1 = c3t3.triangulation().point(c, 1).point(); + const typename Triangulation::Bare_point& p2 = c3t3.triangulation().point(c, 2).point(); + const typename Triangulation::Bare_point& p3 = c3t3.triangulation().point(c, 3).point(); + + const double volume = CGAL::volume(p0, p1, p2, p3); + volumes.push_back(volume); + } + + volume_quality.minimum_volume = *std::min_element(volumes.begin(), volumes.end()); + volume_quality.maximum_volume = *std::max_element(volumes.begin(), volumes.end()); + volume_quality.total_volume = std::accumulate(volumes.begin(), volumes.end(), 0.); + volume_quality.mean_volume = volume_quality.total_volume / volumes.size(); + } + + // dihedral angle + if(c3t3.number_of_cells_in_complex() > 0) + { + std::vector dihedral_angles; + + auto cell_it = c3t3.cells_in_complex_begin(), + end = c3t3.cells_in_complex_end(); + for(; cell_it!=end; ++cell_it) + { + const typename Triangulation::Cell_handle c = cell_it; + + std::array pts; + for(int i=0; i<4; ++i) + pts[i] = c3t3.triangulation().point(c, i).point(); + + constexpr std::array dhis = { 0, 1, 2, 3, + 2, 0, 1, 3, + 0, 3, 1, 2, + 2, 1, 3, 0, + 3, 1, 0, 2, + 3, 2, 1, 0 }; + for(int dhi=0; dhi<6; ++dhi) + { + double dh_angle = CGAL::approximate_dihedral_angle(pts[dhis[4*dhi]], pts[dhis[4*dhi+1]], + pts[dhis[4*dhi+2]], pts[dhis[4*dhi+3]]); + dihedral_angles.push_back(std::abs(dh_angle)); + } + } + + volume_quality.minimum_dihedral_angle = *std::min_element(dihedral_angles.begin(), dihedral_angles.end()); + volume_quality.maximum_dihedral_angle = *std::max_element(dihedral_angles.begin(), dihedral_angles.end()); + volume_quality.mean_dihedral_angle = std::accumulate(dihedral_angles.begin(), dihedral_angles.end(), 0.) / dihedral_angles.size(); + } + + // smallest edge-radius ratio + if(c3t3.number_of_cells_in_complex() > 0) + { + auto cell_it = c3t3.cells_in_complex_begin(), + end = c3t3.cells_in_complex_end(); + for(; cell_it!=end; ++cell_it) + { + const typename Triangulation::Bare_point& p0 = cell_it->vertex(0)->point().point(); + const typename Triangulation::Bare_point& p1 = cell_it->vertex(1)->point().point(); + const typename Triangulation::Bare_point& p2 = cell_it->vertex(2)->point().point(); + const typename Triangulation::Bare_point& p3 = cell_it->vertex(3)->point().point(); + double v = std::abs(CGAL::volume(p0, p1, p2, p3)); + double circumradius = CGAL::approximate_sqrt(CGAL::squared_radius(p0, p1, p2, p3)); + + double edges[6]; + edges[0] = std::sqrt(CGAL::squared_distance(p0, p1)); + edges[1] = std::sqrt(CGAL::squared_distance(p0, p2)); + edges[2] = std::sqrt(CGAL::squared_distance(p0, p3)); + edges[3] = std::sqrt(CGAL::squared_distance(p2, p1)); + edges[4] = std::sqrt(CGAL::squared_distance(p2, p3)); + edges[5] = std::sqrt(CGAL::squared_distance(p1, p3)); + + double min_edge = edges[0]; + for(int i=1; i<6; ++i) + { + if(edges[i] volume_quality.biggest_v_sma) + volume_quality.biggest_v_sma = biggest_v_sma_cube; + } + } +} + + +template +void generate_quality_metrics(const C3t3& c3t3) +{ + Surface_quality surface_quality; + Volume_quality volume_quality; + + generate_surface_qualitymetrics(c3t3, surface_quality); + generate_volume_quality_metrics(c3t3, volume_quality); + + CGAL_MESH_3_SET_PERFORMANCE_DATA("Minimum_edge_length", surface_quality.minimum_edge_length); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Mean_edge_length", surface_quality.mean_edge_length); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Maximum_edge_length", surface_quality.maximum_edge_length); + + CGAL_MESH_3_SET_PERFORMANCE_DATA("Minimum_facet_area", surface_quality.minimum_area); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Mean_facet_area", surface_quality.mean_area); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Maximum_facet_area", surface_quality.maximum_area); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Total_area", surface_quality.total_area); + + CGAL_MESH_3_SET_PERFORMANCE_DATA("Minimum_facet_angle", surface_quality.minimum_angle); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Maximum_facet_angle", surface_quality.maximum_angle); + + CGAL_MESH_3_SET_PERFORMANCE_DATA("Minimum_cell_volume", volume_quality.minimum_volume); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Mean_cell_volume", volume_quality.mean_volume); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Maximum_cell_volume", volume_quality.maximum_volume); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Total_volume", volume_quality.total_volume); + + CGAL_MESH_3_SET_PERFORMANCE_DATA("Minimum_dihedral_angle", volume_quality.minimum_dihedral_angle); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Mean_dihedral_angle", volume_quality.mean_dihedral_angle); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Maximum_dihedral_angle", volume_quality.maximum_dihedral_angle); + + CGAL_MESH_3_SET_PERFORMANCE_DATA("Smallest_edge_radius_ratio", volume_quality.smallest_edge_radius_ratio); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Smallest_radius_radius_ratio", volume_quality.smallest_radius_radius_ratio); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Biggest_V_SMA", volume_quality.biggest_v_sma); +} + +#endif // CGAL_MESH_3_BENCHMARK_MESH_3_MESH_QUALITY_H diff --git a/Mesh_3/include/CGAL/Mesh_3/Concurrent_mesher_config.h b/Mesh_3/include/CGAL/Mesh_3/Concurrent_mesher_config.h index 5edea1e565f1..05f18c65ad15 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Concurrent_mesher_config.h +++ b/Mesh_3/include/CGAL/Mesh_3/Concurrent_mesher_config.h @@ -35,7 +35,8 @@ class Concurrent_mesher_config { // Private constructor (singleton) Concurrent_mesher_config() - : locking_grid_num_cells_per_axis(50), + : num_threads(-1), + locking_grid_num_cells_per_axis(50), first_grid_lock_radius(0), work_stats_grid_num_cells_per_axis(5), num_work_items_per_batch(50), @@ -48,14 +49,14 @@ class Concurrent_mesher_config {} public: - static Concurrent_mesher_config &get() + static Concurrent_mesher_config& get() { static Concurrent_mesher_config singleton; return singleton; } static bool load_config_file(const char *filename, - bool reload_if_already_loaded = false) + bool reload_if_already_loaded = false) { return get().load_file(filename, reload_if_already_loaded); } @@ -64,6 +65,7 @@ class Concurrent_mesher_config //=============== PUBLIC PARAMETERS ============== // From config file (or default) + int num_threads; int locking_grid_num_cells_per_axis; int first_grid_lock_radius; int work_stats_grid_num_cells_per_axis; @@ -81,9 +83,8 @@ class Concurrent_mesher_config protected: - bool load_file( - const char *filename, - bool reload_if_already_loaded = false) + bool load_file(const char *filename, + bool reload_if_already_loaded = false) { CGAL_USE(reload_if_already_loaded); #ifdef CGAL_USE_BOOST_PROGRAM_OPTIONS @@ -104,6 +105,7 @@ class Concurrent_mesher_config // Declare the supported options. po::options_description desc("Allowed options"); desc.add_options() + ("num_threads", po::value(), "") ("locking_grid_num_cells_per_axis", po::value(), "") ("first_grid_lock_radius", po::value(), "") ("work_stats_grid_num_cells_per_axis", po::value(), "") @@ -125,6 +127,8 @@ class Concurrent_mesher_config return false; } + num_threads = + get_config_file_option_value("num_threads"); locking_grid_num_cells_per_axis = get_config_file_option_value("locking_grid_num_cells_per_axis"); first_grid_lock_radius = diff --git a/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h b/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h index a76ee2c5ecf1..036094d60b06 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Mesher_3.h @@ -460,7 +460,7 @@ refine_mesh(std::string dump_after_refine_surface_prefix) // If it's parallel but the refinement is forced to sequential, we don't // output the value # ifndef CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT - CGAL_MESH_3_SET_PERFORMANCE_DATA("Facets_time", facet_ref_time); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Facets_refine_time", facet_ref_time); # endif # endif #endif @@ -503,7 +503,7 @@ refine_mesh(std::string dump_after_refine_surface_prefix) // If it's parallel but the refinement is forced to sequential, we don't // output the value # ifndef CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT - CGAL_MESH_3_SET_PERFORMANCE_DATA("Cells_refin_time", cell_ref_time); + CGAL_MESH_3_SET_PERFORMANCE_DATA("Cells_refine_time", cell_ref_time); # endif # endif #endif diff --git a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h index 6c1a43251841..6771a70bb207 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h @@ -1027,8 +1027,17 @@ scan_triangulation_impl() } #ifdef CGAL_MESH_3_PROFILING - std::cerr << "==== Facet scan: " << t.elapsed() << " seconds ====" + double facet_scan_time = t.elapsed(); + std::cerr << "==== Facet scan: " << facet_scan_time << " seconds ====" << std::endl << std::endl; + + # ifdef CGAL_MESH_3_EXPORT_PERFORMANCE_DATA + // If it's parallel but the refinement is forced to sequential, we don't + // output the value + # ifndef CGAL_DEBUG_FORCE_SEQUENTIAL_MESH_REFINEMENT + CGAL_MESH_3_SET_PERFORMANCE_DATA("Facets_scan_time", facet_scan_time); + # endif + # endif #endif #if defined(CGAL_MESH_3_VERBOSE) || defined(CGAL_MESH_3_PROFILING) diff --git a/Mesh_3/include/CGAL/Mesh_3/Sliver_perturber.h b/Mesh_3/include/CGAL/Mesh_3/Sliver_perturber.h index 876d2079ce84..9e0e045350b9 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Sliver_perturber.h +++ b/Mesh_3/include/CGAL/Mesh_3/Sliver_perturber.h @@ -855,16 +855,7 @@ operator()(Visitor visitor) #if defined(CGAL_MESH_3_EXPORT_PERFORMANCE_DATA) \ && defined(CGAL_MESH_3_PROFILING) - if (ret == BOUND_REACHED) - { - CGAL_MESH_3_SET_PERFORMANCE_DATA("Perturber_optim_time", perturbation_time); - } - else - { - CGAL_MESH_3_SET_PERFORMANCE_DATA("Perturber_optim_time", - (ret == CANT_IMPROVE_ANYMORE ? - "CANT_IMPROVE_ANYMORE" : "TIME_LIMIT_REACHED")); - } + CGAL_MESH_3_SET_PERFORMANCE_DATA("Perturber_optim_time", perturbation_time); #endif return ret; diff --git a/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h b/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h index bcf2ff2fea2a..e4f19eaa9564 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h +++ b/Mesh_3/include/CGAL/Mesh_3/Slivers_exuder.h @@ -427,17 +427,9 @@ class Slivers_exuder << exudation_time << "s ====" << std::endl; #endif -#ifdef CGAL_MESH_3_EXPORT_PERFORMANCE_DATA - if (ret == BOUND_REACHED) - { - CGAL_MESH_3_SET_PERFORMANCE_DATA("Exuder_optim_time", exudation_time); - } - else - { - CGAL_MESH_3_SET_PERFORMANCE_DATA("Exuder_optim_time", - (ret == CANT_IMPROVE_ANYMORE ? - "CANT_IMPROVE_ANYMORE" : "TIME_LIMIT_REACHED")); - } +#if defined(CGAL_MESH_3_EXPORT_PERFORMANCE_DATA) \ + && defined(CGAL_MESH_3_PROFILING) + CGAL_MESH_3_SET_PERFORMANCE_DATA("Exuder_optim_time", exudation_time); #endif return ret;