--- /dev/null
+## ---------------------------------------------------------------------
+##
+## Copyright (C) 2017 by the deal.II authors
+##
+## This file is part of the deal.II library.
+##
+## The deal.II library is free software; you can use it, redistribute
+## it, and/or modify it under the terms of the GNU Lesser General
+## Public License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+## The full text of the license can be found in the file LICENSE at
+## the top level of the deal.II distribution.
+##
+## ---------------------------------------------------------------------
+
+#
+# Usage:
+# SETUP_SOURCE_LIST("${_list_of_unity_source_files}"
+# "${_list_of_non_unity_source_files}"
+# _includes_per_unity_file
+# _source_files)
+#
+# This macro sets up the list of source files for the current directory. If
+# DEAL_II_UNITY_BUILD=ON then this script calls SETUP_UNITY_TARGET to do so;
+# otherwise, if DEAL_II_UNITY_BUILD=OFF, then all source files are added to the
+# variable _source_files.
+#
+MACRO(SETUP_SOURCE_LIST _unity_include_src _separate_src _n_includes_per_unity_file _output_src)
+ IF(DEAL_II_UNITY_BUILD)
+ SETUP_UNITY_TARGET("${_unity_include_src}" ${_n_includes_per_unity_file} ${_output_src})
+ SET(${_output_src}
+ ${${_output_src}}
+ ${_separate_src}
+ )
+ ELSE()
+ SET(${_output_src}
+ ${${_output_src}}
+ ${_unity_include_src}
+ ${_separate_src}
+ )
+ ENDIF()
+ENDMACRO()
--- /dev/null
+## ---------------------------------------------------------------------
+##
+## Copyright (C) 2017 by the deal.II authors
+##
+## This file is part of the deal.II library.
+##
+## The deal.II library is free software; you can use it, redistribute
+## it, and/or modify it under the terms of the GNU Lesser General
+## Public License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+## The full text of the license can be found in the file LICENSE at
+## the top level of the deal.II distribution.
+##
+## ---------------------------------------------------------------------
+
+#
+# Usage:
+# SETUP_UNITY_TARGET("${_list_of_unity_source_files}" _includes_per_unity_file _output_src)
+#
+# This macro sets up some number of unity build targets given a list of files
+# and the number of files to be included per unity file. It generates the unity
+# build files and appends their names to _output_src.
+#
+MACRO(SETUP_UNITY_TARGET _unity_include_src _n_includes_per_unity_file _output_src)
+ #
+ # The unity build files need access to the original source files:
+ #
+ INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_SOURCE_DIR})
+
+ SET(_file_index 0)
+ FOREACH(_unity_file ${_unity_include_src})
+ MATH(EXPR _unity_prefix_index "${_file_index} / ${_n_includes_per_unity_file}")
+ #
+ # Get around the fact that CMake does not support nested lists by generating
+ # a file name and then storing that file name in a list (which we will
+ # uniquify later)
+ #
+ SET(_unity_prefix "unity_${_unity_prefix_index}")
+ LIST(APPEND _unity_prefixes ${_unity_prefix})
+ LIST(APPEND ${_unity_prefix} ${_unity_file})
+
+ MATH(EXPR _file_index "${_file_index} + 1")
+ ENDFOREACH()
+
+ LIST(REMOVE_DUPLICATES _unity_prefixes)
+
+ FOREACH(_unity_prefix ${_unity_prefixes})
+ SET(_unity_file_name "${CMAKE_CURRENT_BINARY_DIR}/${_unity_prefix}.cc")
+ #
+ # Note the CMake weirdness: _output_src is actually a string containing the
+ # variable name since we are in a macro...
+ #
+ SET(${_output_src}
+ ${${_output_src}}
+ ${_unity_file_name}
+ )
+ FILE(WRITE "${_unity_file_name}"
+"// This file was automatically generated by the deal.II CMake configuration as
+// part of the unity build subsystem. Please do not edit this file directly;
+// instead, make appropriate changes to the relevant CMakeLists.txt file.\n\n"
+ )
+ FOREACH(_unity_file ${${_unity_prefix}})
+ FILE(APPEND "${_unity_file_name}" "#include \"${_unity_file}\"\n")
+ ENDFOREACH()
+ ENDFOREACH()
+ENDMACRO()
# DEAL_II_ALLOW_PLATFORM_INTROSPECTION
# DEAL_II_SETUP_DEFAULT_COMPILER_FLAGS
# DEAL_II_SETUP_COVERAGE
+# DEAL_II_UNITY_BUILD
# BUILD_SHARED_LIBS
# DEAL_II_PREFER_STATIC_LIBS
# DEAL_II_STATIC_EXECUTABLE
)
MARK_AS_ADVANCED(DEAL_II_SETUP_COVERAGE)
+OPTION(DEAL_II_UNITY_BUILD
+ "Compile the library by concatenating together source files to form a few large targets instead of many small ones. This lowers total compilation wall time by about 25%."
+ OFF)
+MARK_AS_ADVANCED(DEAL_II_UNITY_BUILD)
+
SET(BUILD_SHARED_LIBS "ON" CACHE BOOL
"Build a shared library"
)
<li><a href="#findmodules"><code>./cmake/modules/Find*.cmake</code></a></li>
<li><a href="#configure"><code>./cmake/configure/configure_*.cmake</code></a></li>
<li><a href="#variables">Global variables controlling the build process</a></li>
+ <li><a href="#unity-build">The unity build subsystem</a></li>
</ol>
</li>
<li>Target definition and installation
</ul>
</p>
+<a name="unity-build"></a>
+<h3>The unity build subsystem</h3>
+<p>
+ For a general description of this feature see
+ the <a href="../readme.html#optional-compilation">deal.II Readme
+ entry</a>. Many of the various <code>CMakeLists.txt</code> files split their
+ source files into two lists: one list of files that are relatively cheap to
+ compile, which are concatenated into the unity build files, and a list of
+ files that are more expensive to compile, which are not included in the unity
+ files. For example: most of the finite element classes take about 5-10 seconds
+ to compile while the <code>FEValues</code> instantiation files each take about
+ 60 seconds. In addition, many <code>CMakeLists.txt</code> files define a
+ variable <code>_n_includes_per_unity_file</code> which specifies how many
+ files should be concatenated into each unity file.
+</p>
+
+<p>
+ A disadvantage to this approach is that it requires profiling the build in two
+ places: the time and memory usage of all source files must be measured and the
+ variable <code>_n_includes_per_unity_file</code> should be set so that the
+ unity build files are not overly expensive in terms of memory and wall
+ time. The current values were chosen so that the unity files, with GCC,
+ require about 30 to 60 seconds of wall time and about 2 GB of memory.
+</p>
<h2>Target definition and installation</h2>
<a name="config.h.in"></a>
--- /dev/null
+New: The cmake configuration now supports unity builds with the option <code>-DDEAL_II_UNITY_BUILD=ON</code>. This option speeds up the build by about 10 to 25%.
+<br> (David Wells, 2017/07/20)
<li> <a href="#documentation">Configuring and building the documentation</a></li>
<li> <a href="#configuration-options">Configuration options</a>
<ol>
- <li> <a href="#optional">Selecting optional behavior</a></li>
+ <li> <a href="#optional-compilation">Selecting optional compilation features</a></li>
+ <li> <a href="#optional">Selecting optional library features</a></li>
<li> <a href="#optional-software">Optional interfaces to
other software packages</a></li>
<li> <a href="#conf-details">More information on configuring
<pre>
cmake -DDEAL_II_COMPONENT_DOCUMENTATION=ON -DCMAKE_INSTALL_PREFIX=/path/install/dir ../deal.II
</pre>
-
+
<p>
For this to succeed, you will need <a href="http://www.perl.org/"
target="_top">Perl 5.x</a>,
the <a href="http://www.graphviz.org" target="_top">GraphViz</a>
package) to be installed.
</p>
-
+
<p>
The documentation contains links to pictures (e.g., for the
tutorial programs) that are by default stored online at the
the <code>contrib/utilities/makeofflinedoc.sh</code> script in
an installed documentation directory to download all images.
</p>
-
+
<p> Finally, the default for locally installed documentation is to
render formulas as images. You can force formulas to be
displayed via the MathJax system by
options.
</p>
+ <a name="optional-compilation"/>
+ <h4>Selecting optional compilation features</h4>
+ <ul>
+ <p>
+ <li> <i>Unity build</i>: deal.II may be compiled with a unity build;
+ that is, one may configure the build process so that the library is
+ compiled as a few large files instead of many small ones. The unity
+ build feature may be enabled by passing
+ the <code>-DDEAL_II_UNITY_BUILD=ON</code> argument
+ to <code>cmake</code>. This feature is disabled by default.
+ </p>
+ </ul>
+
<a name="optional"/>
- <h4>Selecting optional behavior</h4>
+ <h4>Selecting optional library features</h4>
<ul>
<li>
<dd>
<p>
The <a href="http://www.gnu.org/software/gsl/">GNU Scientific Library</a>
- provides a wide range of mathematical routines such as random number
+ provides a wide range of mathematical routines such as random number
generators, special functions and least-squares fitting.
<a href="http://www.gnu.org/software/gsl/">GSL</a> should be
readily packaged by most Linux distributions. (Don't forget
from the official website, as well as with the OpenCASCADE
Community Edition (OCE, available at
<a href="https://github.com/tpaviot/oce">https://github.com/tpaviot/oce</a>),
- which offers a cmake
+ which offers a cmake
interface for its compilation. Alternatively, you can
install one of the many external applications that ship with
- OpenCASCADE internally (for example
- <a href="http://www.salome-platform.org/">SALOME</a>, or
+ OpenCASCADE internally (for example
+ <a href="http://www.salome-platform.org/">SALOME</a>, or
<a href="http://www.freecadweb.org/">FreeCAD</a>). Further
installation instructions can be
found <a href="external-libs/opencascade.html"
greater control over what exactly is configured or built than just the
outline above. If you want to learn more about this, take a look
<a href="users/cmake.html">here</a>. You might also be interested in
- <a href="users/cmakelists.html">CMake for user projects</a> or
+ <a href="users/cmakelists.html">CMake for user projects</a> or
<a href="developers/cmake-internals.html">build system internals</a>.
</p>
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
-SET(_src
+#
+# All source/base files are sufficiently small that they may be added to the
+# unity build file (see the developer documentation on DEAL_II_UNITY_BUILD
+# for more information).
+#
+SET(_unity_include_src
auto_derivative_function.cc
conditional_ostream.cc
config.cc
utilities.cc
)
+SET(_separate_src
+ )
+
+# determined by profiling
+SET(_n_includes_per_unity_file 29)
+
+SETUP_SOURCE_LIST("${_unity_include_src}"
+ "${_separate_src}"
+ ${_n_includes_per_unity_file}
+ _src
+ )
+
SET(_inst
data_out_base.inst.in
function.inst.in
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
-SET(_src
+SET(_unity_include_src
grid_refinement.cc
solution_transfer.cc
tria.cc
p4est_wrappers.cc
)
+SET(_separate_src
+ )
+
+# concatenate all unity inclusion files in one file
+SET(_n_includes_per_unity_file 15)
+
+SETUP_SOURCE_LIST("${_unity_include_src}"
+ "${_separate_src}"
+ ${_n_includes_per_unity_file}
+ _src
+ )
+
SET(_inst
grid_refinement.inst.in
solution_transfer.inst.in
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
-SET(_src
+SET(_unity_include_src
block_info.cc
+ dof_faces.cc
+ dof_handler.cc
+ dof_objects.cc
+ number_cache.cc
+ )
+
+SET(_separate_src
dof_accessor.cc
dof_accessor_get.cc
dof_accessor_set.cc
- dof_faces.cc
- dof_handler.cc
dof_handler_policy.cc
- dof_objects.cc
dof_renumbering.cc
dof_tools.cc
dof_tools_constraints.cc
dof_tools_sparsity.cc
- number_cache.cc
+ )
+
+# concatenate all unity inclusion files in one file
+SET(_n_includes_per_unity_file 15)
+
+SETUP_SOURCE_LIST("${_unity_include_src}"
+ "${_separate_src}"
+ ${_n_includes_per_unity_file}
+ _src
)
SET(_inst
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
-SET(_src
+SET(_unity_include_src
block_mask.cc
component_mask.cc
fe_abf.cc
fe_system.cc
fe_enriched.cc
fe_tools.cc
- fe_tools_interpolate.cc
- fe_tools_extrapolate.cc
fe_trace.cc
- fe_values.cc
- fe_values_inst2.cc
mapping_c1.cc
mapping_cartesian.cc
mapping.cc
- mapping_fe_field.cc
- mapping_fe_field_inst2.cc
mapping_q_generic.cc
mapping_q1.cc
mapping_q1_eulerian.cc
mapping_manifold.cc
)
+SET(_separate_src
+ fe_values.cc
+ fe_values_inst2.cc
+ mapping_fe_field.cc
+ mapping_fe_field_inst2.cc
+ fe_tools_interpolate.cc
+ fe_tools_extrapolate.cc
+ )
+
+# determined by profiling
+SET(_n_includes_per_unity_file 15)
+
+SETUP_SOURCE_LIST("${_unity_include_src}"
+ "${_separate_src}"
+ ${_n_includes_per_unity_file}
+ _src
+ )
+
SET(_inst
fe_abf.inst.in
fe_bdm.inst.in
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
-SET(_src
+SET(_unity_include_src
cell_id.cc
grid_generator.cc
grid_in.cc
grid_out.cc
grid_refinement.cc
grid_reordering.cc
- grid_tools.cc
intergrid_map.cc
manifold.cc
manifold_lib.cc
tria_accessor.cc
tria_boundary.cc
tria_boundary_lib.cc
- tria.cc
tria_faces.cc
tria_levels.cc
tria_objects.cc
)
+SET(_separate_src
+ grid_tools.cc
+ tria.cc
+ )
+
+# include all files in the unity file
+SET(_n_includes_per_unity_file 20)
+
+SETUP_SOURCE_LIST("${_unity_include_src}"
+ "${_separate_src}"
+ ${_n_includes_per_unity_file}
+ _src
+ )
+
SET(_inst
cell_id.inst.in
grid_generator.inst.in
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
-SET(_src
+SET(_unity_include_src
dof_faces.cc
- dof_handler.cc
dof_level.cc
fe_collection.cc
fe_values.cc
mapping_collection.cc
)
+SET(_separate_src
+ dof_handler.cc
+ )
+
+# concatenate all unity inclusion files in one file
+SET(_n_includes_per_unity_file 15)
+
+SETUP_SOURCE_LIST("${_unity_include_src}"
+ "${_separate_src}"
+ ${_n_includes_per_unity_file}
+ _src
+ )
+
SET(_inst
dof_handler.inst.in
fe_collection.inst.in
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
-SET(_src
+SET(_unity_include_src
block_matrix_array.cc
block_sparse_matrix.cc
block_sparse_matrix_ez.cc
sparse_decomposition.cc
sparse_direct.cc
sparse_ilu.cc
- sparse_matrix.cc
- sparse_matrix_inst2.cc
sparse_matrix_ez.cc
sparse_mic.cc
sparse_vanka.cc
vector_view.cc
)
+SET(_separate_src
+ sparse_matrix.cc
+ sparse_matrix_inst2.cc
+ )
+
SET(_inst
block_sparse_matrix.inst.in
block_vector.inst.in
vector_view.inst.in
)
+
# Add PETSc wrapper files. If PETSc has not been found,
# then these files should be empty and there is no need
# to even look at them
IF(DEAL_II_WITH_PETSC)
- SET(_src
- ${_src}
+ SET(_unity_include_src
+ ${_unity_include_src}
petsc_full_matrix.cc
petsc_matrix_base.cc
petsc_matrix_free.cc
# Same for SLEPc
IF(DEAL_II_WITH_SLEPC)
- SET(_src
- ${_src}
+ SET(_unity_include_src
+ ${_unity_include_src}
slepc_solver.cc
slepc_spectral_transformation.cc
)
# Also add Trilinos wrapper files
IF(DEAL_II_WITH_TRILINOS)
- SET(_src
- ${_src}
+ SET(_unity_include_src
+ ${_unity_include_src}
trilinos_block_sparse_matrix.cc
trilinos_block_vector.cc
trilinos_epetra_communication_pattern.cc
trilinos_epetra_vector.cc
trilinos_precondition.cc
trilinos_precondition_ml.cc
- trilinos_precondition_muelu.cc
trilinos_solver.cc
trilinos_sparse_matrix.cc
trilinos_sparsity_pattern.cc
trilinos_vector.cc
)
+
+ SET(_separate_src
+ ${_separate_src}
+ trilinos_precondition_muelu.cc
+ )
+
SET(_inst
${_inst}
trilinos_sparse_matrix.inst.in
# Add CUDA wrapper files
IF(DEAL_II_WITH_CUDA)
- SET(_src
- ${_src}
+ SET(_separate_src
+ ${_separate_src}
cuda_vector.cu
)
ENDIF()
+# determined by profiling
+SET(_n_includes_per_unity_file 30)
+IF(DEAL_II_UNITY_BUILD)
+ # sort files so that the petsc and trilinos files are not together
+ LIST(SORT _unity_include_src)
+ENDIF()
+
+SETUP_SOURCE_LIST("${_unity_include_src}"
+ "${_separate_src}"
+ ${_n_includes_per_unity_file}
+ _src
+ )
FILE(GLOB _header
${CMAKE_SOURCE_DIR}/include/deal.II/lac/*.h
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
-SET(_src
+SET(_unity_include_src
mg_base.cc
mg_level_global_transfer.cc
- mg_tools.cc
mg_transfer_block.cc
mg_transfer_component.cc
mg_transfer_internal.cc
- mg_transfer_matrix_free.cc
mg_transfer_prebuilt.cc
multigrid.cc
)
+SET(_separate_src
+ mg_tools.cc
+ mg_transfer_matrix_free.cc
+ )
+
+# concatenate all unity inclusion files in one file
+SET(_n_includes_per_unity_file 15)
+
+SETUP_SOURCE_LIST("${_unity_include_src}"
+ "${_separate_src}"
+ ${_n_includes_per_unity_file}
+ _src
+ )
+
SET(_inst
mg_base.inst.in
mg_level_global_transfer.inst.in
INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
-SET(_src
+SET(_unity_include_src
data_out.cc
- data_out_dof_data.cc
- data_out_dof_data_codim.cc
data_out_faces.cc
- data_out_rotation.cc
data_out_stack.cc
+ data_out_rotation.cc
data_postprocessor.cc
- derivative_approximation.cc
dof_output_operator.cc
+ histogram.cc
+ matrix_tools_once.cc
+ matrix_tools.cc
+ time_dependent.cc
+ vector_tools_boundary.cc
+ vector_tools_constraints.cc
+ vector_tools_mean_value.cc
+ vector_tools_point_gradient.cc
+ vector_tools_rhs.cc
+ )
+
+SET(_separate_src
+ data_out_dof_data.cc
+ data_out_dof_data_codim.cc
+ derivative_approximation.cc
error_estimator_1d.cc
error_estimator.cc
error_estimator_inst2.cc
fe_field_function.cc
- histogram.cc
matrix_creator.cc
matrix_creator_inst2.cc
matrix_creator_inst3.cc
- matrix_tools_once.cc
- matrix_tools.cc
point_value_history.cc
solution_transfer.cc
solution_transfer_inst2.cc
solution_transfer_inst3.cc
solution_transfer_inst4.cc
- time_dependent.cc
- vector_tools_boundary.cc
- vector_tools_constraints.cc
vector_tools_integrate_difference.cc
vector_tools_interpolate.cc
- vector_tools_mean_value.cc
vector_tools_point_value.cc
- vector_tools_point_gradient.cc
vector_tools_project.cc
vector_tools_project_inst2.cc
vector_tools_project_inst3.cc
vector_tools_project_codim.cc
vector_tools_project_qp.cc
vector_tools_project_qpmf.cc
- vector_tools_rhs.cc
+ )
+
+# determined by profiling
+SET(_n_includes_per_unity_file 8)
+
+SETUP_SOURCE_LIST("${_unity_include_src}"
+ "${_separate_src}"
+ ${_n_includes_per_unity_file}
+ _src
)
SET(_inst