Add module mechanism

This mechanism sets up CMake variables that allow a user to select which
modules/libraries to create. Dependencies will be tracked down to ensure
that all of a module's dependencies are also enabled.

The modules are also arranged into groups.
Groups allow you to set the enable flag for a group of modules at once.
Thus, if you have several modules that are likely to be used together,
you can create a group for them.

This can be handy in converting user-friendly CMake options (such as
`VTKm_ENABLE_RENDERING`) to the modules that enable that by pointing to
the appropriate group.
This commit is contained in:
Kenneth Moreland 2022-02-16 05:50:39 -07:00
parent 0893518f2d
commit ad1e7b5bdb
193 changed files with 1776 additions and 782 deletions

@ -53,4 +53,4 @@ build:centos8:
variables:
CMAKE_BUILD_TYPE: RelWithDebInfo
CMAKE_GENERATOR: "Unix Makefiles"
VTKM_SETTINGS: "serial+no_testing"
VTKM_SETTINGS: "serial+no_testing+min_build"

@ -71,6 +71,10 @@ foreach(option IN LISTS options)
set(VTKm_ENABLE_BENCHMARKS "ON" CACHE STRING "")
set(ENV{CMAKE_PREFIX_PATH} "$ENV{CMAKE_PREFIX_PATH}:$ENV{HOME}/gbench")
elseif(min_build STREQUAL option)
set(VTKm_BUILD_ALL_LIBRARIES "OFF" CACHE STRING "")
set(VTKm_VERBOSE_MODULES "ON" CACHE STRING "")
elseif(mpi STREQUAL option)
set(VTKm_ENABLE_MPI "ON" CACHE STRING "")

@ -10,7 +10,7 @@ build:ubuntu2004_gcc9:
- .run_automatically
variables:
CMAKE_BUILD_TYPE: Debug
VTKM_SETTINGS: "benchmarks+tbb+openmp+mpi+shared+hdf5"
VTKM_SETTINGS: "benchmarks+tbb+openmp+mpi+shared+hdf5+min_build"
test:ubuntu2004_gcc9:
tags:

639
CMake/VTKmModules.cmake Normal file

