Enable changing policy used for library compiles

Previously, the PolicyDefault used to compile all the filters was hard-
coded. The problem was that if any external project that depends on VTK-
m needs a different policy, it had to recompile everything in its own
translation units with a custom policy.

This change allows an external project provide a simple header file that
changes the type lists used in the default policy. That allows VTK-m to
compile the filters exactly as specified by the external project.
This commit is contained in:
Kenneth Moreland 2020-03-17 17:22:35 -06:00
parent 76f870150b
commit dc112b5169
19 changed files with 320 additions and 46 deletions

@ -0,0 +1,53 @@
# Configurable default types
Because VTK-m compiles efficient code for accelerator architectures, it
often has to compile for static types. This means that dynamic types often
have to be determined at runtime and converted to static types. This is the
reason for the `CastAndCall` architecture in VTK-m.
For this `CastAndCall` to work, there has to be a finite set of static
types to try at runtime. If you don't compile in the types you need, you
will get runtime errors. However, the more types you compile in, the longer
the compile time and executable size. Thus, getting the types right is
important.
The "right" types to use can change depending on the application using
VTK-m. For example, when VTK links in VTK-m, it needs to support lots of
types and can sacrifice the compile times to do so. However, if using VTK-m
in situ with a fortran simulation, space and time are critical and you
might only need to worry about double SoA arrays.
Thus, it is important to customize what types VTK-m uses based on the
application. This leads to the oxymoronic phrase of configuring the default
types used by VTK-m.
This is being implemented by providing VTK-m with a header file that
defines the default types. The header file provided to VTK-m should define
one or more of the following preprocessor macros:
* `VTKM_DEFAULT_TYPE_LIST` - a `vtkm::List` of value types for fields that
filters should directly operate on (where applicable).
* `VTKM_DEFAULT_STORAGE_LIST` - a `vtkm::List` of storage tags for fields
that filters should directly operate on.
* `VTKM_DEFAULT_CELL_SET_LIST_STRUCTURED` - a `vtkm::List` of
`vtkm::cont::CellSet` types that filters should operate on as a
strutured cell set.
* `VTKM_DEFAULT_CELL_SET_LIST_UNSTRUCTURED` - a `vtkm::List` of
`vtkm::cont::CellSet` types that filters should operate on as an
unstrutured cell set.
* `VTKM_DEFAULT_CELL_SET_LIST` - a `vtkm::List` of `vtkm::cont::CellSet`
types that filters should operate on (where applicable). The default of
`vtkm::ListAppend<VTKM_DEFAULT_CELL_SET_LIST_STRUCTURED, VTKM_DEFAULT_CELL_SET_LIST>`
is usually correct.
If any of these macros are not defined, a default version will be defined.
(This is the same default used if no header file is provided.)
This header file is provided to the build by setting the
`VTKm_DEFAULT_TYPES_HEADER` CMake variable. `VTKm_DEFAULT_TYPES_HEADER`
points to the file, which will be configured and copied to VTK-m's build
directory.
For convenience, header files can be added to the VTK_m source directory
(conventionally under vtkm/cont/internal). If this is the case, an advanced
CMake option should be added to select the provided header file.

@ -10,10 +10,6 @@
#ifndef vtk_m_TypeList_h
#define vtk_m_TypeList_h
#ifndef VTKM_DEFAULT_TYPE_LIST
#define VTKM_DEFAULT_TYPE_LIST ::vtkm::TypeListCommon
#endif
#include <vtkm/List.h>
#include <vtkm/Types.h>

@ -63,7 +63,7 @@ VTKM_DEPRECATED(
1.6,
"VTKM_DEFAULT_TYPE_LIST_TAG replaced by VTKM_DEFAULT_TYPE_LIST. "
"Note that the new VTKM_DEFAULT_TYPE_LIST cannot be subclassed.")
TypeListTagDefault : vtkm::internal::ListAsListTag<VTKM_DEFAULT_TYPE_LIST>
TypeListTagDefault : vtkm::internal::ListAsListTag<vtkm::TypeListCommon>
{
};

