Merge topic 'vtkm_add_target_information_support_multiple_targets'

e37c2061c vtkm_add_target_information now supports multiple targets

Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !1838
This commit is contained in:
Robert Maynard 2019-09-11 17:33:07 +00:00 committed by Kitware Robot
commit d7ecf2241a
5 changed files with 116 additions and 50 deletions

@ -139,12 +139,13 @@ endfunction()
#-----------------------------------------------------------------------------
# Add a relevant information to target that wants to use VTK-m.
#
# This is a higher order function to allow build-systems that use VTK-m
# to compose add_library/add_executable and the required information to have
# VTK-m enabled.
# This higher order function allow build-systems that use VTK-m
# to use `add_library` or `add_executable` calls but still have an
# easy to way to get the required information to have VTK-m using
# compilation units compile correctly.
#
# vtkm_add_target_information(
# target
# target[s]
# [ MODIFY_CUDA_FLAGS ]
# [ EXTENDS_VTKM ]
# [ DEVICE_SOURCES <source_list>
@ -159,10 +160,14 @@ endfunction()
# target_link_libraries(lib_that_uses_vtkm PRIVATE vtkm_filter)
#
# MODIFY_CUDA_FLAGS: If enabled will add the required -arch=<ver> flags
# that VTK-m was compiled with. This functionality is also provided by the
# the standalone `vtkm_get_cuda_flags` function.
# that VTK-m was compiled with. If you have multiple libraries that use
# VTK-m calling `vtkm_add_target_information` multiple times with
# `MODIFY_CUDA_FLAGS` will cause duplicate compiler flags. To resolve this issue
# you can; pass all targets and sources to a single `vtkm_add_target_information`
# call, have the first one use `MODIFY_CUDA_FLAGS`, or use the provided
# standalone `vtkm_get_cuda_flags` function.
#
# DEVICE_SOURCES: The collection of source files that are used by `target` that
# DEVICE_SOURCES: The collection of source files that are used by `target(s)` that
# need to be marked as going to a special compiler for certain device adapters
# such as CUDA.
#
@ -198,6 +203,23 @@ function(vtkm_add_target_information uses_vtkm_target)
${ARGN}
)
if(VTKm_TI_MODIFY_CUDA_FLAGS)
vtkm_get_cuda_flags(CMAKE_CUDA_FLAGS)
set(CMAKE_CUDA_FLAGS ${CMAKE_CUDA_FLAGS} PARENT_SCOPE)
endif()
set(targets ${uses_vtkm_target})
foreach(item IN LISTS VTKm_TI_UNPARSED_ARGUMENTS)
if(TARGET ${item})
list(APPEND targets ${item})
endif()
endforeach()
# set the required target properties
set_target_properties(${targets} PROPERTIES POSITION_INDEPENDENT_CODE ON)
set_target_properties(${targets} PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
# Validate that following:
# - We are building with CUDA enabled.
# - We are building a VTK-m library or a library that wants cross library
@ -206,35 +228,28 @@ function(vtkm_add_target_information uses_vtkm_target)
# This is required as CUDA currently doesn't support device side calls across
# dynamic library boundaries.
if(TARGET vtkm::cuda)
get_target_property(lib_type ${uses_vtkm_target} TYPE)
get_target_property(requires_static vtkm::cuda requires_static_builds)
if(requires_static AND ${lib_type} STREQUAL "SHARED_LIBRARY" AND VTKm_TI_EXTENDS_VTKM)
#We provide different error messages based on if we are building VTK-m
#or being called by a consumer of VTK-m. We use PROJECT_NAME so that we
#produce the correct error message when VTK-m is a subdirectory include
#of another project
if(PROJECT_NAME STREQUAL "VTKm")
message(SEND_ERROR "${uses_vtkm_target} needs to be built STATIC as CUDA doesn't"
" support virtual methods across dynamic library boundaries. You"
" need to set the CMake option BUILD_SHARED_LIBS to `OFF`.")
else()
message(SEND_ERROR "${uses_vtkm_target} needs to be built STATIC as CUDA doesn't"
" support virtual methods across dynamic library boundaries. You"
" should either explicitly call add_library with the `STATIC` keyword"
" or set the CMake option BUILD_SHARED_LIBS to `OFF`.")
endif()
endif()
set_source_files_properties(${VTKm_TI_DEVICE_SOURCES} PROPERTIES LANGUAGE "CUDA")
endif()
foreach(target IN LISTS targets)
get_target_property(lib_type ${target} TYPE)
get_target_property(requires_static vtkm::cuda requires_static_builds)
set_target_properties(${uses_vtkm_target} PROPERTIES POSITION_INDEPENDENT_CODE ON)
set_target_properties(${uses_vtkm_target} PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
if(VTKm_TI_MODIFY_CUDA_FLAGS)
vtkm_get_cuda_flags(CMAKE_CUDA_FLAGS)
set(CMAKE_CUDA_FLAGS ${CMAKE_CUDA_FLAGS} PARENT_SCOPE)
if(requires_static AND ${lib_type} STREQUAL "SHARED_LIBRARY" AND VTKm_TI_EXTENDS_VTKM)
#We provide different error messages based on if we are building VTK-m
#or being called by a consumer of VTK-m. We use PROJECT_NAME so that we
#produce the correct error message when VTK-m is a subdirectory include
#of another project
if(PROJECT_NAME STREQUAL "VTKm")
message(SEND_ERROR "${target} needs to be built STATIC as CUDA doesn't"
" support virtual methods across dynamic library boundaries. You"
" need to set the CMake option BUILD_SHARED_LIBS to `OFF`.")
else()
message(SEND_ERROR "${target} needs to be built STATIC as CUDA doesn't"
" support virtual methods across dynamic library boundaries. You"
" should either explicitly call add_library with the `STATIC` keyword"
" or set the CMake option BUILD_SHARED_LIBS to `OFF`.")
endif()
endif()
endforeach()
endif()
endfunction()

@ -0,0 +1,58 @@
# CMake vtkm_add_target_information() makes using vtk-m easier
This higher order function allow build-systems that use VTK-m
to use `add_library` or `add_executable` calls but still have an
easy to way to get the required information to have VTK-m using
compilation units compile correctly.
```cmake
vtkm_add_target_information(
target[s]
[ MODIFY_CUDA_FLAGS ]
[ EXTENDS_VTKM ]
[ DEVICE_SOURCES <source_list>
)
```
Usage:
```cmake
add_library(lib_that_uses_vtkm STATIC a.cxx)
vtkm_add_target_information(lib_that_uses_vtkm
MODIFY_CUDA_FLAGS
DEVICE_SOURCES a.cxx
)
target_link_libraries(lib_that_uses_vtkm PRIVATE vtkm_filter)
```
## Options to vtkm_add_target_information
- MODIFY_CUDA_FLAGS: If enabled will add the required -arch=<ver> flags
that VTK-m was compiled with. If you have multiple libraries that use
VTK-m calling `vtkm_add_target_information` multiple times with
`MODIFY_CUDA_FLAGS` will cause duplicate compiler flags. To resolve this issue
you can; pass all targets and sources to a single `vtkm_add_target_information`
call, have the first one use `MODIFY_CUDA_FLAGS`, or use the provided
standalone `vtkm_get_cuda_flags` function.
- DEVICE_SOURCES: The collection of source files that are used by `target(s)` that
need to be marked as going to a special compiler for certain device adapters
such as CUDA.
- EXTENDS_VTKM: Some programming models have restrictions on how types can be used,
passed across library boundaries, and derived from.
For example CUDA doesn't allow device side calls across dynamic library boundaries,
and requires all polymorphic classes to be reachable at dynamic library/executable
link time.
To accommodate these restrictions we need to handle the following allowable
use-cases:
- Object library: do nothing, zero restrictions
- Executable: do nothing, zero restrictions
- Static library: do nothing, zero restrictions
- Dynamic library:
- Wanting to use VTK-m as implementation detail, doesn't expose VTK-m
types to consumers. This is supported no matter if CUDA is enabled.
- Wanting to extend VTK-m and provide these types to consumers.
This is only supported when CUDA isn't enabled. Otherwise we need to ERROR!
- Wanting to pass known VTK-m types across library boundaries for others
to use in filters/worklets. This is only supported when CUDA isn't enabled. Otherwise we need to ERROR!
For most consumers they can ignore the `EXTENDS_VTKM` property as the default will be correct.

@ -16,12 +16,10 @@ find_package(VTKm REQUIRED QUIET)
add_executable(ContourTreeMesh2D ContourTreeMesh2D.cxx)
target_link_libraries(ContourTreeMesh2D vtkm_filter)
vtkm_add_target_information(ContourTreeMesh2D
DEVICE_SOURCES ContourTreeMesh2D.cxx)
add_executable(ContourTreeMesh3D ContourTreeMesh3D.cxx)
target_link_libraries(ContourTreeMesh3D vtkm_filter)
vtkm_add_target_information(ContourTreeMesh3D
vtkm_add_target_information(ContourTreeMesh2D ContourTreeMesh3D
MODIFY_CUDA_FLAGS
DEVICE_SOURCES ContourTreeMesh3D.cxx)
DEVICE_SOURCES
ContourTreeMesh2D.cxx ContourTreeMesh3D.cxx)

@ -18,9 +18,7 @@ add_executable(CosmoHaloFinder CosmoHaloFinder.cxx)
target_link_libraries(CosmoCenterFinder PRIVATE vtkm_filter)
target_link_libraries(CosmoHaloFinder PRIVATE vtkm_filter)
vtkm_add_target_information(CosmoCenterFinder
vtkm_add_target_information(CosmoCenterFinder CosmoHaloFinder
MODIFY_CUDA_FLAGS
DEVICE_SOURCES CosmoCenterFinder.cxx)
vtkm_add_target_information(CosmoHaloFinder
MODIFY_CUDA_FLAGS
DEVICE_SOURCES CosmoHaloFinder.cxx)
DEVICE_SOURCES
CosmoCenterFinder.cxx CosmoHaloFinder.cxx)

@ -16,13 +16,10 @@ find_package(VTKm REQUIRED QUIET)
add_executable(Tetrahedralize Tetrahedralize.cxx)
target_link_libraries(Tetrahedralize PRIVATE vtkm_filter)
vtkm_add_target_information(Tetrahedralize
MODIFY_CUDA_FLAGS
DEVICE_SOURCES Tetrahedralize.cxx)
add_executable(Triangulate Triangulate.cxx)
target_link_libraries(Triangulate PRIVATE vtkm_filter)
vtkm_add_target_information(Triangulate
vtkm_add_target_information(Tetrahedralize Triangulate
MODIFY_CUDA_FLAGS
DEVICE_SOURCES Triangulate.cxx)
DEVICE_SOURCES
Tetrahedralize.cxx Triangulate.cxx)