Add generalized instantiation
Recently, an instantiation method was added to the VTK-m configuration files to set up a set of source files that compile instances of a template. This allows the template instances to be compiled exactly once in separate build files. However, the implementation made the assumption that the instantiations were happening for VTK-m filters. Now that the VTK-m filters are being redesigned, this assumption is broken. Thus, the instantiation code has been redesigned to be more general. It can now be applied to code within the new filter structure. It can also be applied anywhere else in the VTK-m source code.
This commit is contained in:
parent
626c806772
commit
6eb9c9876c
9
CMake/InstantiationTemplate.cxx.in
Normal file
9
CMake/InstantiationTemplate.cxx.in
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef @INSTANTIATION_INC_GUARD@
|
||||
#define @INSTANTIATION_INC_GUARD@
|
||||
#endif
|
||||
|
||||
#include <@INSTANTIATION_TEMPLATE_SOURCE@>
|
||||
|
||||
@INSTANTIATION_DECLARATION@
|
||||
|
||||
#undef @INSTANTIATION_INC_GUARD@
|
@ -547,78 +547,98 @@ function(vtkm_library)
|
||||
|
||||
endfunction(vtkm_library)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Produce _instantiation-files_ given a filter.
|
||||
#
|
||||
# This function will parse the header file of a given filter and for each of
|
||||
# the extern template found on it, it will produce its corresponding
|
||||
# _instantiation-files_. Those produced `instantiation-files` are stored in
|
||||
# the build directory and are not versioned.
|
||||
#
|
||||
# Usage:
|
||||
# vtkm_add_instantiations(
|
||||
# instantiations_list
|
||||
# FILTER <name>
|
||||
# [ INSTANTIATIONS_FILE <path> ]
|
||||
# )
|
||||
#
|
||||
# instantiations_list: Output variable which contain the path of the newly
|
||||
# produced _instantiation-files_.
|
||||
#
|
||||
# FILTER: The name of the filter of which we wish to produce those
|
||||
# instantiations from.
|
||||
#
|
||||
# INSTANTIATIONS_FILE: _Optional_ parameter with the relative path of the file
|
||||
# which contains the extern template instantiations. When omitted,
|
||||
# `vtkm_add_instantiations` will default to `${FILTER}.h`.
|
||||
#
|
||||
#[==[
|
||||
-----------------------------------------------------------------------------
|
||||
Produce _instantiation-files_ given a filter.
|
||||
|
||||
VTK-m makes use of a lot of headers. It is often the case when building a
|
||||
library that you have to compile several instantiations of the template to
|
||||
cover all the types expected. However, when you try to do this in a single
|
||||
cxx file, you can end up with some very long compiles, especially when
|
||||
using a GPU device compiler. In this case, it is helpful to split up the
|
||||
instantiations across multiple files.
|
||||
|
||||
This function will parse a given header file and look for pairs of
|
||||
`VTKM_INSTANTIATION_BEGIN` and `VTKM_INSTANTIATION_END`. (These are defined
|
||||
in `vtkm/internal/Instantiations.h`.) Between these two macros there should
|
||||
be the definition of a single extern template instantiation. The definition
|
||||
needs to fully qualify the namespace of all symbols. The declaration
|
||||
typically looks something like this.
|
||||
|
||||
```cpp
|
||||
VTKM_INSTANTIATION_BEGIN
|
||||
extern template vtkm::cont::ArrayHandle<vtkm::Float32> vtkm::filter::foo::RunFooWorklet(
|
||||
const vtkm::cont::CellSetExplicit<>& inCells,
|
||||
const vtkm::cont::ArrayHandle<vtkm::Vec3f_32>& inField);
|
||||
VTKM_INSTANTIATION_END
|
||||
```
|
||||
|
||||
For each one of these found, a source file will be produced that compiles
|
||||
the template for the given instantiation. Those produced files are stored
|
||||
in the build directory and are not versioned.
|
||||
|
||||
Usage:
|
||||
vtkm_add_instantiations(
|
||||
instantiations_list
|
||||
INSTANTIATIONS_FILE <path>
|
||||
[ TEMPLATE_SOURCE <path> ]
|
||||
)
|
||||
|
||||
instantiations_list: Output variable which contain the path of the newly
|
||||
produced _instantiation-files_.
|
||||
|
||||
INSTANTIATIONS_FILE: Parameter with the relative path of the file that
|
||||
contains the extern template instantiations.
|
||||
|
||||
TEMPLATE_SOURCE: _Optional_ parameter with the relative path to the header
|
||||
file that contains the implementation of the template. If not given, the
|
||||
template source is set to be the same as the INSTANTIATIONS_FILE.
|
||||
#]==]
|
||||
function(vtkm_add_instantiations instantiations_list)
|
||||
# Parse and validate parameters
|
||||
set(oneValueArgs FILTER INSTANTIATIONS_FILE)
|
||||
set(oneValueArgs INSTANTIATIONS_FILE TEMPLATE_SOURCE)
|
||||
cmake_parse_arguments(VTKm_instantiations "" "${oneValueArgs}" "" ${ARGN})
|
||||
|
||||
if(NOT VTKm_instantiations_FILTER)
|
||||
message(FATAL_ERROR "vtkm_add_instantiations needs a valid FILTER parameter")
|
||||
if(NOT VTKm_instantiations_INSTANTIATIONS_FILE)
|
||||
message(FATAL_ERROR "vtkm_add_instantiations needs a valid INSTANTIATIONS_FILE parameter")
|
||||
endif()
|
||||
|
||||
set(filter ${VTKm_instantiations_FILTER})
|
||||
set(file_header "${filter}.h")
|
||||
set(instantiations_file ${VTKm_instantiations_INSTANTIATIONS_FILE})
|
||||
|
||||
set(file_template_source "${filter}.h")
|
||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${filter}.hxx")
|
||||
set(file_template_source "${filter}.hxx")
|
||||
if(VTKm_instantiations_TEMPLATE_SOURCE)
|
||||
set(file_template_source ${VTKm_instantiations_TEMPLATE_SOURCE})
|
||||
else()
|
||||
set(file_template_source ${instantiations_file})
|
||||
endif()
|
||||
|
||||
# Extract explicit instantiations
|
||||
set(instantiations_file ${file_header})
|
||||
if(VTKm_instantiations_INSTANTIATIONS_FILE)
|
||||
set(instantiations_file ${VTKm_instantiations_INSTANTIATIONS_FILE})
|
||||
endif()
|
||||
_vtkm_extract_instantiations(instantiations ${instantiations_file})
|
||||
|
||||
# Compute relative path of header files
|
||||
file(RELATIVE_PATH INSTANTIATION_FILTER_HEADER
|
||||
${VTKm_SOURCE_DIR}
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${file_header}"
|
||||
)
|
||||
|
||||
file(RELATIVE_PATH INSTANTIATION_FILTER_TEMPLATE_SOURCE
|
||||
file(RELATIVE_PATH INSTANTIATION_TEMPLATE_SOURCE
|
||||
${VTKm_SOURCE_DIR}
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${file_template_source}"
|
||||
)
|
||||
|
||||
# Make a guard macro name so that the TEMPLATE_SOURCE can determine if it is compiling
|
||||
# the instances (if necessary).
|
||||
get_filename_component(instantations_name "${instantiations_file}" NAME_WE)
|
||||
set(INSTANTIATION_INC_GUARD "vtkm_${instantations_name}Instantiation")
|
||||
|
||||
# Generate instatiation file in the build directory
|
||||
set(counter 0)
|
||||
foreach(instantiation IN LISTS instantiations)
|
||||
string(REPLACE "$" ";" instantiation ${instantiation})
|
||||
set(INSTANTIATION_FILTER_METHOD "${instantiation}")
|
||||
set(INSTANTIATION_FILTER_INC_GUARD "vtkm_filter_${filter}Instantiation${counter}_cxx")
|
||||
set(INSTANTIATION_DECLARATION "${instantiation}")
|
||||
|
||||
# Create instantiation in build directory
|
||||
set(instantiation_path "${CMAKE_CURRENT_BINARY_DIR}/${filter}Instantiation${counter}.cxx")
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/InstantiationTemplate.cxx.in"
|
||||
set(instantiation_path
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/${instantations_name}Instantiation${counter}.cxx"
|
||||
)
|
||||
configure_file("${VTKm_SOURCE_DIR}/CMake/InstantiationTemplate.cxx.in"
|
||||
${instantiation_path}
|
||||
@ONLY)
|
||||
@ONLY
|
||||
)
|
||||
|
||||
# Return value
|
||||
list(APPEND _instantiations_list ${instantiation_path})
|
||||
|
14
docs/changelog/general-instantiations.md
Normal file
14
docs/changelog/general-instantiations.md
Normal file
@ -0,0 +1,14 @@
|
||||
# Generalized instantiation
|
||||
|
||||
Recently, an instantiation method was added to the VTK-m configuration
|
||||
files to set up a set of source files that compile instances of a template.
|
||||
This allows the template instances to be compiled exactly once in separate
|
||||
build files.
|
||||
|
||||
However, the implementation made the assumption that the instantiations
|
||||
were happening for VTK-m filters. Now that the VTK-m filters are being
|
||||
redesigned, this assumption is broken.
|
||||
|
||||
Thus, the instantiation code has been redesigned to be more general. It can
|
||||
now be applied to code within the new filter structure. It can also be
|
||||
applied anywhere else in the VTK-m source code.
|
@ -34,6 +34,7 @@ set(deprecated_headers
|
||||
ImageConnectivity.h
|
||||
ImageDifference.h
|
||||
ImageMedian.h
|
||||
Instantiations.h
|
||||
Mask.h
|
||||
MaskPoints.h
|
||||
MeshQuality.h
|
||||
@ -79,7 +80,6 @@ set(common_headers
|
||||
FilterTraits.h
|
||||
PolicyBase.h
|
||||
PolicyDefault.h
|
||||
Instantiations.h
|
||||
)
|
||||
|
||||
vtkm_declare_headers(${common_headers})
|
||||
|
@ -1,21 +0,0 @@
|
||||
#ifndef @INSTANTIATION_FILTER_INC_GUARD@
|
||||
#define @INSTANTIATION_FILTER_INC_GUARD@
|
||||
#endif
|
||||
|
||||
/* Needed for linking errors when no instantiations */
|
||||
int __@INSTANTIATION_FILTER_INC_GUARD@;
|
||||
|
||||
#include <@INSTANTIATION_FILTER_HEADER@>
|
||||
#include <@INSTANTIATION_FILTER_TEMPLATE_SOURCE@>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace filter
|
||||
{
|
||||
|
||||
@INSTANTIATION_FILTER_METHOD@
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#undef @INSTANTIATION_FILTER_INC_GUARD@
|
@ -8,43 +8,26 @@
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
|
||||
#ifndef vtk_m_Instantiations_h
|
||||
#define vtk_m_Instantiations_h
|
||||
//
|
||||
// The following empty macros are instantiation delimiters used by
|
||||
// vtk_add_instantiations at CMake/VTKmWrappers.cmake to generate transient
|
||||
// instantiation files at the build directory.
|
||||
//
|
||||
// # Example #
|
||||
//
|
||||
// ## Contour.h ##
|
||||
//
|
||||
// VTKM_INSTANTIATION_BEGIN
|
||||
// extern template vtkm::cont::DataSet Contour::DoExecute(
|
||||
// const vtkm::cont::DataSet&,
|
||||
// const vtkm::cont::ArrayHandle<vtkm::UInt8>&,
|
||||
// const vtkm::filter::FieldMetadata&,
|
||||
// vtkm::filter::PolicyBase<vtkm::filter::PolicyDefault>);
|
||||
// VTKM_INSTANTIATION_END
|
||||
//
|
||||
// ## ContourInstantiationsN.cxx ##
|
||||
//
|
||||
// template vtkm::cont::DataSet Contour::DoExecute(
|
||||
// const vtkm::cont::DataSet&,
|
||||
// const vtkm::cont::ArrayHandle<vtkm::UInt8>&,
|
||||
// const vtkm::filter::FieldMetadata&,
|
||||
// vtkm::filter::PolicyBase<vtkm::filter::PolicyDefault>);
|
||||
//
|
||||
// # KNOWN ISSUES #
|
||||
//
|
||||
// Abstain to use the following constructors in the code section between
|
||||
// the VTKM_INSTANTIATION_BEGIN/END directives:
|
||||
//
|
||||
// - The word extern other than for extern template.
|
||||
// - The word _TEMPLATE_EXPORT other then for the EXPORT macro.
|
||||
// - Comments that use the '$' symbol.
|
||||
//
|
||||
#define VTKM_INSTANTIATION_BEGIN
|
||||
#define VTKM_INSTANTIATION_END
|
||||
#ifndef vtk_m_filter_Instantiations_h
|
||||
#define vtk_m_filter_Instantiations_h
|
||||
|
||||
#endif
|
||||
#include <vtkm/Deprecated.h>
|
||||
#include <vtkm/internal/Instantiations.h>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace filter
|
||||
{
|
||||
|
||||
VTKM_DEPRECATED(1.8, "Use vtkm/internal/Instantiations.h instead of vtkm/filter/Instantiations.h")
|
||||
inline void Instantiations_deprecated() {}
|
||||
|
||||
inline void Instantiations_deprecated_warning()
|
||||
{
|
||||
Instantiations_deprecated();
|
||||
}
|
||||
|
||||
} // namespace vtkm
|
||||
} // namespace filter
|
||||
|
||||
#endif //vtk_m_filter_Instantiations_h
|
||||
|
@ -66,6 +66,7 @@ set(headers
|
||||
FunctionInterfaceDetailPre.h
|
||||
IndexTag.h
|
||||
IndicesExtrude.h
|
||||
Instantiations.h
|
||||
Invocation.h
|
||||
Meta.h
|
||||
Unreachable.h
|
||||
|
50
vtkm/internal/Instantiations.h
Normal file
50
vtkm/internal/Instantiations.h
Normal file
@ -0,0 +1,50 @@
|
||||
//============================================================================
|
||||
// Copyright (c) Kitware, Inc.
|
||||
// All rights reserved.
|
||||
// See LICENSE.txt for details.
|
||||
//
|
||||
// This software is distributed WITHOUT ANY WARRANTY; without even
|
||||
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
// PURPOSE. See the above copyright notice for more information.
|
||||
//============================================================================
|
||||
|
||||
#ifndef vtk_m_internal_Instantiations_h
|
||||
#define vtk_m_internal_Instantiations_h
|
||||
//
|
||||
// The following empty macros are instantiation delimiters used by
|
||||
// vtk_add_instantiations at CMake/VTKmWrappers.cmake to generate transient
|
||||
// instantiation files at the build directory.
|
||||
//
|
||||
// # Example #
|
||||
//
|
||||
// ## Contour.h ##
|
||||
//
|
||||
// VTKM_INSTANTIATION_BEGIN
|
||||
// extern template vtkm::cont::DataSet Contour::DoExecute(
|
||||
// const vtkm::cont::DataSet&,
|
||||
// const vtkm::cont::ArrayHandle<vtkm::UInt8>&,
|
||||
// const vtkm::filter::FieldMetadata&,
|
||||
// vtkm::filter::PolicyBase<vtkm::filter::PolicyDefault>);
|
||||
// VTKM_INSTANTIATION_END
|
||||
//
|
||||
// ## ContourInstantiationsN.cxx ##
|
||||
//
|
||||
// template vtkm::cont::DataSet Contour::DoExecute(
|
||||
// const vtkm::cont::DataSet&,
|
||||
// const vtkm::cont::ArrayHandle<vtkm::UInt8>&,
|
||||
// const vtkm::filter::FieldMetadata&,
|
||||
// vtkm::filter::PolicyBase<vtkm::filter::PolicyDefault>);
|
||||
//
|
||||
// # KNOWN ISSUES #
|
||||
//
|
||||
// Abstain to use the following constructors in the code section between
|
||||
// the VTKM_INSTANTIATION_BEGIN/END directives:
|
||||
//
|
||||
// - The word extern other than for extern template.
|
||||
// - The word _TEMPLATE_EXPORT other then for the EXPORT macro.
|
||||
// - Comments that use the '$' symbol.
|
||||
//
|
||||
#define VTKM_INSTANTIATION_BEGIN
|
||||
#define VTKM_INSTANTIATION_END
|
||||
|
||||
#endif //vtk_m_internal_Instantiations_h
|
Loading…
Reference in New Issue
Block a user