For VTK-m libs all includes of DeviceAdapterTagCuda happen from cuda files

It is very easy to cause ODR violations with DeviceAdapterTagCuda.
If you include that header from a C++ file and a CUDA file inside
the same program we an ODR violation. The reasons is that the C++
versions will say the tag is invalid, and the CUDA will say the
tag is valid.

The solution to this is that any compilation unit that includes
DeviceAdapterTagCuda from a version of VTK-m that has CUDA enabled
must be invoked by the cuda compiler.
This commit is contained in:
Robert Maynard 2019-04-17 13:59:49 -04:00
parent 2c026508b3
commit ff687016ee
30 changed files with 96 additions and 98 deletions

@ -270,6 +270,7 @@ endfunction(vtkm_library)
# SOURCES <source_list>
# BACKEND <type>
# LIBRARIES <dependent_library_list>
# DEFINES <target_compile_definitions>
# TEST_ARGS <argument_list>
# MPI
# ALL_BACKENDS
@ -285,6 +286,8 @@ endfunction(vtkm_library)
#
# [LIBRARIES] : extra libraries that this set of tests need to link too
#
# [DEFINES] : extra defines that need to be set for all unit test sources
#
# [TEST_ARGS] : arguments that should be passed on the command line to the
# test executable
#
@ -301,7 +304,7 @@ function(vtkm_unit_tests)
set(options)
set(global_options ${options} MPI ALL_BACKENDS)
set(oneValueArgs BACKEND NAME)
set(multiValueArgs SOURCES LIBRARIES TEST_ARGS)
set(multiValueArgs SOURCES LIBRARIES DEFINES TEST_ARGS)
cmake_parse_arguments(VTKm_UT
"${global_options}" "${oneValueArgs}" "${multiValueArgs}"
${ARGN}
@ -370,6 +373,8 @@ function(vtkm_unit_tests)
target_link_libraries(${test_prog} PRIVATE vtkm_cont ${VTKm_UT_LIBRARIES})
endif()
target_compile_definitions(${test_prog} PRIVATE ${VTKm_UT_DEFINES})
foreach(current_backend ${all_backends})
set (device_command_line_argument --device=${current_backend})
if (current_backend STREQUAL "NO_BACKEND")

@ -121,15 +121,13 @@ set(template_sources
set(sources
ArrayHandle.cxx
ArrayHandleVirtual.cxx
CellLocator.cxx
ColorTablePresets.cxx
DeviceAdapterTag.cxx
EnvironmentTracker.cxx
ErrorBadDevice.cxx
ErrorBadType.cxx
internal/ArrayHandleBasicImpl.cxx
internal/ArrayManagerExecutionShareWithControl.cxx
internal/DeviceAdapterTag.cxx
internal/TransferInfo.cxx
internal/VirtualObjectTransfer.cxx
Initialize.cxx
@ -137,16 +135,17 @@ set(sources
RuntimeDeviceTracker.cxx
StorageBasic.cxx
TryExecute.cxx
VariantArrayHandle.cxx
)
# This list of sources has code that uses devices and so might need to be
# compiled with a device-specific compiler (like CUDA).
set(device_sources
# This list of sources has code that uses devices and so might need to be
# compiled with a device-specific compiler (like CUDA).
set(device_sources
ArrayHandleVirtual.cxx
ArrayRangeCompute.cxx
AssignerMultiBlock.cxx
BoundsCompute.cxx
BoundsGlobalCompute.cxx
CellLocator.cxx
CellLocatorBoundingIntervalHierarchy.cxx
CellLocatorGeneral.cxx
CellLocatorRectilinearGrid.cxx
@ -161,6 +160,7 @@ set(device_sources
DataSetBuilderExplicit.cxx
DataSetBuilderRectilinear.cxx
DataSetBuilderUniform.cxx
internal/VariantArrayHandleContainer.cxx
Field.cxx
FieldRangeCompute.cxx
FieldRangeGlobalCompute.cxx

@ -12,7 +12,7 @@
#include <vtkm/Types.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/serial/internal/DeviceAdapterTagSerial.h>
namespace vtkm
{

@ -22,4 +22,4 @@ set(unit_tests
UnitTestTypeCheckKeys.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests})
vtkm_unit_tests(SOURCES ${unit_tests} DEFINES VTKM_NO_ERROR_ON_MIXED_CUDA_CXX_TAG)

@ -15,8 +15,10 @@
//We always create the cuda tag when included, but we only mark it as
//a valid tag when VTKM_CUDA is true. This is for easier development
//of multi-backend systems
#ifdef VTKM_CUDA
#if defined(VTKM_CUDA) && defined(VTKM_ENABLE_CUDA)
VTKM_VALID_DEVICE_ADAPTER(Cuda, VTKM_DEVICE_ADAPTER_CUDA);
#elif defined(VTKM_ENABLE_CUDA) && !defined(VTKM_NO_ERROR_ON_MIXED_CUDA_CXX_TAG)
#error When VTK-m is build with CUDA enabled all compilation units that include DeviceAdapterTagCuda must use the cuda compiler
#else
VTKM_INVALID_DEVICE_ADAPTER(Cuda, VTKM_DEVICE_ADAPTER_CUDA);
#endif

@ -10,6 +10,7 @@
#include <vtkm/cont/RuntimeDeviceTracker.h>
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/testing/TestingMath.h>
#include <vtkm/worklet/DispatcherMapField.h>

@ -11,10 +11,8 @@
#include <sstream>
#include <typeindex>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/ErrorBadValue.h>
#include <vtkm/cont/VariantArrayHandle.h>
#include <vtkm/cont/internal/VariantArrayHandleContainer.h>
namespace vtkm
{
@ -40,7 +38,8 @@ VariantArrayHandleContainerBase::~VariantArrayHandleContainerBase()
namespace detail
{
void ThrowCastAndCallException(const vtkm::cont::internal::VariantArrayHandleContainerBase& ref,
VTKM_CONT_EXPORT void ThrowCastAndCallException(
const vtkm::cont::internal::VariantArrayHandleContainerBase& ref,
const std::type_info& type)
{
std::ostringstream out;

@ -15,4 +15,4 @@ set(unit_tests
UnitTestDynamicTransform.cxx
UnitTestIteratorFromArrayPortal.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests})
vtkm_unit_tests(SOURCES ${unit_tests} DEFINES VTKM_NO_ERROR_ON_MIXED_CUDA_CXX_TAG)

@ -25,7 +25,7 @@ set(unit_tests
UnitTestOpenMPPointLocatorUniformGrid.cxx
UnitTestOpenMPVirtualObjectHandle.cxx
)
vtkm_unit_tests(OpenMP SOURCES ${unit_tests})
vtkm_unit_tests(OpenMP SOURCES ${unit_tests} DEFINES VTKM_NO_ERROR_ON_MIXED_CUDA_CXX_TAG)
if (VTKm_ENABLE_TESTING)
#We need to have all OpenMP tests run serially as they

@ -26,4 +26,4 @@ set(unit_tests
UnitTestSerialPointLocatorUniformGrid.cxx
UnitTestSerialVirtualObjectHandle.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests})
vtkm_unit_tests(SOURCES ${unit_tests} DEFINES VTKM_NO_ERROR_ON_MIXED_CUDA_CXX_TAG)

@ -26,4 +26,4 @@ set(unit_tests
UnitTestTBBVirtualObjectHandle.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests})
vtkm_unit_tests(SOURCES ${unit_tests} DEFINES VTKM_NO_ERROR_ON_MIXED_CUDA_CXX_TAG)

@ -78,8 +78,7 @@ set(unit_tests
UnitTestTryExecute.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests})
vtkm_unit_tests(SOURCES ${unit_tests} DEFINES VTKM_NO_ERROR_ON_MIXED_CUDA_CXX_TAG)
# add distributed tests i.e. test to run with MPI
# if MPI is enabled.
@ -88,4 +87,4 @@ set(mpi_unit_tests
UnitTestSerializationArrayHandle.cxx
UnitTestSerializationDataSet.cxx
)
vtkm_unit_tests(MPI SOURCES ${mpi_unit_tests})
vtkm_unit_tests(MPI SOURCES ${mpi_unit_tests} DEFINES VTKM_NO_ERROR_ON_MIXED_CUDA_CXX_TAG)

@ -7,8 +7,8 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/testing/Testing.h>
#include <vtkm/exec/FunctorBase.h>
#include <vtkm/exec/arg/BasicArg.h>
@ -20,8 +20,6 @@
#include <vtkm/internal/FunctionInterface.h>
#include <vtkm/internal/Invocation.h>
#include <vtkm/cont/testing/Testing.h>
#if defined(VTKM_MSVC)
#pragma warning(push)
#pragma warning(disable : 4068) //unknown pragma
@ -372,8 +370,7 @@ void TestTaskStrided()
int UnitTestTaskStrided(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(
TestTaskStrided<vtkm::cont::DeviceAdapterTagCuda>, argc, argv);
return vtkm::testing::Testing::Run(TestTaskStrided<vtkm::cont::DeviceAdapterTagCuda>, argc, argv);
}
#if defined(__NVCC__) && defined(__CUDACC_VER_MAJOR__)

@ -11,7 +11,7 @@
#include <vtkm/StaticAssert.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/testing/Testing.h>
#include <vtkm/exec/FunctorBase.h>
#include <vtkm/exec/arg/BasicArg.h>

@ -20,7 +20,6 @@
#include <vtkm/internal/Invocation.h>
#include <vtkm/testing/Testing.h>
namespace
{

@ -9,9 +9,10 @@
//============================================================================
#include <vtkm/cont/openmp/DeviceAdapterOpenMP.h>
#include <vtkm/exec/internal/testing/TestingTaskTiling.h>
#include <vtkm/testing/Testing.h>
int UnitTestTaskTilingOpenMP(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(
return vtkm::testing::Testing::Run(
vtkm::exec::internal::testing::TestTaskTiling<vtkm::cont::DeviceAdapterTagOpenMP>, argc, argv);
}

@ -7,13 +7,13 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
#include <vtkm/exec/internal/testing/TestingTaskTiling.h>
#include <vtkm/testing/Testing.h>
int UnitTestTaskTilingSerial(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(
return vtkm::testing::Testing::Run(
vtkm::exec::internal::testing::TestTaskTiling<vtkm::cont::DeviceAdapterTagSerial>, argc, argv);
}

@ -7,12 +7,12 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
#include <vtkm/exec/internal/testing/TestingTaskTiling.h>
#include <vtkm/testing/Testing.h>
int UnitTestTaskTilingTBB(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(
return vtkm::testing::Testing::Run(
vtkm::exec::internal::testing::TestTaskTiling<vtkm::cont::DeviceAdapterTagTBB>, argc, argv);
}

@ -8,13 +8,11 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/internal/ArrayPortalValueReference.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/testing/Testing.h>
#include <vtkm/TypeTraits.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/internal/ArrayPortalValueReference.h>
namespace
{
@ -304,5 +302,5 @@ void DoTest()
int UnitTestArrayPortalValueReference(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(DoTest, argc, argv);
return vtkm::testing::Testing::Run(DoTest, argc, argv);
}

@ -7,12 +7,8 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/internal/FunctionInterface.h>
#include <vtkm/cont/Timer.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/testing/Testing.h>
#include <sstream>
#include <string>
@ -21,6 +17,9 @@
// the most critical invoke (for the instance of a worklet) does not directly
// use the Invoke method.
//#define TEST_INVOKE_TIME
#ifdef TEST_INVOKE_TIME
#include <vtkm/cont/Timer.h>
#endif
namespace
{
@ -532,5 +531,5 @@ void TestFunctionInterface()
int UnitTestFunctionInterface(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(TestFunctionInterface, argc, argv);
return vtkm::testing::Testing::Run(TestFunctionInterface, argc, argv);
}

@ -42,5 +42,8 @@ elseif(VTKm_ENABLE_GL_CONTEXT AND TARGET vtkm_rendering)
endif()
if(unit_tests)
vtkm_unit_tests(SOURCES ${unit_tests} LIBRARIES vtkm_rendering GLUT::GLUT)
vtkm_unit_tests(SOURCES ${unit_tests}
LIBRARIES vtkm_rendering GLUT::GLUT
DEFINES VTKM_NO_ERROR_ON_MIXED_CUDA_CXX_TAG)
endif()

@ -12,4 +12,4 @@ set(unit_tests
UnitTestVTKDataSetReader.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests})
vtkm_unit_tests(SOURCES ${unit_tests} ALL_BACKENDS)

@ -12,4 +12,4 @@ set(unit_tests
UnitTestVTKDataSetWriter.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests})
vtkm_unit_tests(SOURCES ${unit_tests} ALL_BACKENDS)

@ -12,7 +12,6 @@
#include <vtkm/rendering/vtkm_rendering_export.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/rendering/Color.h>
#include <vtkm/rendering/Scene.h>
#include <vtkm/rendering/WorldAnnotator.h>

@ -78,34 +78,67 @@ set(headers
)
set(sources
BitmapFont.cxx
BitmapFontFactory.cxx
Camera.cxx
Color.cxx
DecodePNG.cxx
raytracing/Logger.cxx
)
# This list of sources has code that uses devices and so might need to be
# compiled with a device-specific compiler (like CUDA).
set(device_sources
Actor.cxx
AxisAnnotation.cxx
AxisAnnotation2D.cxx
AxisAnnotation3D.cxx
BitmapFont.cxx
BitmapFontFactory.cxx
BoundingBoxAnnotation.cxx
Camera.cxx
Color.cxx
Canvas.cxx
CanvasRayTracer.cxx
ColorBarAnnotation.cxx
ColorLegendAnnotation.cxx
DecodePNG.cxx
ConnectivityProxy.cxx
LineRenderer.cxx
Mapper.cxx
MapperConnectivity.cxx
MapperCylinder.cxx
MapperPoint.cxx
MapperQuad.cxx
MapperRayTracer.cxx
MapperVolume.cxx
MapperWireframer.cxx
Scene.cxx
TextAnnotation.cxx
TextAnnotationBillboard.cxx
TextAnnotationScreen.cxx
TextRenderer.cxx
View.cxx
View1D.cxx
View2D.cxx
View3D.cxx
WorldAnnotator.cxx
raytracing/Logger.cxx
internal/RunTriangulator.cxx
raytracing/BoundingVolumeHierarchy.cxx
raytracing/Camera.cxx
raytracing/ChannelBuffer.cxx
raytracing/ConnectivityTracer.cxx
raytracing/CylinderExtractor.cxx
raytracing/CylinderIntersector.cxx
raytracing/MeshConnectivityBuilder.cxx
raytracing/MeshConnectivityContainers.cxx
raytracing/QuadExtractor.cxx
raytracing/QuadIntersector.cxx
raytracing/RayTracer.cxx
raytracing/RayOperations.cxx
raytracing/ShapeIntersector.cxx
raytracing/SphereExtractor.cxx
raytracing/SphereIntersector.cxx
raytracing/TriangleExtractor.cxx
raytracing/TriangleIntersector.cxx
raytracing/VolumeRendererStructured.cxx
)
# Note that EGL and OSMesa Canvas depend on the GL version being built. Only
@ -140,38 +173,6 @@ set(osmesa_sources
CanvasOSMesa.cxx
)
# This list of sources has code that uses devices and so might need to be
# compiled with a device-specific compiler (like CUDA).
set(device_sources
Actor.cxx
Canvas.cxx
CanvasRayTracer.cxx
ConnectivityProxy.cxx
Mapper.cxx
MapperWireframer.cxx
TextRenderer.cxx
internal/RunTriangulator.cxx
raytracing/BoundingVolumeHierarchy.cxx
raytracing/Camera.cxx
raytracing/ChannelBuffer.cxx
raytracing/ConnectivityTracer.cxx
raytracing/CylinderExtractor.cxx
raytracing/CylinderIntersector.cxx
raytracing/MeshConnectivityBuilder.cxx
raytracing/MeshConnectivityContainers.cxx
raytracing/QuadExtractor.cxx
raytracing/QuadIntersector.cxx
raytracing/RayTracer.cxx
raytracing/RayOperations.cxx
raytracing/ShapeIntersector.cxx
raytracing/SphereExtractor.cxx
raytracing/SphereIntersector.cxx
raytracing/TriangleExtractor.cxx
raytracing/TriangleIntersector.cxx
raytracing/VolumeRendererStructured.cxx
)
#-----------------------------------------------------------------------------
vtkm_library(
NAME vtkm_rendering
@ -196,9 +197,8 @@ endif()
#-----------------------------------------------------------------------------
target_link_libraries(vtkm_rendering PUBLIC vtkm_filter)
if(UNIX AND NOT APPLE)
target_link_libraries(vtkm_rendering PRIVATE rt )
target_link_libraries(vtkm_rendering PRIVATE rt)
endif()
#-----------------------------------------------------------------------------

@ -13,8 +13,6 @@
#include <vtkm/cont/Algorithm.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/ExecutionObjectBase.h>
namespace vtkm

@ -19,8 +19,6 @@
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/testing/Testing.h>
#include <limits>
#define VTKM_MATH_ASSERT(condition, message) \

@ -8,13 +8,13 @@
// PURPOSE. See the above copyright notice for more information.
//============================================================================
#include <vtkm/testing/Testing.h>
#include <vtkm/testing/TestingMath.h>
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
#include <vtkm/cont/testing/Testing.h>
int UnitTestMath(int argc, char* argv[])
{
return vtkm::cont::testing::Testing::Run(
return vtkm::testing::Testing::Run(
UnitTestMathNamespace::RunMathTests<vtkm::cont::DeviceAdapterTagSerial>, argc, argv);
}

@ -12,4 +12,4 @@ set(unit_tests
UnitTestDispatcherBase.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests})
vtkm_unit_tests(SOURCES ${unit_tests} DEFINES VTKM_NO_ERROR_ON_MIXED_CUDA_CXX_TAG)