Add a swap implementation that works on all backend.

Calling std::swap isn't legal from CUDA code, but the new vtkm::Swap
method is safe. It currently does a naive swap when compiling CUDA
code, and falls back to an ADL swap
This commit is contained in:
Allison Vacanti 2018-06-01 14:01:23 -04:00
parent b8468761c7
commit ec0791e941
4 changed files with 65 additions and 5 deletions

7
docs/changelog/swap.md Normal file

@ -0,0 +1,7 @@
# Add a CUDA-safe `vtkm::Swap` method.
Added a swap implementation that is safe to call from all backends.
It is not legal to call std functions from CUDA code, and the new
`vtkm::Swap` implements a naive swap when compiled under NVCC while
falling back to a std/ADL swap otherwise.

@ -46,6 +46,7 @@ set(headers
RangeId.h
RangeId3.h
StaticAssert.h
Swap.h
TopologyElementTag.h
Transform3D.h
TypeListTag.h

51
vtkm/Swap.h Normal file

@ -0,0 +1,51 @@
//============================================================================
// 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.
//
// Copyright 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2018 UT-Battelle, LLC.
// Copyright 2018 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_Swap_h
#define vtk_m_Swap_h
#include <vtkm/internal/ExportMacros.h>
#include <algorithm>
namespace vtkm
{
/// Performs a swap operation. Safe to call from cuda code.
#ifdef __CUDACC__
template <typename T>
VTKM_EXEC_CONT void Swap(T& a, T& b)
{
T tmp = a;
a = b;
b = tmp;
}
#else
template <typename T>
VTKM_EXEC_CONT void Swap(T& a, T& b)
{
using namespace std;
swap(a, b);
}
#endif
} // end namespace vtkm
#endif //vtk_m_Swap_h

@ -23,6 +23,7 @@
#include <vtkm/Assert.h>
#include <vtkm/Math.h>
#include <vtkm/Swap.h>
#include <vtkm/Types.h>
#include <vtkm/VectorAnalysis.h>
#include <vtkm/cont/ArrayHandle.h>
@ -219,16 +220,16 @@ public:
bool transposed = vtkm::Abs(y2 - y1) > vtkm::Abs(x2 - x1);
if (transposed)
{
std::swap(x1, y1);
std::swap(x2, y2);
vtkm::Swap(x1, y1);
vtkm::Swap(x2, y2);
}
// Ensure we are always going from left to right
if (x1 > x2)
{
std::swap(x1, x2);
std::swap(y1, y2);
std::swap(z1, z2);
vtkm::Swap(x1, x2);
vtkm::Swap(y1, y2);
vtkm::Swap(z1, z2);
}
vtkm::Float32 dx = x2 - x1;