@ -13,8 +13,6 @@
#include <vtkm/cont/StorageExtrude.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/CoordinateSystem.hxx>
namespace vtkm
{

@ -189,6 +189,39 @@ set(sources
Timer.cxx
)
#-----------------------------------------------------------------------------
# Set up default types, which can be custom configured by other build systems.
vtkm_get_kit_name(kit_name kit_dir)
# Some custom types included with VTK-m
option(VTKm_USE_DEFAULT_TYPES_FOR_VTK "Compile VTK-m algorithms for use with types from VTK." OFF)
if (VTKm_USE_DEFAULT_TYPES_FOR_VTK)
set(VTKm_DEFAULT_TYPES_HEADER "internal/DefaultTypesVTK.h.in")
endif()
mark_as_advanced(VTKm_USE_DEFAULT_TYPES_FOR_VTK)
if (VTKm_DEFAULT_TYPES_HEADER)
set(VTK_M_HAS_DEFAULT_TYPES_HEADER TRUE)
get_filename_component(VTKm_DEFAULT_TYPES_HEADER_FILENAME ${VTKm_DEFAULT_TYPES_HEADER} NAME_WE)
set(VTKm_DEFAULT_TYPES_HEADER_FILENAME "${VTKm_DEFAULT_TYPES_HEADER_FILENAME}.h")
configure_file(${VTKm_DEFAULT_TYPES_HEADER}
${VTKm_BINARY_INCLUDE_DIR}/${kit_dir}/internal/${VTKm_DEFAULT_TYPES_HEADER_FILENAME}
@ONLY
)
vtkm_install_headers(vtkm/cont/internal
${VTKm_BINARY_INCLUDE_DIR}/${kit_dir}/internal/${VTKm_DEFAULT_TYPES_HEADER_FILENAME}
)
endif()
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/DefaultTypes.h.in
${VTKm_BINARY_INCLUDE_DIR}/${kit_dir}/DefaultTypes.h
@ONLY
)
vtkm_install_headers(vtkm/cont
${VTKm_BINARY_INCLUDE_DIR}/${kit_dir}/DefaultTypes.h
)
#-----------------------------------------------------------------------------
vtkm_library( NAME vtkm_cont
SOURCES ${sources}

@ -15,9 +15,6 @@
#include <vtkm/StaticAssert.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/Field.h>
#include <vtkm/cont/VariantArrayHandle.h>
namespace vtkm
{

@ -10,10 +10,6 @@
#ifndef vtk_m_cont_CellSetList_h
#define vtk_m_cont_CellSetList_h
#ifndef VTKM_DEFAULT_CELL_SET_LIST
#define VTKM_DEFAULT_CELL_SET_LIST ::vtkm::cont::CellSetListCommon
#endif
#include <vtkm/List.h>
#include <vtkm/cont/CellSetExplicit.h>

@ -15,6 +15,7 @@
#include <vtkm/TopologyElementTag.h>
#include <vtkm/cont/CellSet.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/ErrorBadType.h>
#include <vtkm/exec/ConnectivityStructured.h>
#include <vtkm/internal/ConnectivityStructuredInternals.h>

@ -38,7 +38,10 @@ public:
const vtkm::cont::VariantArrayHandleBase<TypeList>& data);
template <typename T, typename Storage>
VTKM_CONT CoordinateSystem(std::string name, const ArrayHandle<T, Storage>& data);
VTKM_CONT CoordinateSystem(std::string name, const ArrayHandle<T, Storage>& data)
: Superclass(name, Association::POINTS, vtkm::cont::ArrayHandleVirtualCoordinates(data))
{
}
/// This constructor of coordinate system sets up a regular grid of points.
///

@ -56,13 +56,6 @@ VTKM_CONT CoordinateSystem::CoordinateSystem(
{
}
template <typename T, typename Storage>
VTKM_CONT CoordinateSystem::CoordinateSystem(std::string name,
const vtkm::cont::ArrayHandle<T, Storage>& data)
: Superclass(name, Association::POINTS, vtkm::cont::ArrayHandleVirtualCoordinates(data))
{
}
template <typename T, typename Storage>
VTKM_CONT void CoordinateSystem::SetData(const vtkm::cont::ArrayHandle<T, Storage>& newdata)
{

104
vtkm/cont/DefaultTypes.h.in Normal file

@ -0,0 +1,104 @@
//============================================================================
// 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.
//============================================================================
// The intention of the header file is to configure VTK-m to compile its algorithms
// and filters for some set of types and data storage. You can customize the types
// for which VTK-m is compiled for by setting the VTKm_DEFAULT_TYPES_HEADER CMake
// variable. This CMake variable can be set to a header file that defines one or
// more of the following macros:
//
// VTKM_FIELD_TYPE_LIST - a vtkm::List of value types for fields that filters
// should directly operate on (where applicable).
// VTKM_FIELD_STORAGE_LIST - a vtkm::List of storage tags for fields that
// filters should directly operate on.
// VTKM_DEFAULT_CELL_SET_LIST_STRUCTURED - a vtkm::List of vtkm::cont::CellSet types
// that filters should operate on as a strutured cell set.
// VTKM_DEFAULT_CELL_SET_LIST_UNSTRUCTURED - a vtkm::List of vtkm::cont::CellSet types
// that filters should operate on as an unstrutured cell set.
// VTKM_DEFAULT_CELL_SET_LIST - a vtkm::List of vtkm::cont::CellSet types that filters
// should operate on (where applicable). The default of
// vtkm::ListAppend<VTKM_STRUCTURED_CELL_SET_LIST, VTKM_DEFAULT_CELL_SET_LIST_UNSTRUCTURED>
// is usually correct.
//
// Note that if you specify VTKm_DEFAULT_TYPES_HEADER, that file will be copied
// to the VTK-m build directory. Thus, be careful about editing the file included
// by this one (if it exists).
#ifndef vtk_m_cont_DefaultTypes_h
#define vtk_m_cont_DefaultTypes_h
#cmakedefine VTK_M_HAS_DEFAULT_TYPES_HEADER
#ifdef VTK_M_HAS_DEFAULT_TYPES_HEADER
#include "internal/@VTKm_DEFAULT_TYPES_HEADER_FILENAME@"
#endif
#ifndef VTKM_DEFAULT_TYPE_LIST
#include <vtkm/TypeList.h>
#define VTKM_DEFAULT_TYPE_LIST ::vtkm::TypeListCommon
#endif //VTKM_DEFAULT_TYPE_LIST
#ifndef VTKM_DEFAULT_STORAGE_LIST
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/StorageList.h>
namespace vtkm
{
namespace cont
{
namespace internal
{
using StorageListField = vtkm::ListAppend<
vtkm::cont::StorageListBasic,
vtkm::List<
vtkm::cont::ArrayHandleUniformPointCoordinates::StorageTag,
vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<vtkm::Float32>,
vtkm::cont::ArrayHandle<vtkm::Float32>,
vtkm::cont::ArrayHandle<vtkm::Float32>>::StorageTag,
vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<vtkm::Float64>,
vtkm::cont::ArrayHandle<vtkm::Float64>,
vtkm::cont::ArrayHandle<vtkm::Float64>>::StorageTag>>;
}
}
} // namespace vtkm::cont
#define VTKM_DEFAULT_STORAGE_LIST ::vtkm::cont::internal::StorageListField
#endif // VTKM_FIELD_STORAGE_LIST
#ifndef VTKM_DEFAULT_CELL_SET_LIST_STRUCTURED
#include <vtkm/cont/CellSetList.h>
#define VTKM_DEFAULT_CELL_SET_LIST_STRUCTURED ::vtkm::cont::CellSetListStructured
#endif // VTKM_DEFAULT_CELL_SET_LIST_STRUCTURED
#ifndef VTKM_DEFAULT_CELL_SET_LIST_UNSTRUCTURED
#include <vtkm/cont/CellSetList.h>
#define VTKM_DEFAULT_CELL_SET_LIST_UNSTRUCTURED ::vtkm::cont::CellSetListUnstructured
#endif // VTKM_DEFAULT_CELL_SET_LIST_UNSTRUCTURED
#ifndef VTKM_DEFAULT_CELL_SET_LIST
namespace vtkm
{
namespace cont
{
namespace internal
{
using CellSetList = vtkm::ListAppend<VTKM_DEFAULT_CELL_SET_LIST_STRUCTURED, VTKM_DEFAULT_CELL_SET_LIST_UNSTRUCTURED>;
}
}
} // namespace vtkm::cont::internal
#define VTKM_DEFAULT_CELL_SET_LIST ::vtkm::cont::internal::CellSetList
#endif // VTKM_CELL_SET_LIST
#endif //vtk_m_cont_DefaultTypes_h

@ -13,6 +13,7 @@
#include <vtkm/cont/CastAndCall.h>
#include <vtkm/cont/CellSet.h>
#include <vtkm/cont/CellSetList.h>
#include <vtkm/cont/DefaultTypes.h>
#include <vtkm/cont/ErrorBadValue.h>
#include <vtkm/cont/Logging.h>

@ -10,10 +10,6 @@
#ifndef vtk_m_cont_StorageList_h
#define vtk_m_cont_StorageList_h
#ifndef VTKM_DEFAULT_STORAGE_LIST
#define VTKM_DEFAULT_STORAGE_LIST ::vtkm::cont::StorageListBasic
#endif
#include <vtkm/List.h>
#include <vtkm/cont/Storage.h>
@ -25,10 +21,6 @@ namespace cont
{
using StorageListBasic = vtkm::List<vtkm::cont::StorageTagBasic>;
// If we want to compile VTK-m with support of memory layouts other than the basic layout, then
// add the appropriate storage tags here.
using StorageListSupported = vtkm::List<vtkm::cont::StorageTagBasic>;
}
} // namespace vtkm::cont

@ -35,9 +35,9 @@ struct VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(
struct VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(
1.6,
"StorageListTagSupported replaced by StorageListSupported. "
"StorageListTagSupported replaced by StorageListBasic. "
"Note that the new StorageListSupported cannot be subclassed.") StorageListTagSupported
: vtkm::internal::ListAsListTag<StorageListSupported>
: vtkm::internal::ListAsListTag<StorageListBasic>
{
};
@ -48,7 +48,7 @@ struct VTKM_ALWAYS_EXPORT VTKM_DEPRECATED(
1.6,
"VTKM_DEFAULT_STORAGE_LIST_TAG replaced by VTKM_DEFAULT_STORAGE_LIST. "
"Note that the new VTKM_DEFAULT_STORAGE_LIST cannot be subclassed.") StorageListTagDefault
: vtkm::internal::ListAsListTag<VTKM_DEFAULT_STORAGE_LIST>
: vtkm::internal::ListAsListTag<vtkm::cont::StorageListBasic>
{
};

@ -19,6 +19,7 @@
#include <vtkm/cont/ArrayHandleTransform.h>
#include <vtkm/cont/ArrayHandleVirtual.h>
#include <vtkm/cont/CastAndCall.h>
#include <vtkm/cont/DefaultTypes.h>
#include <vtkm/cont/ErrorBadType.h>
#include <vtkm/cont/Logging.h>
#include <vtkm/cont/StorageList.h>

@ -0,0 +1,107 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
//
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#ifndef vtkmDefaultTypes_h
#define vtkmDefaultTypes_h
// This configures the default types to use when compiling VTK-m for use as an
// accelerator in VTK.
#include <vtkm/TypeList.h>
#include <vtkm/cont/CellSetList.h>
namespace tovtkm
{
//------------------------------------------------------------------------------
// All scalar types in vtkType.h
using VTKScalarTypes = vtkm::List< //
char, //
signed char, //
unsigned char, //
short, //
unsigned short, //
int, //
unsigned int, //
long, //
unsigned long, //
long long, //
unsigned long long, //
float, //
double //
>;
using SpecialGradientOutTypes =
vtkm::List<vtkm::Vec<vtkm::Vec<vtkm::Float32, 3>, 3>, vtkm::Vec<vtkm::Vec<vtkm::Float64, 3>, 3> >;
using FieldTypeInVTK = vtkm::ListAppend<vtkm::TypeListVecCommon, VTKScalarTypes>;
using FieldTypeOutVTK =
vtkm::ListAppend<vtkm::TypeListVecCommon, SpecialGradientOutTypes, VTKScalarTypes>;
//------------------------------------------------------------------------------
using CellListStructuredInVTK =
vtkm::List<vtkm::cont::CellSetStructured<3>, vtkm::cont::CellSetStructured<2>, vtkm::cont::CellSetStructured<1> >;
using CellListStructuredOutVTK = CellListStructuredInVTK;
// vtkCellArray may use either 32 or 64 bit arrays to hold connectivity/offset
// data, so we may be using ArrayHandleCast to convert to vtkm::Ids.
#ifdef VTKM_USE_64BIT_IDS
using Int32AOSHandle = vtkm::cont::ArrayHandle<vtkm::Int32>;
using Int32AsIdAOSHandle = vtkm::cont::ArrayHandleCast<vtkm::Id, Int32AOSHandle>;
using Int32AsIdAOSStorage = typename Int32AsIdAOSHandle::StorageTag;
using CellSetExplicit32Bit = vtkm::cont::CellSetExplicit<vtkm::cont::StorageTagBasic,
Int32AsIdAOSStorage, Int32AsIdAOSStorage>;
using CellSetExplicit64Bit = vtkm::cont::CellSetExplicit<vtkm::cont::StorageTagBasic,
vtkm::cont::StorageTagBasic, vtkm::cont::StorageTagBasic>;
using CellSetSingleType32Bit = vtkm::cont::CellSetSingleType<Int32AsIdAOSStorage>;
using CellSetSingleType64Bit = vtkm::cont::CellSetSingleType<vtkm::cont::StorageTagBasic>;
#else // VTKM_USE_64BIT_IDS
using Int64AOSHandle = vtkm::cont::ArrayHandle<vtkm::Int64, vtkm::cont::StorageTagBasic>;
using Int64AsIdAOSHandle = vtkm::cont::ArrayHandleCast<vtkm::Id, Int64AOSHandle>;
using Int64AsIdAOSStorage = typename Int64AsIdAOSHandle::StorageTag;
using CellSetExplicit32Bit = vtkm::cont::CellSetExplicit<vtkm::cont::StorageTagBasic,
vtkm::cont::StorageTagBasic, vtkm::cont::StorageTagBasic>;
using CellSetExplicit64Bit = vtkm::cont::CellSetExplicit<vtkm::cont::StorageTagBasic,
Int64AsIdAOSStorage, Int64AsIdAOSStorage>;
using CellSetSingleType32Bit = vtkm::cont::CellSetSingleType<vtkm::cont::StorageTagBasic>;
using CellSetSingleType64Bit = vtkm::cont::CellSetSingleType<Int64AsIdAOSStorage>;
#endif // VTKM_USE_64BIT_IDS
//------------------------------------------------------------------------------
using CellListUnstructuredInVTK = vtkm::List< //
CellSetExplicit32Bit, //
CellSetExplicit64Bit, //
CellSetSingleType32Bit, //
CellSetSingleType64Bit //
>;
using CellListUnstructuredOutVTK = vtkm::List< //
vtkm::cont::CellSetExplicit<>, //
vtkm::cont::CellSetSingleType<>, //
CellSetExplicit32Bit, //
CellSetExplicit64Bit, //
CellSetSingleType32Bit, //
CellSetSingleType64Bit //
>;
//------------------------------------------------------------------------------
using CellListAllInVTK = vtkm::ListAppend<CellListStructuredInVTK, CellListUnstructuredInVTK>;
using CellListAllOutVTK = vtkm::ListAppend<CellListStructuredOutVTK, CellListUnstructuredOutVTK>;
} // end namespace tovtkm
#define VTKM_DEFAULT_TYPE_LIST ::tovtkm::FieldTypeInVTK
#define VTKM_DEFAULT_CELL_SET_LIST_STRUCTURED ::tovtkm::CellListStructuredInVTK
#define VTKM_DEFAULT_CELL_SET_LIST_UNSTRUCTURED ::tovtkm::CellListUnstructuredInVTK
#endif //vtkmDefaultTypes_h

@ -110,7 +110,7 @@ struct CheckFunctor
template <typename T>
void operator()(
const vtkm::cont::ArrayHandle<T, typename ArrayHandleWithUnusualStorage<T>::StorageTag>& array,
const vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagImplicit<UnusualPortal<T>>>& array,
bool& vtkmNotUsed(calledBasic),
bool& calledUnusual,
bool& vtkmNotUsed(calledVirtual)) const
@ -138,6 +138,12 @@ struct CheckFunctor
auto portal = array.ReadPortal();
CheckPortal(portal);
}
template <typename T, typename S>
void operator()(const vtkm::cont::ArrayHandle<T, S>&, bool&, bool&, bool&) const
{
VTKM_TEST_FAIL("Array resolved to unexpected type.");
}
};
template <typename TypeList>

@ -16,6 +16,7 @@
#include <vtkm/cont/CellSetList.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DefaultTypes.h>
#include <vtkm/cont/DeviceAdapterList.h>
#include <vtkm/cont/DynamicCellSet.h>
#include <vtkm/cont/Field.h>
@ -32,19 +33,10 @@ template <typename Derived>
struct PolicyBase
{
using FieldTypeList = VTKM_DEFAULT_TYPE_LIST;
using StorageList = vtkm::ListAppend<
VTKM_DEFAULT_STORAGE_LIST,
vtkm::List<
vtkm::cont::ArrayHandleUniformPointCoordinates::StorageTag,
vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<vtkm::Float32>,
vtkm::cont::ArrayHandle<vtkm::Float32>,
vtkm::cont::ArrayHandle<vtkm::Float32>>::StorageTag,
vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<vtkm::Float64>,
vtkm::cont::ArrayHandle<vtkm::Float64>,
vtkm::cont::ArrayHandle<vtkm::Float64>>::StorageTag>>;
using StorageList = VTKM_DEFAULT_STORAGE_LIST;
using StructuredCellSetList = vtkm::cont::CellSetListStructured;
using UnstructuredCellSetList = vtkm::cont::CellSetListUnstructured;
using StructuredCellSetList = VTKM_DEFAULT_CELL_SET_LIST_STRUCTURED;
using UnstructuredCellSetList = VTKM_DEFAULT_CELL_SET_LIST_UNSTRUCTURED;
using AllCellSetList = VTKM_DEFAULT_CELL_SET_LIST;
};

@ -12,6 +12,7 @@
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/ArrayPortalToIterators.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/Field.h>
#include <vtkm/cont/Invoker.h>
#include <vtkm/cont/TryExecute.h>