@ -0,0 +1,639 @@
##============================================================================
## 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.
##============================================================================
option(VTKm_VERBOSE_MODULES
"When on, extra information about what modules are found and why they are \
built or not is added as CMake status messages."
OFF
)
mark_as_advanced(VTKm_VERBOSE_MODULES)
# -----------------------------------------------------------------------------
#[==[
Sets a property for a module of a particular name. The module property is
available globally and can be retrieved with `vtkm_module_get_property`.
#]==]
function(vtkm_module_set_property module_name property_name property_value)
set_property(GLOBAL PROPERTY
"_vtkm_module_${module_name}_${property_name}" "${property_value}")
endfunction()
#[==[
Gets a property for a value of a particular name.
#]==]
function(vtkm_module_get_property out_var module_name property_name)
get_property(_vtkm_module_property GLOBAL PROPERTY
"_vtkm_module_${module_name}_${property_name}")
set("${out_var}" "${_vtkm_module_property}" PARENT_SCOPE)
endfunction()
#[==[
Sets out_var to true if a module of the given name exists, false otherwise.
A module does not need to be built for this to return true. Only the
associated vtkm.module file needs to exist.
#]==]
function(vtkm_module_exists out_var module_name)
vtkm_module_get_property(_vtkm_module_exists_name ${module_name} NAME)
if(_vtkm_module_exists_name)
set("${out_var}" TRUE PARENT_SCOPE)
else()
set("${out_var}" FALSE PARENT_SCOPE)
endif()
endfunction()
#[==[
Forces the enable value of a module group to be a particular value. This is
useful for converting a CMake `option` to a group of modules to turn on or
off. When a group of modules is forced with this function, a CMake cache
variable is not made, thus not allowing the user to change the value.
(Presumably, the value is changed via other, easier means.)
```cmake
vtkm_module_force_group(group_name
[VALUE <value>] | [ENABLE_OPTION <name>] | [DISABLE_OPTION <name>]
[ENABLE_VALUE <value>]
[DISABLE_VALUE <value>]
[REASON <string>]
)
The first argument is always the name of the group to force. Exactly
one of VALUE, ENABLE_OPTION, or DISABLE_OPTION must be provided.
* `VALUE`: The specific value to set the group enable/disable flag.
Must be `YES`, `NO`, `WANT`, `DONT_WANT`, `NO`, or `DEFAULT`.
* `ENABLE_OPTION`: The name of a CMake variable (usually a cache
variable) that sets the flag to `ENABLE_VALUE` if true or
`DISABLE_VALUE` if false.
* `DISABLE_OPTION`: The name of a CMake variable (usually a cache
variable) that sets the flag to `DISABLE_VALUE` if true or
`ENABLE_VALUE` if false.
* `ENABLE_VALUE`: Value used to turn on the group. Defaults to `YES`.
* `DISABLE_VALUE`: Value used to turn off the group. Defaults to `NO`.
* `REASON`: String given to inform users how the group enable/disable
flag got its value.
```
#]==]
function(vtkm_module_force_group group_name)
cmake_parse_arguments(PARSE_ARGV 1 force
""
"VALUE;ENABLE_OPTION;DISABLE_OPTION;ENABLE_VALUE;DISABLE_VALUE;REASON"
"")
if(force_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Bad arguments to vtkm_module_force_group")
endif()
if(NOT DEFINED force_ENABLE_VALUE)
set(force_ENABLE_VALUE "YES")
endif()
if(NOT DEFINED force_DISABLE_VALUE)
set(force_DISABLE_VALUE "NO")
endif()
if(DEFINED force_VALUE)
if(NOT force_REASON)
set(force_REASON "Forced value")
endif()
elseif(force_ENABLE_OPTION)
if(${${force_ENABLE_OPTION}})
set(force_VALUE ${force_ENABLE_VALUE})
else()
set(force_VALUE ${force_DISABLE_VALUE})
endif()
if(NOT force_REASON)
set(force_REASON "${force_ENABLE_OPTION} set to ${${force_ENABLE_OPTION}}")
endif()
elseif(force_DISABLE_OPTION)
if(NOT ${${force_DISABLE_OPTION}})
set(force_VALUE ${force_ENABLE_VALUE})
else()
set(force_VALUE ${force_DISABLE_VALUE})
endif()
if(NOT force_REASON)
set(force_REASON "${force_DISABLE_OPTION} set to ${${force_DISABLE_OPTION}}")
endif()
else()
message(FATAL_ERROR
"vtkm_module_force_group must be given VALUE, ENABLE_OPTION, or DISABLE_OPTION")
endif()
set(force_REASON "${force_REASON} (forcing VTKm_GROUP_ENABLE_${group_name} to ${force_VALUE})")
set_property(GLOBAL PROPERTY
"_vtkm_module_group_enable_${group_name}_override" TRUE)
set_property(GLOBAL PROPERTY
"_vtkm_module_group_enable_${group_name}_value" "${force_VALUE}")
set_property(GLOBAL PROPERTY
"_vtkm_module_group_enable_${group_name}_reason" "${force_REASON}")
endfunction()
#[==[
Creates a CMake variable to enable/disable the module with the given name.
This cached variable can be set by the user to turn the module on or off.
If the cache variable already exists, then this call has no effect.
#]==]
function(vtkm_module_enable_module_variable module_name default_value)
set(VTKm_MODULE_ENABLE_${module_name} ${default_value}
CACHE STRING
"Enable the ${module_name} module.
YES - Always create the module (it is an error otherwise).
WANT - Create the module if possible.
DONT_WANT - Create the module only if there is a dependency that requires it.
NO - Never create the module.
DEFAULT - Do the default behavior."
)
mark_as_advanced(VTKm_MODULE_ENABLE_${module_name})
set_property(CACHE VTKm_MODULE_ENABLE_${module_name}
PROPERTY STRINGS "YES;WANT;DONT_WANT;NO;DEFAULT"
)
endfunction()
#[==[
Creates a CMake variable to enable/disable the modules with the given group name.
This cached variable can be set by the user to turn the module on or off.
This cache variable only has an effect on modules that belong to this group and
have their own ENABLE flag set to DEFAULT.
If the cache variable already exists, then this call has no effect.
#]==]
function(vtkm_module_enable_group_variable group_name default_value)
get_property(override_exists GLOBAL PROPERTY _vtkm_module_group_enable_${group_name}_override)
if(override_exists)
# There is a force of this group overriding any setting, in which case
# don't even give the option.
return()
endif()
set(VTKm_GROUP_ENABLE_${group_name} ${default_value}
CACHE STRING
"Enable the ${group_name} module group.
YES - Always create the group of modules (it is an error otherwise).
WANT - Create the group of modules if possible.
DONT_WANT - Create the module only if there is a dependency that requires it.
NO - Never create the module.
DEFAULT - Do the default behavior."
)
mark_as_advanced(VTKm_GROUP_ENABLE_${group_name})
set_property(CACHE VTKm_GROUP_ENABLE_${group_name}
PROPERTY STRINGS "YES;WANT;DONT_WANT;NO;DEFAULT"
)
endfunction()
# -----------------------------------------------------------------------------
#[==[
Parses the given `module_file`. The name of the module (extracted from the file)
is returned in `name_var`.
For each module option expected in the module file, a module property with the
same name is created to hold that option. Additionally, a `DIRECTORY` property
is created to point to the source directory containing the module. The module
properties can be retrieved with the vtkm_module_get_property function.
#]==]
function(_vtkm_module_parse_module_file module_file name_var)
# Read the file
if(NOT IS_ABSOLUTE "${module_file}")
string(PREPEND module_file "${CMAKE_CURRENT_SOURCE_DIR}/")
endif()
file(READ ${module_file} module_file_contents)
# Remove comments
string(REGEX REPLACE "#[^\n]*\n" "\n" module_file_contents "${module_file_contents}")
# Separate arguments with `;` to treat it like a list.
string(REGEX REPLACE "( |\n)+" ";" module_file_contents "${module_file_contents}")
# Parse module file as arguments to a function
set(options NO_TESTING)
set(oneValueArgs NAME)
set(multiValueArgs
GROUPS DEPENDS PRIVATE_DEPENDS OPTIONAL_DEPENDS TEST_DEPENDS TEST_OPTIONAL_DEPENDS)
cmake_parse_arguments(_vtkm_module
"${options}"
"${oneValueArgs}"
"${multiValueArgs}"
${module_file_contents})
# Check required arguments
if(_vtkm_module_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Module file ${module_file} contains unknown options.")
endif()
if(NOT _vtkm_module_NAME)
message(FATAL_ERROR "Module file ${module_file} does not specify a NAME option.")
endif()
set(NAME ${_vtkm_module_NAME})
# Stash the information in variables
foreach(module_var_name IN LISTS options oneValueArgs multiValueArgs)
vtkm_module_set_property(${NAME} ${module_var_name} "${_vtkm_module_${module_var_name}}")
endforeach()
get_filename_component(directory "${module_file}" DIRECTORY)
vtkm_module_set_property(${NAME} DIRECTORY "${directory}")
set(${name_var} ${NAME} PARENT_SCOPE)
endfunction()
# -----------------------------------------------------------------------------
#[==[
Scans the given directories recursively for `vtkm.module` files and put the
paths into the output variable. Note that the module files are assumed to
live next to the `CMakeLists.txt` file, which will build the module.
#]==]
function(_vtkm_modules_find output)
set(all_modules)
foreach(search_directory IN LISTS ARGN)
file(GLOB_RECURSE found_modules "${search_directory}/vtkm.module")
list(APPEND all_modules ${found_modules})
endforeach()
set(${output} ${all_modules} PARENT_SCOPE)
endfunction()
# -----------------------------------------------------------------------------
#[==[
Scans for modules and builds the appropriate cached variables to optionally
build them. Modules are found by looking for files named `vtkm.module`.
This module file is assumed to live next to the `CMakeLists.txt` file that
can build the module.
```cmake
vtkm_modules_scan(
SCAN_DIRECTORIES <file>...
PROVIDED_MODULES <variable>
)
The arguments are as follows:
* `SCAN_DIRECTORIES`: (Required) A list of directories to (recursively) scan
for modules (indicated by a `vtkm.module` file).
* `PROVIDED_MODULES`: (Required) The name of a variable that will be set with
a list of modules that exist.
All the directories in `SCAN_DIRECTORIES` are recursively searched for files
named `vtkm.module`. See docs/Modules.md for information on the format of
`vtkm.module` files.
#]==]
function(vtkm_modules_scan)
cmake_parse_arguments(PARSE_ARGV 0 _scan
""
"PROVIDED_MODULES"
"SCAN_DIRECTORIES"
)
if(_scan_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Invalid arguments given to vtkm_module_scan.")
endif()
if(NOT _scan_PROVIDED_MODULES)
message(FATAL_ERROR "vtkm_scan_modules must have a `PROVIDED_MODULES` argument.")
endif()
_vtkm_modules_find(_scan_module_files ${_scan_SCAN_DIRECTORIES})
if (NOT _scan_module_files)
message(FATAL_ERROR "No vtkm.module files found in '${_scan_SCAN_DIRECTORIES}'")
endif()
set(_scan_module_names)
# Read all of the module files passed in.
foreach(module_file IN LISTS _scan_module_files)
_vtkm_module_parse_module_file(${module_file} name)
if(VTKm_VERBOSE_MODULES)
message(STATUS "Found module ${name} in ${module_file}")
endif()
vtkm_module_enable_module_variable(${name} "DEFAULT")
vtkm_module_get_property(module_groups ${name} GROUPS)
foreach(group_name IN LISTS module_groups)
vtkm_module_enable_group_variable(${group_name} "DEFAULT")
endforeach()
list(APPEND _scan_module_names "${name}")
endforeach()
set(${_scan_PROVIDED_MODULES} ${_scan_module_names} PARENT_SCOPE)
endfunction()
# -----------------------------------------------------------------------------
function(_vtkm_module_check_enable_flag variable_name)
set(valid_flags YES WANT DONT_WANT NO DEFAULT)
if(NOT "${${variable_name}}" IN_LIST valid_flags)
message(FATAL_ERROR
"${variable_name} must be set to one of ${valid_flags}, not `${${variable_name}}`.")
endif()
endfunction()
function(_vtkm_module_get_enable_flag module output)
set(reasons_output "${ARGV2}")
_vtkm_module_check_enable_flag(VTKm_MODULE_ENABLE_${module})
set(enable_flag ${VTKm_MODULE_ENABLE_${module}})
if(reasons_output)
set(reasons "VTKm_MODULE_ENABLE_${module} is set to `${VTKm_MODULE_ENABLE_${module}}`")
else()
set(reasons)
endif()
if(enable_flag STREQUAL "DEFAULT")
vtkm_module_get_property(module_groups ${module} GROUPS)
foreach(group IN LISTS module_groups)
get_property(override_exists GLOBAL PROPERTY _vtkm_module_group_enable_${group}_override)
if(override_exists)
get_property(group_enable_flag GLOBAL PROPERTY _vtkm_module_group_enable_${group}_value)
if(reasons_output)
get_property(force_reason
GLOBAL PROPERTY _vtkm_module_group_enable_${group}_reason)
list(APPEND reasons "${force_reason}")
endif()
else()
_vtkm_module_check_enable_flag(VTKm_GROUP_ENABLE_${group})
set(group_enable_flag "${VTKm_GROUP_ENABLE_${group}}")
if(reasons_output)
list(APPEND reasons "VTKm_GROUP_ENABLE_${group} is set to `${group_enable_flag}`")
endif()
endif()
if(NOT ${group_enable_flag} STREQUAL "DEFAULT")
set(enable_flag ${group_enable_flag})
break()
endif()
endforeach()
endif()
if(enable_flag STREQUAL "DEFAULT")
if(_vtkm_modules_want_by_default)
set(enable_flag "WANT")
else()
set(enable_flag "DONT_WANT")
endif()
if(reasons_output)
list(APPEND reasons "${_vtkm_modules_want_by_default_reason}")
endif()
endif()
set(${output} ${enable_flag} PARENT_SCOPE)
if(reasons_output)
set(${reasons_output} ${reasons} PARENT_SCOPE)
endif()
endfunction()
function(_vtkm_modules_print_enable_flag module)
_vtkm_module_get_enable_flag(${module} enable_flag reasons)
message(STATUS "Module ${module} is `${enable_flag}` because:")
foreach(reason IN LISTS reasons)
message(STATUS " ${reason}")
endforeach()
endfunction()
function(_vtkm_modules_print_dependency_chain first_module)
set(last_module ${first_module})
foreach(dep IN LISTS ARGN)
message(STATUS "Module `${last_module}` depends on module `${dep}`")
set(last_module ${dep})
endforeach()
endfunction()
# -----------------------------------------------------------------------------
function(_vtkm_modules_try_build target_module dependent_module dependency_chain)
vtkm_module_exists(exists ${target_module})
if(NOT exists)
# The calling code should check to make sure something is a module before calling this.
message(FATAL_ERROR "\
Internal error: _vtkm_modules_try_build called for a non-existant module `${target_module}`.")
endif()
if(TARGET ${target_module})
# This module is already created. Everything is good.
return()
endif()
# Detect circular dependencies (to prevent infinite CMake loops)
list(FIND dependency_chain ${target_module} chain_index)
if(chain_index GREATER -1)
message("Circular dependency in modules detected!")
list(SUBLIST dependency_chain ${chain_index} -1 subchain)
_vtkm_modules_print_dependency_chain(${subchain} ${target_module})
message(FATAL_ERROR "\
Detected a circular dependency for module `${target_module}`. See the previous \
messages for the dependency chain. Modify the dependencies in the vtkm.module \
files to break the dependency cycle.")
endif()
_vtkm_module_get_enable_flag(${target_module} enable_flag)
if(enable_flag STREQUAL "NO")
# Cannot build this module.
if(dependent_module)
message("\
Unable to enable module ${dependent_module} because module ${depends_on_module}, \
on which it depends, cannot be enabled. See the following status messages \
for more information.")
_vtkm_modules_print_enable_flag(${dependent_module})
_vtkm_modules_print_enable_flag(${target_module})
_vtkm_modules_print_dependency_chain(${dependent_module} ${dependency_chain} ${target_module})
message(FATAL_ERROR "Inconsistent module enable states. See previous status for details.")
endif()
if(VTKm_VERBOSE_MODULES)
message(STATUS "Not building module ${target_module} because enable flag set to NO.")
_vtkm_modules_print_enable_flag(${target_module})
endif()
return()
endif()
if((enable_flag STREQUAL "DONT_WANT") AND (NOT dependent_module))
# Have no reason to build this module.
if(VTKm_VERBOSE_MODULES)
message(STATUS "\
Not building module ${target_module} because enable flag set to `DONT_WANT` \
unless a dependency is found.")
_vtkm_modules_print_enable_flag(${target_module})
endif()
return()
endif()
# At this point, we either want or need the module.
if((enable_flag STREQUAL "YES") AND (NOT dependent_module))
# Found new target_module
set(dependent_module ${target_module})
endif()
list(APPEND dependency_chain ${target_module})
# Attempt to build all dependent modules first.
vtkm_module_get_property(module_dependencies ${target_module} DEPENDS)
vtkm_module_get_property(module_private_dependencies ${target_module} PRIVATE_DEPENDS)
foreach(depends_on_module IN LISTS module_dependencies module_private_dependencies)
# A module can depend on either a module (which defines a target) or a target created
# somewhere else. If it depends on a module, allow that module to create the target.
vtkm_module_exists(depends_on_is_module ${depends_on_module})
if(depends_on_is_module)
_vtkm_modules_try_build(${depends_on_module} "${dependent_module}" "${dependency_chain}")
endif()
if(NOT TARGET ${depends_on_module})
# The module target_module depends on is not being built. Thus, we cannot compile
# this module. Customize the messages based on whether this module was needed to
# be on for correctness and whether the dependency is actually a module or just an
# expected library.
if(dependent_module)
if(depends_on_is_module)
# Internal error. If the dependent module could not be built, it should have already
# issued a FATAL_ERROR.
message(FATAL_ERROR "Internal error: Required module not built.")
else()
_vtkm_modules_print_enable_flag(${target_module})
message(FATAL_ERROR "\
Unable to enable module `${target_module}` because it depends on `${depends_on_module}`. \
There is no module of that name. Either create a module of that name (using a `vtkm.module` \
file) or create a CMake target of that name before the modules are built.")
endif()
elseif(VTKm_VERBOSE_MODULES)
if(depends_on_is_module)
message(STATUS "\
Not building module `${target_module}` because it depends on module `${depends_on_module}`, \
which is not built.")
else()
message(STATUS "\
Not building module `${target_module}` because it depends on `${depends_on_module}`, which \
is neither a module or an existing target. Either create a module of that name (using a \
`vtkm.module` file) or create a CMake target of that name before the modules are built.")
endif()
_vtkm_modules_print_enable_flag(${target_module})
endif()
return()
endif()
endforeach()
# Also attempt to build optional dependent modules. These behave the same except we do
# not generate an error if the module cannot be loaded by removing the "dependent_module"
# and ignoring whether the dependent module actually gets built.
vtkm_module_get_property(module_optional_dependencies ${target_module} OPTIONAL_DEPENDS)
foreach(depends_on_module IN LISTS module_optional_dependencies)
vtkm_module_exists(depends_on_is_module ${depends_on_module})
if(depends_on_is_module)
_vtkm_modules_try_build(${depends_on_module} "" "${dependency_chain}")
endif()
endforeach()
# We have verified that we can enable this module.
if(VTKm_VERBOSE_MODULES)
if(enable_flag STREQUAL "DONT_WANT")
list(GET dependency_chain -2 needed_by)
message(STATUS "Enabling module `${target_module}` because it is needed by `${needed_by}`")
else()
message(STATUS "Enabling module `${target_module}`")
endif()
_vtkm_modules_print_enable_flag(${target_module})
endif()
vtkm_module_get_property(src_directory ${target_module} DIRECTORY)
file(RELATIVE_PATH rel_directory "${VTKm_SOURCE_DIR}" "${src_directory}")
set(vtkm_module_current ${target_module})
add_subdirectory("${src_directory}" "${VTKm_BINARY_DIR}/${rel_directory}")
set(vtkm_module_current)
if(NOT TARGET ${target_module})
if(VTKm_VERBOSE_MODULES)
message(STATUS "\
Module `${target_module}` did not create the expected target. Creating a 'fake' target \
so that other modules know this module is loaded.")
endif()
add_library(${target_module} INTERFACE)
endif()
endfunction()
# -----------------------------------------------------------------------------
function(_vtkm_modules_try_build_tests target_module)
if(NOT TARGET ${target_module})
# This module was never created, so don't compile tests for it.
return()
endif()
vtkm_module_get_property(no_testing ${target_module} NO_TESTING)
if(no_testing)
if(VTKm_VERBOSE_MODULES)
message(STATUS
"Not building tests for `${target_module}` because it has the NO_TESTING option.")
endif()
return()
endif()
vtkm_module_get_property(target_dependencies ${target_module} TEST_DEPENDS)
foreach(dependency IN LISTS target_dependencies)
if(NOT TARGET ${dependency})
if(VTKm_VERBOSE_MODULES)
message(STATUS
"Not building tests for `${target_module}` because missing dependency `${dependency}`")
endif()
return()
endif()
endforeach()
vtkm_module_get_property(src_directory ${target_module} DIRECTORY)
file(RELATIVE_PATH rel_directory "${VTKm_SOURCE_DIR}" "${src_directory}")
set(vtkm_module_current_test ${target_module})
add_subdirectory("${src_directory}/testing" "${VTKm_BINARY_DIR}/${rel_directory}/testing")
set(vtkm_module_current_test)
endfunction()
# -----------------------------------------------------------------------------
#[==[
Determines which modules should be built and then calls `add_subdirectory` on those
modules to build them.
```cmake
vtkm_modules_build(
PROVIDED_MODULES <name>...
[WANT_BY_DEFAULT <ON|OFF>]
[WANT_BY_DEFAULT_REASON <string>]
)
The arguments are as follows:
* `PROVIDED_MODULES`: (Required) A list of module names that are available.
This list typically provided by `vtkm_modules_scan`.
* `WANT_BY_DEFAULT`: (Defaults to `OFF`) Whether modules should by default be
built if possible.
* `WANT_BY_DEFAULT_REASON`: When `VTKm_VERBOSE_MODULES` and a module's enable
is set to the default value (dictated by `WANT_BY_DEFAULT`), then this string
is given as the reason.
```
#]==]
function(vtkm_modules_build)
cmake_parse_arguments(PARSE_ARGV 0 _build
""
"WANT_BY_DEFAULT;WANT_BY_DEFAULT_REASON"
"PROVIDED_MODULES"
)
if(_build_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Invalid arguments given to vtkm_modules_build.")
endif()
if(NOT _build_PROVIDED_MODULES)
message(FATAL_ERROR "vtkm_modules_build requires PROVIDED_MODULES variable.")
endif()
if(_build_WANT_BY_DEFAULT)
set(_vtkm_modules_want_by_default ${_build_WANT_BY_DEFAULT})
else()
set(_vtkm_modules_want_by_default OFF)
endif()
if(_build_WANT_BY_DEFAULT_REASON)
set(_vtkm_modules_want_by_default_reason "${_build_WANT_BY_DEFAULT_REASON}")
else()
set(_vtkm_modules_want_by_default_reason "WANT_BY_DEFAULT is ${_vtkm_modules_want_by_default}")
endif()
foreach(module IN LISTS _build_PROVIDED_MODULES)
_vtkm_modules_try_build(${module} "" "")
endforeach()
if(VTKm_ENABLE_TESTING)
foreach(module IN LISTS _build_PROVIDED_MODULES)
_vtkm_modules_try_build_tests(${module})
endforeach()
endif()
endfunction()

@ -92,6 +92,11 @@ endif()
#-----------------------------------------------------------------------------
if(VTKm_ENABLE_RENDERING AND NOT TARGET vtkm_rendering_gl_context)
add_library(vtkm_rendering_gl_context INTERFACE)
if(NOT VTKm_INSTALL_ONLY_LIBRARIES)
install(TARGETS vtkm_rendering_gl_context
EXPORT ${VTKm_EXPORT_NAME}
)
endif()
endif()
#-----------------------------------------------------------------------------

@ -512,6 +512,35 @@ function(vtkm_library)
endif()
set_property(TARGET ${lib_name} PROPERTY OUTPUT_NAME ${lib_name}${_lib_suffix})
# Include any module information
if(vtkm_module_current)
if(NOT lib_name STREQUAL vtkm_module_current)
# We do want each library to be in its own module. (VTK's module allows you to declare
# multiple libraries per module. We may want that in the future, but right now we should
# not need it.) Right now we have one exception: vtkm_filter_extra inside of the
# vtkm_filter_core module. We are in the process of moving the filters to the new filter
# structure, and when that is done, vtkm_filter_extra should go away. But it is complex
# and will take some time. When that is done, perhaps this should be a stronger message
# (either a warning or error).
message("Library name `${lib_name}` does not match module name `${vtkm_module_current}`")
endif()
vtkm_module_get_property(depends ${vtkm_module_current} DEPENDS)
vtkm_module_get_property(private_depends ${vtkm_module_current} PRIVATE_DEPENDS)
vtkm_module_get_property(optional_depends ${vtkm_module_current} OPTIONAL_DEPENDS)
target_link_libraries(${lib_name}
PUBLIC ${depends}
PRIVATE ${private_depends}
)
foreach(opt_dep IN LISTS optional_depends)
if(TARGET ${opt_dep})
target_link_libraries(${lib_name} PRIVATE ${opt_dep})
endif()
endforeach()
else()
# Might need to add an argument to vtkm_library to create an exception to this rule
message(FATAL_ERROR "Library `${lib_name}` is not created inside of a VTK-m module.")
endif()
#generate the export header and install it
vtkm_generate_export_header(${lib_name})

@ -16,8 +16,7 @@
# -DVTKm_SOURCE_DIR=<VTKm_SOURCE_DIR>
# -DVTKm_BINARY_DIR=<VTKm_BINARY_DIR>
# -DVTKm_INSTALL_INCLUDE_DIR=<VTKm_INSTALL_INCLUDE_DIR>
# -DVTKm_ENABLE_RENDERING=<VTKm_ENABLE_RENDERING>
# -DVTKm_ENABLE_LOGGING=<VTKm_ENABLE_LOGGING>
# -DDIR_EXCEPTIONS=<dir>:<dir>:...
# -DVTKm_ENABLE_HDF5_IO=<VTKm_ENABLE_HDF5_IO>
# -P <VTKm_SOURCE_DIR>/CMake/testing/VTKMCheckSourceInInstall.cmake
##
@ -34,12 +33,9 @@ endif ()
if (NOT VTKm_INSTALL_INCLUDE_DIR)
message(FATAL_ERROR "VTKm_INSTALL_INCLUDE_DIR not defined.")
endif ()
if (NOT DEFINED VTKm_ENABLE_RENDERING)
message(FATAL_ERROR "VTKm_ENABLE_RENDERING not defined.")
endif ()
if (NOT DEFINED VTKm_ENABLE_LOGGING)
message(FATAL_ERROR "VTKm_ENABLE_LOGGING not defined.")
endif ()
if (NOT DEFINED DIR_EXCEPTIONS)
message(FATAL_ERROR "DIR_EXCEPTIONS not defined.")
endif()
if (NOT DEFINED VTKm_ENABLE_HDF5_IO)
message(FATAL_ERROR "VTKm_ENABLE_HDF5_IO not defined.")
endif()
@ -141,16 +137,11 @@ function(do_verify root_dir prefix)
internal/ArrayPortalVirtual.h
)
string(REPLACE ":" ";" directory_exceptions "${DIR_EXCEPTIONS}")
#by default every header in a testing directory doesn't need to be installed
set(directory_exceptions ".*/testing" )
list(APPEND directory_exceptions ".*/testing")
# These exceptions should be based on the status of the associated
# cmake option
if(NOT VTKm_ENABLE_RENDERING)
list(APPEND directory_exceptions rendering)
endif()
if(NOT VTKm_ENABLE_LOGGING)
list(APPEND directory_exceptions thirdparty/loguru)
endif()
if (NOT VTKm_ENABLE_HDF5_IO)
list(APPEND file_exceptions
io/ImageWriterHDF5.h

@ -11,12 +11,23 @@
# -----------------------------------------------------------------------------
function(vtkm_test_install )
if(NOT VTKm_INSTALL_ONLY_LIBRARIES)
# Find all modules that are not-compiled. Skip these directories.
set(dir_exceptions)
foreach(module IN LISTS all_modules)
if(NOT TARGET ${module})
vtkm_module_get_property(directory ${module} DIRECTORY)
file(RELATIVE_PATH directory "${VTKm_SOURCE_DIR}/vtkm" "${directory}")
list(APPEND dir_exceptions ${directory})
endif()
endforeach()
# Replace ';' list separator with ':' to preserve them as a single argument
string(REPLACE ";" ":" dir_exceptions "${dir_exceptions}")
set(command_args
"-DVTKm_SOURCE_DIR=${VTKm_SOURCE_DIR}"
"-DVTKm_BINARY_DIR=${VTKm_BINARY_DIR}"
"-DVTKm_INSTALL_INCLUDE_DIR=${VTKm_INSTALL_INCLUDE_DIR}"
"-DVTKm_ENABLE_RENDERING=${VTKm_ENABLE_RENDERING}"
"-DVTKm_ENABLE_LOGGING=${VTKm_ENABLE_LOGGING}"
"-DDIR_EXCEPTIONS=${dir_exceptions}"
"-DVTKm_ENABLE_HDF5_IO=${VTKm_ENABLE_HDF5_IO}"
)

@ -10,7 +10,7 @@
include(VTKmWrappers)
function(vtkm_create_test_executable
function(_vtkm_create_test_executable
prog_name
sources
device_sources
@ -206,35 +206,67 @@ function(vtkm_unit_tests)
# Add the path to the location where generated regression test images should be written
list(APPEND VTKm_UT_TEST_ARGS "--vtkm-write-dir=${VTKm_BINARY_DIR}")
set(test_libraries)
if(vtkm_module_current_test)
vtkm_module_get_property(module_dir ${vtkm_module_current_test} DIRECTORY)
vtkm_module_get_property(depends ${vtkm_module_current_test} TEST_DEPENDS)
vtkm_module_get_property(optional_depends ${vtkm_module_current_test} TEST_OPTIONAL_DEPENDS)
list(APPEND depends ${vtkm_module_current_test})
set(test_libraries ${depends})
foreach(lib IN LISTS VTKm_UT_LIBRARIES)
vtkm_module_exists(lib_is_module ${lib})
if((lib_is_module) AND (NOT ${lib} IN_LIST depends) AND (NOT ${lib} IN_LIST optional_depends))
message(WARNING "\
Test program for module `${vtkm_module_current_test}` lists `${lib} as a library in \
vtkm_unit_tests but not in its test dependencies. Add test dependencies to \
`${module_dir}/vtkm.module`.")
endif()
list(APPEND test_libraries ${lib})
endforeach()
foreach(module IN LISTS optional_depends)
if(TARGET ${module})
list(APPEND test_libraries ${module})
endif()
endforeach()
else()
if(NOT vtkm_module_current)
message(WARNING "TEST ${test_prog} is not associated with any module.")
endif()
endif()
if(vtkm_module_current)
message(WARNING "Test ${test_prog} is being created inside a module definition rather than tests.")
endif()
if(VTKm_UT_MPI)
if (VTKm_ENABLE_MPI)
vtkm_create_test_executable(
_vtkm_create_test_executable(
${test_prog}
"${VTKm_UT_SOURCES}"
"${VTKm_UT_DEVICE_SOURCES}"
"${VTKm_UT_LIBRARIES}"
"${test_libraries}"
"${VTKm_UT_DEFINES}"
ON # is_mpi_test
ON # use_mpi
${VTKm_UT_USE_VTKM_JOB_POOL})
endif()
if ((NOT VTKm_ENABLE_MPI) OR VTKm_ENABLE_DIY_NOMPI)
vtkm_create_test_executable(
_vtkm_create_test_executable(
${test_prog}
"${VTKm_UT_SOURCES}"
"${VTKm_UT_DEVICE_SOURCES}"
"${VTKm_UT_LIBRARIES}"
"${test_libraries}"
"${VTKm_UT_DEFINES}"
ON # is_mpi_test
OFF # use_mpi
${VTKm_UT_USE_VTKM_JOB_POOL})
endif()
else()
vtkm_create_test_executable(
_vtkm_create_test_executable(
${test_prog}
"${VTKm_UT_SOURCES}"
"${VTKm_UT_DEVICE_SOURCES}"
"${VTKm_UT_LIBRARIES}"
"${test_libraries}"
"${VTKm_UT_DEFINES}"
OFF # is_mpi_test
OFF # use_mpi

@ -112,6 +112,14 @@ cmake_dependent_option(VTKm_ENABLE_TESTING_LIBRARY "Enable VTKm Testing Library"
OFF "NOT VTKm_ENABLE_TESTING;NOT VTKm_ENABLE_BENCHMARKS" ON)
mark_as_advanced(VTKm_ENABLE_TESTING_LIBRARY)
# We may want to make finer controls on whether libraries/modules get built.
# VTK uses the concept of groups for its modules
vtkm_option(VTKm_BUILD_ALL_LIBRARIES
"Build all libraries by default. (Can be overridden for each library.)"
ON
)
mark_as_advanced(VTKm_BUILD_ALL_LIBRARIES)
vtkm_option(VTKm_USE_DOUBLE_PRECISION "Use double precision for floating point calculations" OFF)
vtkm_option(VTKm_USE_64BIT_IDS "Use 64-bit indices." ON)
@ -192,6 +200,26 @@ mark_as_advanced(
VTKm_SKIP_LIBRARY_VERSIONS
)
#-----------------------------------------------------------------------------
# Force building of modules where specified by user-facing options.
include(VTKmModules)
vtkm_module_force_group(Core VALUE "YES" REASON "Core modules always built")
vtkm_module_force_group(Rendering ENABLE_OPTION VTKm_ENABLE_RENDERING)
vtkm_module_force_group(Logging ENABLE_OPTION VTKm_ENABLE_LOGGING)
vtkm_module_force_group(Testing
ENABLE_OPTION VTKm_ENABLE_TESTING_LIBRARY
ENABLE_VALUE "WANT"
DISABLE_VALUE "DONT_WANT"
)
vtkm_module_force_group(Benchmarking ENABLE_OPTION VTKm_ENABLE_BENCHMARKS)
# The tutorial requires several common filters. This logic might need to
# become more complicated (or less compliated if we decide to always
# compile these).
if(VTKm_ENABLE_TUTORIALS)
vtkm_module_force_group(FiltersCommon VALUE "YES" REASON "Tutorial needs common filters.")
endif()
#-----------------------------------------------------------------------------
# Setup default build types
@ -262,7 +290,18 @@ check_type_size("long long" VTKm_SIZE_LONG_LONG BUILTIN_TYPES_ONLY)
#-----------------------------------------------------------------------------
# Add subdirectories
add_subdirectory(vtkmstd)
add_subdirectory(vtkm)
#-----------------------------------------------------------------------------
# Process modules
vtkm_modules_scan(
SCAN_DIRECTORIES vtkm benchmarking
PROVIDED_MODULES all_modules
)
vtkm_modules_build(
PROVIDED_MODULES ${all_modules}
WANT_BY_DEFAULT ${VTKm_BUILD_ALL_LIBRARIES}
WANT_BY_DEFAULT_REASON "VTKm_BUILD_ALL_LIBRARIES is `${VTKm_BUILD_ALL_LIBRARIES}`"
)
#-----------------------------------------------------------------------------
# Build documentation
@ -376,12 +415,6 @@ if (VTKm_ENABLE_CPACK)
include(CPack)
endif ()
#-----------------------------------------------------------------------------
#add the benchmarking folder
if(VTKm_ENABLE_BENCHMARKS)
add_subdirectory(benchmarking)
endif()
#-----------------------------------------------------------------------------
if (VTKm_ENABLE_TESTING)

@ -8,23 +8,25 @@
## PURPOSE. See the above copyright notice for more information.
##============================================================================
if(NOT vtkm_module_current STREQUAL "benchmarking")
message(FATAL_ERROR "Benchmarking CMakeLists.txt not loaded by benchmarking module.")
endif()
#Find Google Benchmark.Note that benchmark_DIR must be pointed at an
#installation, not a build directory.
find_package(benchmark REQUIRED)
function(add_benchmark)
set(options)
set(oneValueArgs NAME FILE)
set(multiValueArgs LIBS)
cmake_parse_arguments(VTKm_AB
"${options}" "${oneValueArgs}" "${multiValueArgs}"
${ARGN}
)
set(exe_name ${VTKm_AB_NAME})
add_executable(${exe_name} ${VTKm_AB_FILE})
target_link_libraries(${exe_name} PRIVATE ${VTKm_AB_LIBS})
function(add_benchmark exe_name)
add_executable(${exe_name} ${exe_name}.cxx)
target_link_libraries(${exe_name} PRIVATE benchmark::benchmark)
vtkm_module_get_property(depends benchmarking DEPENDS)
target_link_libraries(${exe_name} PRIVATE ${depends})
vtkm_module_get_property(optional_depends benchmarking OPTIONAL_DEPENDS)
foreach(dep IN LISTS optional_depends)
if(TARGET ${dep})
target_link_libraries(${exe_name} PRIVATE ${dep})
endif()
endforeach()
vtkm_add_drop_unused_function_flags(${exe_name})
vtkm_add_target_information(${exe_name})
@ -34,7 +36,8 @@ function(add_benchmark)
CUDA_VISIBILITY_PRESET "hidden"
)
vtkm_add_target_information(${exe_name} DEVICE_SOURCES ${VTKm_AB_FILE})
# At some point, we might not want to compile benchmarks with device compilers.
vtkm_add_target_information(${exe_name} DEVICE_SOURCES ${exe_name}.cxx)
endfunction()
set(benchmarks
@ -48,22 +51,24 @@ set(benchmarks
BenchmarkTopologyAlgorithms
)
if(TARGET vtkm_rendering)
list(APPEND benchmarks
BenchmarkRayTracing
BenchmarkInSitu
)
endif()
set(VTKm_BENCHS_RANGE_LOWER_BOUNDARY 4096 CACHE STRING "Smallest sample for input size bench for BenchmarkDeviceAdapter")
set(VTKm_BENCHS_RANGE_UPPER_BOUNDARY 134217728 CACHE STRING "Biggest sample for input size bench for BenchmarkDeviceAdapter")
mark_as_advanced(VTKm_BENCHS_RANGE_LOWER_BOUNDARY VTKm_BENCHS_RANGE_UPPER_BOUNDARY)
foreach (benchmark ${benchmarks})
add_benchmark(NAME ${benchmark} FILE ${benchmark}.cxx LIBS vtkm_source vtkm_filter vtkm_io)
add_benchmark(${benchmark})
endforeach ()
target_compile_definitions(BenchmarkDeviceAdapter PUBLIC VTKm_BENCHS_RANGE_LOWER_BOUNDARY=${VTKm_BENCHS_RANGE_LOWER_BOUNDARY})
target_compile_definitions(BenchmarkDeviceAdapter PUBLIC VTKm_BENCHS_RANGE_UPPER_BOUNDARY=${VTKm_BENCHS_RANGE_UPPER_BOUNDARY})
if(TARGET vtkm_rendering)
add_benchmark(NAME BenchmarkRayTracing FILE BenchmarkRayTracing.cxx LIBS vtkm_rendering vtkm_source)
add_benchmark(NAME BenchmarkInSitu FILE BenchmarkInSitu.cxx LIBS vtkm_rendering vtkm_source vtkm_filter vtkm_io)
endif()
if(VTKm_ENABLE_PERFORMANCE_TESTING)
include("${VTKm_SOURCE_DIR}/CMake/testing/VTKmPerformanceTest.cmake")
add_benchmark_test(BenchmarkFilters

20
benchmarking/vtkm.module Normal file

@ -0,0 +1,20 @@
NAME
benchmarking
GROUPS
Benchmarking
DEPENDS
vtkm_cont
vtkm_filter_contour
vtkm_filter_entity_extraction
vtkm_filter_field_conversion
vtkm_filter_field_transform
vtkm_filter_flow
vtkm_filter_geometry_refinement
vtkm_filter_mesh_info
vtkm_filter_vector_analysis
vtkm_io
vtkm_source
OPTIONAL_DEPENDS
vtkm_rendering
vtkm_filter_extra # Hack for non-module library that should go away.
NO_TESTING

245
docs/Modules.md Normal file

@ -0,0 +1,245 @@
# Specifying modules in the VTK-m build system
The VTK-m build system comes with a module mechanism that allows a library
or other target be optionally compiled based on CMake configuration
variables. Additionally, modules can be optionally compiled based on their
dependencies. That is, a module can be turned on if a module that depends
on it wants to be compiled. Likewise, a module can be turned off if a
module that it depends on cannot be compiled.
## Module configuration
All modules have a "name" that is the same as the target created by the
module (for example, the name of a library). Every module has an associated
(advanced) CMake variable named `VTKm_MODULE_ENABLE_<name>`. For example,
the module that builds the `vtkm_filter_entity_extraction` filter has an
associated CMake variable named
`VTKm_MODULE_ENABLE_vtkm_filter_entity_extraction`. This CMake variable can
be used to control whether the module should be included in the build. It
can be set to one of the following values.
* `YES`: Always create the module. If it is not possible to create the
module, the CMake configuration fails.
* `WANT`: Create the module if possible. If it is possible to create all
modules it depends on, then this module will be created. If this is not
possible, this module will not be created, but this will not cause an
error in the configuration.
* `DONT_WANT`: Create the module only if there is a dependency that
requires it. This is useful for stripping out modules not directly
needed but required for a select list of modules desired.
* `NO`: Never create the module. Any module that depends on this module
will also not be built.
* `DEFAULT`: Does the default behavior. This is typically either `WANT`
or `DONT_WANT` depending on other configuration.
The advantage of having these multiple options is that it becomes possible
to turn off all modules except a select desired few and have the CMake
configuration automatically determine dependencies.
### Module groups
Modules can also declare themselves as part of a group. Module groups
provide a way to turn on/off the build of several related modules. For
example, there is a module group named `FiltersCommon` that contains
modules with the most commonly used filters in VTK-m.
Every module group has an associated (advanced) CMake variable named
`VTKm_GROUP_ENABLE_<name>`. For example, the `FiltersCommon` group has an
associated CMake variable named `VTKm_GROUP_ENABLE_FiltersCommon`. This
variable can be set to the same `YES`/`WANT`/`DONT_WANT`/`NO`/`DEFAULT`
values as those for the `VTKm_MODULE_ENABLE` variables described earlier.
### Default behavior
If a `VTKm_MODULE_ENABLE_*` variable is set to `DEFAULT`, then the
configuration first checks all the `VTKm_GROUP_ENABLE_*` variables
associated with the groups the module belongs to. It will use the first
value not set to `DEFAULT` that it encounters.
If all the module's group are also set to `DEFAULT` (or the module does not
belong to any groups) then the behavior is based on the
`VTKm_BUILD_ALL_LIBRARIES` CMake variable. If `VTKm_BUILD_ALL_LIBRARIES` is
`ON`, then the default behavior becomes `WANT`. Otherwise, it becomes
`DONT_WANT`.
## Specifying a module
A module is created in much the same way as a normal target is made in
CMake: Create a directory with the appropriate source material and add a
`CMakeLists.txt` file to specify how they are built. However, the main
difference is that you do _not_ link to the directory with a CMake
`add_subdirectory` command (or any other command like `include` or
`subdirs`).
Instead, you simply create a file named `vtkm.module` and place it in the
same directory with the `CMakeLists.txt` file. The VTK-m configuration will
automatically find this `vtkm.module` file, recognize the directory as
containing a module, and automatically include the associated
`CMakeLists.txt` in the build (given that the CMake configuration turns on
the module to be compiled).
Each `vtkm.module` is a simple text file that contains a list of options.
Each option is provided by giving the name of the option followed by the
arguments for that option. The following options can be defined in a
`vtkm.module` file. `NAME` is required, but the rest are optional.
* `NAME`: The name of the target created by the module.
* `GROUPS`: A list of all groups the module belongs to. If a module's
enable flag is set to `DEFAULT`, then the enable option is taken from
the groups it belongs to.
* `DEPENDS`: A list of all modules (or other libraries) on which this
module depends. Everything in this list is added as a link library to
the library created with `vtkm_library`.
* `PRIVATE_DEPENDS`: Same as `DEPENDS` except that these libraries are
added as private link libraries.
* `OPTIONAL_DEPENDS`: A list of all modules that that are not strictly
needed but will be used if available.
* `TEST_DEPENDS`: A list of all modules (or other libraries) on which the
tests for this module depends.
* `TEST_OPTIONAL_DEPENDS`: A list of all modules that the test executable
will like to if they exist, but are not necessary.
* `NO_TESTING`: Normally, a module is expected to have a subdirectory
named `testing`, which will build any necessary testing executables and
add ctest tests. If this option is given, no tests are added. (Note,
modules generally should have tests.)
A `vtkm.module` file may also have comments. Everything between a `#` and
the end of the line will be ignored.
As an example, the `vtkm_filter_entity_extraction` module (located in
`vtkm/filter/entity_extraction` has a `vtkm.module` file that looks like
the following.
``` cmake
NAME
vtkm_filter_entity_extraction
GROUPS
FiltersCommon
Filters
DEPENDS
vtkm_worklet
vtkm_filter_core
vtkm_filter_clean_grid
TEST_DEPENDS
vtkm_filter_clean_grid
vtkm_filter_entity_extraction
vtkm_source
```
## Building the module
As mentioned earlier, a VTK-m module directory has its own
`CMakeLists.txt`. There does not have to be anything particularly special
about the `CMakeLists.txt`. If the module is building a library target
(which is typical), it should use the `vtkm_library` CMake command to do so
to make sure the proper compiler flags are added.
Here is an example portion of the `CMakeLists.txt` for the
`vtkm_filter_entity_extraction` module. (Mainly, the definition of
variables containing source and header files is left out.)
``` cmake
vtkm_library(
NAME vtkm_filter_entity_extraction
HEADERS ${entity_extraction_headers}
DEVICE_SOURCES ${entity_extraction_sources_device}
USE_VTKM_JOB_POOL
)
target_link_libraries(vtkm_filter PUBLIC INTERFACE vtkm_filter_entity_extraction)
```
Note that if a library created by a module depends on the library created
by another module, it should be in the `DEPENDS` list of `vtkm.module`. For
example, the `vtkm.module` contains `vtkm_filter_clean_grid` in its
`DEPENDS` list, and that library will automatically be added as a target
link library to `vtkm_filter_entity_extraction`. You should avoid using
`target_link_libraries` to link one module to another as the modules will
not be able to guarantee that all the targets will be created correctly.
Also note that the `CMakeLists.txt` file should _not_ include its testing
directory with `add_subdirectory`. As described in the next section, the
testing directory will automatically be added, if possible. (Using
`add_subdirectory` for other subdirectories on which the module depends is
OK.)
## Module testing directory
All modules are expected to have a `testing` subdirectory. This
subdirectory should contain its own `CMakeLists.txt` that, typically,
builds a testing executable and adds the appropriate tests. (This is
usually done with the `vtkm_unit_tests` CMake function.)
However, a module should _not_ include its own `testing` directory with
`add_subdirectory`. This is because the tests for a module might have
dependencies that the module itself does not. For example, it is common for
filter tests to use a source to generate some test data. But what if the
CMake configuration has the source module turned off? Should the filter
module be turned off because the tests need the source module? No. Should
the source module be turned on just because some tests want it? No.
To resolve this issue, VTK-m modules allow for an extended set of
dependencies for the tests. This is specified with the `TEST_DEPENDS`
variable in `vtkm.module`. It will then add the test only if all the test
dependencies are met.
If the dependencies for both the module itself and the module's tests are
met, then the `testing` subdirectory of the module will be added to the
build. Like for the module itself, the `CMakeLists.txt` in the `testing`
directory should build tests just like any other CMake directory. Here is
an example `CMakeLists.txt` for the `vtkm_filter_entity_extraction` module.
``` cmake
set(unit_tests
UnitTestExternalFacesFilter.cxx
UnitTestExtractGeometryFilter.cxx
UnitTestExtractPointsFilter.cxx
UnitTestExtractStructuredFilter.cxx
UnitTestGhostCellRemove.cxx
UnitTestMaskFilter.cxx
UnitTestMaskPointsFilter.cxx
UnitTestThresholdFilter.cxx
UnitTestThresholdPointsFilter.cxx
)
set(libraries
vtkm_filter_clean_grid
vtkm_filter_entity_extraction
vtkm_source
)
vtkm_unit_tests(
SOURCES ${unit_tests}
LIBRARIES ${libraries}
USE_VTKM_JOB_POOL
)
```
## Testing if a module is being built
The easiest way to test if a module is being built (in CMake) is to check
whether the associated target exists.
``` cmake
if(TARGET vtkm_filter_entity_extraction)
# Do stuff dependent on vtkm_filter_entity_extraction library/module
endif()
```
Note that this only works in a module if the module properly depends on the
named target. It only works outside of modules if modules have already been
processed.
## Debugging modules
Because modules depend on each other, and these dependencies affect whether
a particular module will be built, it can sometimes be difficult to
understand why a particular module is or is not built. To help diagnose
problems with modules, you can turn on extra reporting with the
`VTKm_VERBOSE_MODULES` CMake variable.
When `VTKm_VERBOSE_MODULES` is set to `OFF` (the default), then the parsing
and dependency resolution of the modules is silent unless there is an
error. When `VTKm_VERBOSE_MODULES` is set to `ON`, then information about
what modules are found, which modules are built, and why they are or are
not built are added as status messages during CMake configuration.

@ -0,0 +1,16 @@
# Added modules to the build system
VTK-m libraries and other targets can now be built as modules. The
advantage of modules is that you can selectively choose which
modules/libraries will be built. This makes it easy to create a more
stripped down compile of VTK-m. For example, you might want a reduced set
of libraries to save memory or you might want to turn off certain libraries
to save compile time.
The module system will automatically determine dependencies among the
modules. It is capable of weakly turning off a module where it will still
be compiled if needed. Likewise, it is capabile of weakly turning on a
module where the build will still work if it cannot be created.
The use of modules is described in the `Modules.md` file in the `docs`
directory of the VTK-m source.

@ -13,5 +13,7 @@ project(Clipping CXX)
#Find the VTK-m package
find_package(VTKm REQUIRED QUIET)
add_executable(Clipping Clipping.cxx)
target_link_libraries(Clipping PRIVATE vtkm_filter vtkm_io)
if(TARGET vtkm_filter_contour AND TARGET vtkm_io)
add_executable(Clipping Clipping.cxx)
target_link_libraries(Clipping PRIVATE vtkm_filter_contour vtkm_io)
endif()

@ -13,8 +13,10 @@ project(ContourTree CXX)
#Find the VTK-m package
find_package(VTKm REQUIRED QUIET)
add_executable(ContourTreeMesh2D ContourTreeMesh2D.cxx)
target_link_libraries(ContourTreeMesh2D vtkm_filter)
if (TARGET vtkm_filter_scalar_topology)
add_executable(ContourTreeMesh2D ContourTreeMesh2D.cxx)
target_link_libraries(ContourTreeMesh2D vtkm_filter_core vtkm_filter_scalar_topology)
add_executable(ContourTreeMesh3D ContourTreeMesh3D.cxx)
target_link_libraries(ContourTreeMesh3D vtkm_filter)
add_executable(ContourTreeMesh3D ContourTreeMesh3D.cxx)
target_link_libraries(ContourTreeMesh3D vtkm_filter_core vtkm_filter_scalar_topology)
endif()

@ -55,11 +55,16 @@ cmake_minimum_required(VERSION 3.12...3.15 FATAL_ERROR)
# Find the VTK-m package
find_package(VTKm REQUIRED QUIET)
if(NOT TARGET vtkm_io OR NOT TARGET vtkm_filter_scalar_topology)
# Libraries needed are not built.
return()
endif()
####################################
# Serial
####################################
add_executable(ContourTree_Augmented ContourTreeApp.cxx)
target_link_libraries(ContourTree_Augmented vtkm_filter vtkm_io)
target_link_libraries(ContourTree_Augmented vtkm_filter_scalar_topology vtkm_io)
vtkm_add_target_information(ContourTree_Augmented
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES ContourTreeApp.cxx)
@ -79,7 +84,7 @@ endif()
####################################
if (VTKm_ENABLE_MPI)
add_executable(ContourTree_Augmented_MPI ContourTreeApp.cxx)
target_link_libraries(ContourTree_Augmented_MPI vtkm_filter vtkm_io MPI::MPI_CXX)
target_link_libraries(ContourTree_Augmented_MPI vtkm_filter_scalar_topology vtkm_io MPI::MPI_CXX)
vtkm_add_target_information(ContourTree_Augmented_MPI
MODIFY_CUDA_FLAGS
DEVICE_SOURCES ContourTreeApp.cxx)

@ -58,9 +58,9 @@ find_package(VTKm REQUIRED QUIET)
####################################
# MPI
####################################
if (VTKm_ENABLE_MPI)
if (VTKm_ENABLE_MPI AND TARGET vtkm_filter_scalar_topology AND TARGET vtkm_io)
add_executable(ContourTree_Distributed ContourTreeApp.cxx)
target_link_libraries(ContourTree_Distributed vtkm_filter vtkm_io MPI::MPI_CXX)
target_link_libraries(ContourTree_Distributed vtkm_filter_scalar_topology vtkm_io MPI::MPI_CXX)
vtkm_add_target_information(ContourTree_Distributed
MODIFY_CUDA_FLAGS
DEVICE_SOURCES ContourTreeApp.cxx)
@ -78,7 +78,7 @@ if (VTKm_ENABLE_MPI)
endif()
add_executable(TreeCompiler TreeCompilerApp.cxx)
target_link_libraries(TreeCompiler vtkm_filter)
target_link_libraries(TreeCompiler vtkm_filter_core)
vtkm_add_target_information(TreeCompiler DROP_UNUSED_SYMBOLS)
add_executable(BranchCompiler BranchCompilerApp.cxx)

@ -15,8 +15,8 @@ find_package(VTKm REQUIRED QUIET)
add_executable(CosmoCenterFinder CosmoCenterFinder.cxx)
add_executable(CosmoHaloFinder CosmoHaloFinder.cxx)
target_link_libraries(CosmoCenterFinder PRIVATE vtkm_filter)
target_link_libraries(CosmoHaloFinder PRIVATE vtkm_filter)
target_link_libraries(CosmoCenterFinder PRIVATE vtkm_filter_core)
target_link_libraries(CosmoHaloFinder PRIVATE vtkm_filter_core)
vtkm_add_target_information(CosmoCenterFinder CosmoHaloFinder
DROP_UNUSED_SYMBOLS

@ -13,7 +13,7 @@ project(VTKmDemo CXX)
#Find the VTK-m package
find_package(VTKm REQUIRED QUIET)
if(TARGET vtkm_rendering)
if(TARGET vtkm_rendering AND TARGET vtkm_filter_contour AND TARGET vtkm_source)
add_executable(Demo Demo.cxx)
target_link_libraries(Demo PRIVATE vtkm_filter vtkm_rendering vtkm_source)
target_link_libraries(Demo PRIVATE vtkm_rendering vtkm_filter_contour vtkm_source)
endif()

@ -13,9 +13,12 @@ project(HelloWorklet CXX)
#Find the VTK-m package
find_package(VTKm REQUIRED QUIET)
add_executable(HelloWorklet HelloWorklet.cxx)
target_link_libraries(HelloWorklet PRIVATE vtkm_filter vtkm_io)
if(TARGET vtkm_io)
add_executable(HelloWorklet HelloWorklet.cxx)
target_link_libraries(HelloWorklet PRIVATE vtkm_filter_core vtkm_io)
vtkm_add_target_information(HelloWorklet
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES HelloWorklet.cxx)
vtkm_add_target_information(HelloWorklet
DROP_UNUSED_SYMBOLS
MODIFY_CUDA_FLAGS
DEVICE_SOURCES HelloWorklet.cxx)
endif()

@ -12,9 +12,12 @@ project(Histogram CXX)
#Find the VTK-m package
find_package(VTKm REQUIRED QUIET)
if (VTKm_ENABLE_MPI)
if (VTKm_ENABLE_MPI AND vtkm_filter_density_estimate)
# TODO: this example desperately needs to be updated. The histogram filter has
# improved immensely since this has originally been written, and the code can
# be simplified a lot, which will make it more illustrative of using VTK-m.
add_executable(Histogram Histogram.cxx HistogramMPI.h HistogramMPI.cxx)
target_link_libraries(Histogram PRIVATE vtkm_filter MPI::MPI_CXX)
target_link_libraries(Histogram PRIVATE vtkm_filter_density_estimate MPI::MPI_CXX)
vtkm_add_target_information(Histogram
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES HistogramMPI.cxx)

@ -13,9 +13,12 @@ project(IsingModel CXX)
#Find the VTK-m package
find_package(VTKm REQUIRED QUIET)
add_executable(Ising Ising.cxx)
target_link_libraries(Ising PRIVATE vtkm_worklet vtkm_io vtkm_rendering)
if(TARGET vtkm_rendering)
add_executable(Ising Ising.cxx)
target_link_libraries(Ising PRIVATE vtkm_worklet vtkm_rendering)
vtkm_add_target_information(Ising
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES Ising.cxx)
vtkm_add_target_information(Ising
DROP_UNUSED_SYMBOLS
MODIFY_CUDA_FLAGS
DEVICE_SOURCES Ising.cxx)
endif()

@ -12,21 +12,7 @@ cmake_minimum_required(VERSION 3.12...3.15 FATAL_ERROR)
#Find the VTK-m package
find_package(VTKm REQUIRED QUIET)
if ((TARGET vtkm::cuda) OR (TARGET vtkm::kokkos_cuda))
# CUDA architecture has a limited amount of memory available for constants. The CUDA
# compiler uses this space to hold constants for some optimizations. However, for large
# kernels, the number of constants needed might be larger than the constant space
# available. For these conditions, you have to disable this form of optimization with
# the -Xptxas --disable-optimizer-constants flags.
# TODO: Find a more elegant way to do this. Either figure out a way around this problem
# or add more general flags to vtkm_library/vtkm_unit_tests for sources with "large" kernels.
set_source_files_properties(lagrangian.cxx PROPERTIES
COMPILE_OPTIONS "-Xptxas;--disable-optimizer-constants"
)
if(TARGET vtkm_filter_flow)
add_executable(Lagrangian lagrangian.cxx ABCfield.h)
target_link_libraries(Lagrangian PRIVATE vtkm_filter_flow)
endif()
add_executable(Lagrangian lagrangian.cxx ABCfield.h)
target_link_libraries(Lagrangian PRIVATE vtkm_filter)
vtkm_add_target_information(Lagrangian
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES lagrangian.cxx)

@ -14,14 +14,13 @@
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DataSetBuilderRectilinear.h>
#include <vtkm/cont/DataSetBuilderUniform.h>
#include <vtkm/cont/Initialize.h>
#include <vtkm/filter/flow/Lagrangian.h>
using namespace std;
vtkm::cont::DataSet make3DRectilinearDataSet(double time)
vtkm::cont::DataSet make3DUniformDataSet(double time)
{
ABCfield field;
@ -86,7 +85,7 @@ int main(int argc, char** argv)
lagrangianFilter.SetWriteFrequency(10);
for (int i = 0; i < 100; i++)
{
vtkm::cont::DataSet inputData = make3DRectilinearDataSet((double)i * stepSize);
vtkm::cont::DataSet inputData = make3DUniformDataSet((double)i * stepSize);
lagrangianFilter.SetActiveField("velocity");
vtkm::cont::DataSet extractedBasisFlows = lagrangianFilter.Execute(inputData);
}

@ -12,9 +12,12 @@ project(LogisticMap CXX)
find_package(VTKm REQUIRED QUIET)
add_executable(LogisticMap LogisticMap.cxx)
target_link_libraries(LogisticMap PRIVATE vtkm_io)
if(TARGET vtkm_io)
add_executable(LogisticMap LogisticMap.cxx)
target_link_libraries(LogisticMap PRIVATE vtkm_io)
vtkm_add_target_information(LogisticMap
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES LogisticMap.cxx)
vtkm_add_target_information(LogisticMap
DROP_UNUSED_SYMBOLS
MODIFY_CUDA_FLAGS
DEVICE_SOURCES LogisticMap.cxx)
endif()

@ -25,5 +25,7 @@ project(MeshQuality CXX)
#Find the VTK-m package
find_package(VTKm REQUIRED QUIET)
add_executable(MeshQuality MeshQuality.cxx)
target_link_libraries(MeshQuality PRIVATE vtkm_filter vtkm_io)
if(TARGET vtkm_filter_mesh_info AND TARGET vtkm_io)
add_executable(MeshQuality MeshQuality.cxx)
target_link_libraries(MeshQuality PRIVATE vtkm_filter_mesh_info vtkm_io)
endif()

@ -26,8 +26,11 @@ set(srcs
IOGenerator.cxx
)
add_executable(MultiBackend ${srcs} ${headers})
target_link_libraries(MultiBackend PRIVATE vtkm_filter Threads::Threads)
vtkm_add_target_information(MultiBackend
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES ${srcs})
if(TARGET vtkm_filter_vector_analysis)
add_executable(MultiBackend ${srcs} ${headers})
target_link_libraries(MultiBackend PRIVATE vtkm_filter_vector_analysis Threads::Threads)
vtkm_add_target_information(MultiBackend
DROP_UNUSED_SYMBOLS
MODIFY_CUDA_FLAGS
DEVICE_SOURCES ${srcs})
endif()

@ -13,5 +13,7 @@ project(Oscillator CXX)
#Find the VTK-m package
find_package(VTKm REQUIRED QUIET)
add_executable(Oscillator Oscillator.cxx)
target_link_libraries(Oscillator PRIVATE vtkm_source)
if(TARGET vtkm_source)
add_executable(Oscillator Oscillator.cxx)
target_link_libraries(Oscillator PRIVATE vtkm_source)
endif()

@ -13,5 +13,7 @@ project(ParticleAdvection CXX)
#Find the VTK-m package
find_package(VTKm REQUIRED QUIET)
add_executable(Particle_Advection ParticleAdvection.cxx)
target_link_libraries(Particle_Advection PRIVATE vtkm_filter_flow vtkm_io)
if(TARGET vtkm_filter_flow AND TARGET vtkm_io)
add_executable(Particle_Advection ParticleAdvection.cxx)
target_link_libraries(Particle_Advection PRIVATE vtkm_filter_flow vtkm_io)
endif()

@ -11,10 +11,17 @@ cmake_minimum_required(VERSION 3.12...3.15 FATAL_ERROR)
project(PolyLineArchimedeanHelix CXX)
find_package(VTKm REQUIRED QUIET)
if (VTKm_ENABLE_RENDERING)
add_executable(PolyLineArchimedeanHelix PolyLineArchimedeanHelix.cxx)
target_link_libraries(PolyLineArchimedeanHelix PRIVATE vtkm_filter vtkm_rendering)
vtkm_add_target_information(PolyLineArchimedeanHelix
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES PolyLineArchimedeanHelix.cxx)
if (TARGET vtkm_rendering)
# TODO: This example should be changed from using the Tube worklet to using
# the Tube filter (in the vtkm_filter_geometry_refinement library). Then
# compiling it would no longer require a device compiler and the example
# would generally be simpler.
add_executable(PolyLineArchimedeanHelix PolyLineArchimedeanHelix.cxx)
target_link_libraries(PolyLineArchimedeanHelix PRIVATE vtkm_rendering)
vtkm_add_target_information(PolyLineArchimedeanHelix
DROP_UNUSED_SYMBOLS
MODIFY_CUDA_FLAGS
DEVICE_SOURCES PolyLineArchimedeanHelix.cxx
)
endif()

@ -12,11 +12,16 @@ project(RedistributePoints CXX)
#Find the VTK-m package
find_package(VTKm REQUIRED QUIET)
add_executable(RedistributePoints RedistributePoints.cxx RedistributePoints.h main.cxx)
target_link_libraries(RedistributePoints PRIVATE vtkm_filter vtkm_io)
vtkm_add_target_information(RedistributePoints
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES RedistributePoints.cxx)
set_property(TARGET RedistributePoints PROPERTY CUDA_VISIBILITY_PRESET "hidden")
set_property(TARGET RedistributePoints PROPERTY CXX_VISIBILITY_PRESET "hidden")
if(TARGET vtkm_io AND TARGET vtkm_filter_entity_extraction)
add_executable(RedistributePoints RedistributePoints.cxx RedistributePoints.h main.cxx)
target_link_libraries(RedistributePoints PRIVATE vtkm_io vtkm_filter_entity_extraction)
vtkm_add_target_information(RedistributePoints
DROP_UNUSED_SYMBOLS
MODIFY_CUDA_FLAGS
DEVICE_SOURCES RedistributePoints.cxx
)
set_property(TARGET RedistributePoints PROPERTY CUDA_VISIBILITY_PRESET "hidden")
set_property(TARGET RedistributePoints PROPERTY CXX_VISIBILITY_PRESET "hidden")
endif()

@ -14,12 +14,12 @@ include(CTest)
find_package(VTKm REQUIRED)
add_executable(smoke_test smoke_test.cxx)
target_link_libraries(smoke_test PRIVATE vtkm_source)
if(TARGET vtkm_source)
add_executable(smoke_test smoke_test.cxx)
target_link_libraries(smoke_test PRIVATE vtkm_source)
vtkm_add_target_information(smoke_test DEVICE_SOURCES smoke_test.cxx)
# Only add this test when this an standalone project
if (PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
add_test(NAME SmokeTestInternal COMMAND ${CMAKE_BINARY_DIR}/smoke_test)
# Only add this test when this a standalone project
if (PROJECT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
add_test(NAME SmokeTestInternal COMMAND ${CMAKE_BINARY_DIR}/smoke_test)
endif()
endif()

@ -13,7 +13,7 @@ project(StreamlineMPI CXX)
#Find the VTK-m package
find_package(VTKm REQUIRED QUIET)
if (VTKm_ENABLE_MPI)
if (VTKm_ENABLE_MPI AND TARGET vtkm_io AND TARGET vtkm_filter_flow)
add_executable(StreamlineMPI StreamlineMPI.cxx)
target_compile_definitions(StreamlineMPI PRIVATE "MPI_ENABLED")
target_link_libraries(StreamlineMPI PRIVATE vtkm_filter_flow vtkm_io MPI::MPI_CXX)

@ -15,8 +15,10 @@ project(TemporalAdvection CXX)
#Find the VTK-m package
find_package(VTKm REQUIRED QUIET)
add_executable(Temporal_Advection TemporalAdvection.cxx)
vtkm_add_target_information(Temporal_Advection
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES TemporalAdvection.cxx)
target_link_libraries(Temporal_Advection PRIVATE vtkm_filter vtkm_io)
if(TARGET vtkm_filter_flow AND TARGET vtkm_io)
add_executable(Temporal_Advection TemporalAdvection.cxx)
vtkm_add_target_information(Temporal_Advection
DROP_UNUSED_SYMBOLS MODIFY_CUDA_FLAGS
DEVICE_SOURCES TemporalAdvection.cxx)
target_link_libraries(Temporal_Advection PRIVATE vtkm_filter_flow vtkm_io)
endif()

@ -13,8 +13,10 @@ project(Tetrahedra CXX)
#Find the VTK-m package
find_package(VTKm REQUIRED QUIET)
add_executable(Tetrahedralize Tetrahedralize.cxx)
target_link_libraries(Tetrahedralize PRIVATE vtkm_filter vtkm_io)
if(TARGET vtkm_filter_geometry_refinement AND TARGET vtkm_io)
add_executable(Tetrahedralize Tetrahedralize.cxx)
target_link_libraries(Tetrahedralize PRIVATE vtkm_filter_geometry_refinement vtkm_io)
add_executable(Triangulate Triangulate.cxx)
target_link_libraries(Triangulate PRIVATE vtkm_filter vtkm_io)
add_executable(Triangulate Triangulate.cxx)
target_link_libraries(Triangulate PRIVATE vtkm_filter_geometry_refinement vtkm_io)
endif()

@ -79,46 +79,11 @@ vtkm_declare_headers(
${template_sources}
)
#-----------------------------------------------------------------------------
#first add all the components vtkm that are shared between control and exec
add_subdirectory(thirdparty/diy)
add_subdirectory(thirdparty/lodepng)
if(VTKm_ENABLE_LOGGING)
add_subdirectory(thirdparty/loguru)
endif()
add_subdirectory(thirdparty/optionparser)
add_subdirectory(thirdparty/lcl)
# Declare testing headers to install. (Needs to be special because they are in a different dir.)
set(testing_headers
testing/Testing.h
testing/VecTraitsTests.h
)
vtkm_install_headers(${kit_dir}/testing ${testing_headers})
if(VTKm_ENABLE_TESTING_LIBRARY)
add_subdirectory(testing)
endif()
add_subdirectory(internal)
#-----------------------------------------------------------------------------
#add the control and exec folders
add_subdirectory(cont)
add_subdirectory(exec)
#-----------------------------------------------------------------------------
#add the worklet folder
add_subdirectory(worklet)
#-----------------------------------------------------------------------------
#add the filter folder
add_subdirectory(filter)
#-----------------------------------------------------------------------------
# Build rendering
add_subdirectory(rendering)
add_subdirectory(interop)
#-----------------------------------------------------------------------------
#add the io folder
add_subdirectory(io)
#add the source folder
add_subdirectory(source)
#add Pseudo Random Number Generator folder
add_subdirectory(random)

@ -189,7 +189,7 @@ if(VTKm_ENABLE_TESTING_LIBRARY)
# deprecated behavior expects to only need to include vtkm_cont. As a workaround, add the code
# to vtkm_cont for now. This should probably be changed back to be in vtkm_cont_testing for the
# 2.0 release.
testing/MakeTestDataSet.cxx
testlib/MakeTestDataSet.cxx
)
endif()
@ -312,11 +312,6 @@ vtkm_library( NAME vtkm_cont
add_subdirectory(internal)
add_subdirectory(arg)
add_subdirectory(serial)
add_subdirectory(tbb)
add_subdirectory(openmp)
add_subdirectory(cuda)
add_subdirectory(kokkos)
set(backends )
if(TARGET vtkm::tbb)
@ -334,12 +329,3 @@ endif()
target_link_libraries(vtkm_cont PUBLIC vtkm_compiler_flags ${backends})
target_link_libraries(vtkm_cont PUBLIC Threads::Threads)
target_link_libraries(vtkm_cont PUBLIC vtkm_optionparser vtkm_diy vtkm_lcl)
if(TARGET vtkm_loguru)
target_link_libraries(vtkm_cont PRIVATE vtkm_loguru)
endif()
#-----------------------------------------------------------------------------
if(VTKm_ENABLE_TESTING_LIBRARY)
add_subdirectory(testing)
endif()

@ -39,9 +39,3 @@ set(headers
)
vtkm_declare_headers(${headers})
#-----------------------------------------------------------------------------
if (VTKm_ENABLE_TESTING)
add_subdirectory(testing)
endif ()

@ -1,28 +0,0 @@
##============================================================================
## 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.
##============================================================================
set(unit_tests
UnitTestControlSignatureTag.cxx
UnitTestTypeCheckArray.cxx
UnitTestTypeCheckCellSet.cxx
UnitTestTypeCheckExecObject.cxx
UnitTestTypeCheckKeys.cxx
)
set(unit_tests_device
UnitTestTransportArrayIn.cxx
UnitTestTransportArrayInOut.cxx
UnitTestTransportArrayOut.cxx
UnitTestTransportCellSetIn.cxx
UnitTestTransportExecObject.cxx
UnitTestTransportWholeArray.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests} DEVICE_SOURCES ${unit_tests_device})

@ -17,9 +17,3 @@ set(headers
#-----------------------------------------------------------------------------
add_subdirectory(internal)
vtkm_declare_headers(${headers})
#-----------------------------------------------------------------------------
if (TARGET vtkm::cuda AND VTKm_ENABLE_TESTING)
add_subdirectory(testing)
endif()

@ -0,0 +1,9 @@
NAME
vtkm_cont_cuda
GROUPS
Core
DEPENDS
vtkm_cont
TEST_DEPENDS
vtkm_worklet
vtkm::cuda

@ -59,7 +59,3 @@ vtkm_declare_headers(${headers})
# They are in a separate directory to highlight which objects are
# internal and which are part of the external interface.
#add_custom_target(vtkmContInternal ALL DEPENDS vtkmCont)
if (VTKm_ENABLE_TESTING)
add_subdirectory(testing)
endif ()

@ -1,18 +0,0 @@
##============================================================================
## 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.
##============================================================================
set(unit_tests
UnitTestArrayPortalFromIterators.cxx
UnitTestBuffer.cxx
UnitTestRuntimeConfigurationOptions.cxx
UnitTestIteratorFromArrayPortal.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests} DEFINES VTKM_NO_ERROR_ON_MIXED_CUDA_CXX_TAG)

@ -15,8 +15,3 @@ set(headers
#-----------------------------------------------------------------------------
add_subdirectory(internal)
vtkm_declare_headers(${headers})
#-----------------------------------------------------------------------------
if (TARGET vtkm::kokkos AND VTKm_ENABLE_TESTING)
add_subdirectory(testing)
endif()

@ -0,0 +1,9 @@
NAME
vtkm_cont_kokkos
GROUPS
Core
DEPENDS
vtkm_cont
TEST_DEPENDS
vtkm_worklet
vtkm::kokkos

@ -15,8 +15,3 @@ set(headers
add_subdirectory(internal)
vtkm_declare_headers(${headers})
#-----------------------------------------------------------------------------
if (TARGET vtkm::openmp AND VTKm_ENABLE_TESTING)
add_subdirectory(testing)
endif()

@ -0,0 +1,9 @@
NAME
vtkm_cont_openmp
GROUPS
Core
DEPENDS
vtkm_cont
TEST_DEPENDS
vtkm_worklet
vtkm::openmp

@ -15,8 +15,3 @@ set(headers
add_subdirectory(internal)
vtkm_declare_headers(${headers})
#-----------------------------------------------------------------------------
if (VTKm_ENABLE_TESTING)
add_subdirectory(testing)
endif ()

@ -0,0 +1,8 @@
NAME
vtkm_cont_serial
GROUPS
Core
DEPENDS
vtkm_cont
TEST_DEPENDS
vtkm_worklet

@ -15,8 +15,3 @@ set(headers
add_subdirectory(internal)
vtkm_declare_headers(${headers})
#-----------------------------------------------------------------------------
if (TARGET vtkm::tbb AND VTKm_ENABLE_TESTING)
add_subdirectory(testing)
endif()

@ -0,0 +1,9 @@
NAME
vtkm_cont_tbb
GROUPS
Core
DEPENDS
vtkm_cont
TEST_DEPENDS
vtkm_worklet
vtkm::tbb

@ -9,9 +9,6 @@
##============================================================================
set(headers
ExplicitTestData.h
MakeTestDataSet.h
Testing.h
TestingDeviceAdapter.h
TestingRuntimeDeviceConfiguration.h
TestingSerialization.h
@ -31,8 +28,11 @@ set(unit_tests
UnitTestArrayHandleThreadSafety.cxx
UnitTestArrayHandleUniformPointCoordinates.cxx
UnitTestArrayHandleVirtual.cxx
UnitTestArrayPortalFromIterators.cxx
UnitTestArrayPortalToIterators.cxx
UnitTestBuffer.cxx
UnitTestComputeRange.cxx
UnitTestControlSignatureTag.cxx
UnitTestContTesting.cxx
UnitTestDataSetBuilderCurvilinear.cxx
UnitTestDataSetBuilderExplicit.cxx
@ -48,11 +48,13 @@ set(unit_tests
UnitTestError.cxx
UnitTestFieldRangeCompute.cxx
UnitTestInitialize.cxx
UnitTestIteratorFromArrayPortal.cxx
UnitTestLateDeallocate.cxx
UnitTestLogging.cxx
UnitTestMergePartitionedDataSet.cxx
UnitTestMoveConstructors.cxx
UnitTestPartitionedDataSet.cxx
UnitTestRuntimeConfigurationOptions.cxx
UnitTestRuntimeDeviceInformation.cxx
UnitTestRuntimeDeviceNames.cxx
UnitTestScopedRuntimeDeviceTracker.cxx
@ -61,6 +63,10 @@ set(unit_tests
UnitTestTimer.cxx
UnitTestToken.cxx
UnitTestTryExecute.cxx
UnitTestTypeCheckArray.cxx
UnitTestTypeCheckCellSet.cxx
UnitTestTypeCheckExecObject.cxx
UnitTestTypeCheckKeys.cxx
UnitTestUnknownArrayHandle.cxx
UnitTestUnknownCellSet.cxx
UnitTestVariantArrayHandle.cxx
@ -98,7 +104,6 @@ set(unit_tests_device
UnitTestCellLocatorUniformGrid.cxx
UnitTestCellSet.cxx
UnitTestCellSetExplicit.cxx
UnitTestCellSetExtrude.cxx
UnitTestCellSetPermutation.cxx
UnitTestColorTable.cxx
UnitTestDataSetPermutation.cxx
@ -107,7 +112,18 @@ set(unit_tests_device
UnitTestImplicitFunction.cxx
UnitTestParticleArrayCopy.cxx
UnitTestPointLocatorSparseGrid.cxx
UnitTestTransportArrayIn.cxx
UnitTestTransportArrayInOut.cxx
UnitTestTransportArrayOut.cxx
UnitTestTransportCellSetIn.cxx
UnitTestTransportExecObject.cxx
UnitTestTransportWholeArray.cxx
)
if(TARGET vtkm_filter_field_conversion)
list(APPEND unit_tests_device
UnitTestCellSetExtrude.cxx
)
endif()
if (NOT VTKm_NO_DEPRECATED_VIRTUAL)
list(APPEND unit_tests_device
@ -115,31 +131,13 @@ if (NOT VTKm_NO_DEPRECATED_VIRTUAL)
)
endif()
set(library_sources
TestEqualArrayHandles.cxx
Testing.cxx
)
set(library_sources_device
)
vtkm_library(
NAME vtkm_cont_testing
SOURCES ${library_sources}
DEVICE_SOURCES ${library_sources_device}
HEADERS ${headers}
)
target_link_libraries(vtkm_cont_testing PUBLIC vtkm_cont vtkm_worklet)
if(VTKm_ENABLE_TESTING)
vtkm_unit_tests(SOURCES ${unit_tests} DEVICE_SOURCES ${unit_tests_device})
vtkm_unit_tests(SOURCES ${unit_tests} DEVICE_SOURCES ${unit_tests_device})
#add distributed tests i.e.test to run with MPI
#if MPI is enabled.
set(mpi_unit_tests
UnitTestFieldRangeGlobalCompute.cxx
UnitTestSerializationArrayHandle.cxx
UnitTestSerializationDataSet.cxx
)
vtkm_unit_tests(MPI SOURCES ${mpi_unit_tests})
endif()
set(mpi_unit_tests
UnitTestFieldRangeGlobalCompute.cxx
UnitTestSerializationArrayHandle.cxx
UnitTestSerializationDataSet.cxx
)
vtkm_unit_tests(MPI SOURCES ${mpi_unit_tests})

@ -24,7 +24,11 @@
#include <vtkm/cont/UncertainCellSet.h>
#include <vtkm/cont/UnknownArrayHandle.h>
#include <vtkm/cont/testing/vtkm_cont_testing_export.h>
// Because the testing directory is reserved for test executables and not
// libraries, the vtkm_cont_testing module has to put this file in
// vtkm/cont/testlib instead of vtkm/cont/testing where you normally would
// expect it.
#include <vtkm/cont/testlib/vtkm_cont_testing_export.h>
#include <sstream>
#include <vtkm/thirdparty/diy/diy.h>

@ -0,0 +1,32 @@
##============================================================================
## 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.
##============================================================================
# Headers, which are used by tests all over VTK-m, are expected to be in the
# testing directory where tests are located. We could move things around so
# that this module is built in the testing directory and the tests are created
# somewhere else, which would also be confusing to developers trying to add
# tests. This seems like the least confusing option.
set(testing_library_headers
../testing/ExplicitTestData.h
../testing/MakeTestDataSet.h
../testing/Testing.h
)
set(testing_library_sources
# MakeTestDataSet.cxx Currently in vtkm_cont. Should be moved to testlib in VTK-m 2.0
TestEqualArrayHandles.cxx
Testing.cxx
)
vtkm_library(
NAME vtkm_cont_testing
SOURCES ${testing_library_sources}
HEADERS ${testing_library_headers}
)

@ -0,0 +1,7 @@
NAME
vtkm_cont_testing
DEPENDS
vtkm_cont
GROUPS
Testing
NO_TESTING

12
vtkm/cont/vtkm.module Normal file

@ -0,0 +1,12 @@
NAME
vtkm_cont
GROUPS
Core
DEPENDS
vtkm_optionparser
vtkm_diy
vtkm_lcl
OPTIONAL_DEPENDS
vtkm_loguru
TEST_OPTIONAL_DEPENDS
vtkm_filter_field_conversion

@ -53,16 +53,3 @@ add_subdirectory(arg)
vtkm_declare_headers(${headers}
${header_impls}
)
#-----------------------------------------------------------------------------
add_subdirectory(serial)
add_subdirectory(tbb)
add_subdirectory(openmp)
add_subdirectory(cuda)
add_subdirectory(kokkos)
#-----------------------------------------------------------------------------
if (VTKm_ENABLE_TESTING)
add_subdirectory(testing)
endif ()

@ -46,9 +46,3 @@ set(headers
)
vtkm_declare_headers(${headers})
#-----------------------------------------------------------------------------
if (VTKm_ENABLE_TESTING)
add_subdirectory(testing)
endif ()

@ -1,28 +0,0 @@
##============================================================================
## 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.
##============================================================================
set(headers
ThreadIndicesTesting.h
)
vtkm_declare_headers(${headers})
set(unit_tests
UnitTestExecutionSignatureTag.cxx
UnitTestFetchArrayDirectIn.cxx
UnitTestFetchArrayDirectIn3d.cxx
UnitTestFetchArrayDirectInOut.cxx
UnitTestFetchArrayDirectOut.cxx
UnitTestFetchArrayNeighborhoodIn.cxx
UnitTestFetchArrayTopologyMapIn.cxx
UnitTestFetchExecObject.cxx
UnitTestFetchWorkIndex.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests})

@ -23,8 +23,3 @@ vtkm_declare_headers(${headers})
set_source_files_properties(ThrustPatches.h
PROPERTIES VTKm_CANT_BE_HEADER_TESTED TRUE)
#-----------------------------------------------------------------------------
if (TARGET vtkm::cuda AND VTKm_ENABLE_TESTING)
add_subdirectory(testing)
endif()

@ -0,0 +1,8 @@
NAME
vtkm_exec_cuda
GROUPS
Core
DEPENDS
vtkm_exec
TEST_DEPENDS
vtkm::cuda

@ -21,7 +21,3 @@ set(headers
vtkm_declare_headers(${headers})
vtkm_pyexpander_generated_file(WorkletInvokeFunctorDetail.h)
if (VTKm_ENABLE_TESTING)
add_subdirectory(testing)
endif ()

@ -1,23 +0,0 @@
##============================================================================
## 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.
##============================================================================
set(headers
TestingTaskTiling.h
)
vtkm_declare_headers(${headers})
set(unit_tests
UnitTestErrorMessageBuffer.cxx
UnitTestTaskSingular.cxx
UnitTestVariant.cxx
UnitTestWorkletInvokeFunctor.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests})

@ -0,0 +1,7 @@
NAME
vtkm_exec_kokkos
GROUPS
Core
DEPENDS
vtkm_exec
NO_TESTING

@ -13,8 +13,3 @@ set(headers
)
vtkm_declare_headers(${headers})
#-----------------------------------------------------------------------------
if (VTKm_ENABLE_OPENMP AND VTKm_ENABLE_TESTING)
add_subdirectory(testing)
endif()

@ -10,7 +10,7 @@
#include <vtkm/testing/Testing.h>
#include <vtkm/cont/openmp/DeviceAdapterOpenMP.h>
#include <vtkm/exec/internal/testing/TestingTaskTiling.h>
#include <vtkm/exec/testing/TestingTaskTiling.h>
int UnitTestTaskTilingOpenMP(int argc, char* argv[])
{

@ -0,0 +1,8 @@
NAME
vtkm_exec_openmp
GROUPS
Core
DEPENDS
vtkm_exec
TEST_DEPENDS
vtkm::openmp

@ -13,8 +13,3 @@ set(headers
)
vtkm_declare_headers(${headers})
#-----------------------------------------------------------------------------
if (VTKm_ENABLE_TESTING)
add_subdirectory(testing)
endif ()

@ -10,7 +10,7 @@
#include <vtkm/testing/Testing.h>
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
#include <vtkm/exec/internal/testing/TestingTaskTiling.h>
#include <vtkm/exec/testing/TestingTaskTiling.h>
int UnitTestTaskTilingSerial(int argc, char* argv[])
{

@ -0,0 +1,6 @@
NAME
vtkm_exec_serial
GROUPS
Core
DEPENDS
vtkm_exec

@ -13,8 +13,3 @@ set(headers
)
vtkm_declare_headers(${headers})
#-----------------------------------------------------------------------------
if (TARGET vtkm::tbb AND VTKm_ENABLE_TESTING)
add_subdirectory(testing)
endif()

@ -10,7 +10,7 @@
#include <vtkm/testing/Testing.h>
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
#include <vtkm/exec/internal/testing/TestingTaskTiling.h>
#include <vtkm/exec/testing/TestingTaskTiling.h>
int UnitTestTaskTilingTBB(int argc, char* argv[])
{

@ -0,0 +1,8 @@
NAME
vtkm_exec_tbb
GROUPS
Core
DEPENDS
vtkm_exec
TEST_DEPENDS
vtkm::tbb

@ -8,10 +8,30 @@
## PURPOSE. See the above copyright notice for more information.
##============================================================================
set(headers
TestingTaskTiling.h
ThreadIndicesTesting.h
)
vtkm_declare_headers(${headers})
set(unit_tests
UnitTestCellDerivative.cxx
UnitTestCellEdgeFace.cxx
UnitTestCellInterpolate.cxx
UnitTestErrorMessageBuffer.cxx
UnitTestExecutionSignatureTag.cxx
UnitTestFetchArrayDirectIn.cxx
UnitTestFetchArrayDirectIn3d.cxx
UnitTestFetchArrayDirectInOut.cxx
UnitTestFetchArrayDirectOut.cxx
UnitTestFetchArrayNeighborhoodIn.cxx
UnitTestFetchArrayTopologyMapIn.cxx
UnitTestFetchExecObject.cxx
UnitTestFetchWorkIndex.cxx
UnitTestParametricCoordinates.cxx
UnitTestTaskSingular.cxx
UnitTestVariant.cxx
UnitTestWorkletInvokeFunctor.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests})

Some files were not shown because too many files have changed in this diff Show More