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. # 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 # This higher order function allow build-systems that use VTK-m
# to compose add_library/add_executable and the required information to have # to use `add_library` or `add_executable` calls but still have an
# VTK-m enabled. # easy to way to get the required information to have VTK-m using
# compilation units compile correctly.
# #
# vtkm_add_target_information( # vtkm_add_target_information(
# target # target[s]
# [ MODIFY_CUDA_FLAGS ] # [ MODIFY_CUDA_FLAGS ]
# [ EXTENDS_VTKM ] # [ EXTENDS_VTKM ]
# [ DEVICE_SOURCES <source_list> # [ DEVICE_SOURCES <source_list>
@ -159,10 +160,14 @@ endfunction()
# target_link_libraries(lib_that_uses_vtkm PRIVATE vtkm_filter) # target_link_libraries(lib_that_uses_vtkm PRIVATE vtkm_filter)
# #
# MODIFY_CUDA_FLAGS: If enabled will add the required -arch=<ver> flags # 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 # that VTK-m was compiled with. If you have multiple libraries that use
# the standalone `vtkm_get_cuda_flags` function. # 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 # need to be marked as going to a special compiler for certain device adapters
# such as CUDA. # such as CUDA.
# #
@ -198,6 +203,23 @@ function(vtkm_add_target_information uses_vtkm_target)
${ARGN} ${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: # Validate that following:
# - We are building with CUDA enabled. # - We are building with CUDA enabled.
# - We are building a VTK-m library or a library that wants cross library # - 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 # This is required as CUDA currently doesn't support device side calls across
# dynamic library boundaries. # dynamic library boundaries.
if(TARGET vtkm::cuda) 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") 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) if(requires_static AND ${lib_type} STREQUAL "SHARED_LIBRARY" AND VTKm_TI_EXTENDS_VTKM)
set_target_properties(${uses_vtkm_target} PROPERTIES CUDA_SEPARABLE_COMPILATION ON) #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
if(VTKm_TI_MODIFY_CUDA_FLAGS) #produce the correct error message when VTK-m is a subdirectory include
vtkm_get_cuda_flags(CMAKE_CUDA_FLAGS) #of another project
set(CMAKE_CUDA_FLAGS ${CMAKE_CUDA_FLAGS} PARENT_SCOPE) 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() endif()
endfunction() 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) add_executable(ContourTreeMesh2D ContourTreeMesh2D.cxx)
target_link_libraries(ContourTreeMesh2D vtkm_filter) target_link_libraries(ContourTreeMesh2D vtkm_filter)
vtkm_add_target_information(ContourTreeMesh2D
DEVICE_SOURCES ContourTreeMesh2D.cxx)
add_executable(ContourTreeMesh3D ContourTreeMesh3D.cxx) add_executable(ContourTreeMesh3D ContourTreeMesh3D.cxx)
target_link_libraries(ContourTreeMesh3D vtkm_filter) target_link_libraries(ContourTreeMesh3D vtkm_filter)
vtkm_add_target_information(ContourTreeMesh3D vtkm_add_target_information(ContourTreeMesh2D ContourTreeMesh3D
MODIFY_CUDA_FLAGS 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(CosmoCenterFinder PRIVATE vtkm_filter)
target_link_libraries(CosmoHaloFinder PRIVATE vtkm_filter) target_link_libraries(CosmoHaloFinder PRIVATE vtkm_filter)
vtkm_add_target_information(CosmoCenterFinder vtkm_add_target_information(CosmoCenterFinder CosmoHaloFinder
MODIFY_CUDA_FLAGS MODIFY_CUDA_FLAGS
DEVICE_SOURCES CosmoCenterFinder.cxx) DEVICE_SOURCES
vtkm_add_target_information(CosmoHaloFinder CosmoCenterFinder.cxx CosmoHaloFinder.cxx)
MODIFY_CUDA_FLAGS
DEVICE_SOURCES CosmoHaloFinder.cxx)

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