mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-16 17:22:55 +00:00
Add in a serial device adapter and required supporting classes.
We now can verify that the array handle is usable by a device adapter.
This commit is contained in:
parent
a94abd7a71
commit
c2101b8ffc
144
vtkm/cont/ArrayHandleCounting.h
Normal file
144
vtkm/cont/ArrayHandleCounting.h
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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 2014 Sandia Corporation.
|
||||||
|
// Copyright 2014 UT-Battelle, LLC.
|
||||||
|
// Copyright 2014. Los Alamos National Security
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// 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 vtkm_cont_ArrayHandleCounting_h
|
||||||
|
#define vtkm_cont_ArrayHandleCounting_h
|
||||||
|
|
||||||
|
#include <vtkm/cont/ArrayContainerControlImplicit.h>
|
||||||
|
#include <vtkm/cont/ArrayHandle.h>
|
||||||
|
#include <vtkm/cont/internal/IteratorFromArrayPortal.h>
|
||||||
|
|
||||||
|
namespace vtkm {
|
||||||
|
namespace cont {
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
/// \brief An implicit array portal that returns an counting value.
|
||||||
|
template <class CountingValueType>
|
||||||
|
class ArrayPortalCounting
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef CountingValueType ValueType;
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT_EXPORT
|
||||||
|
ArrayPortalCounting() :
|
||||||
|
StartingValue(),
|
||||||
|
NumberOfValues(0)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT_EXPORT
|
||||||
|
ArrayPortalCounting(ValueType startingValue, vtkm::Id numValues) :
|
||||||
|
StartingValue(startingValue),
|
||||||
|
NumberOfValues(numValues)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
template<typename OtherValueType>
|
||||||
|
VTKM_EXEC_CONT_EXPORT
|
||||||
|
ArrayPortalCounting(const ArrayPortalCounting<OtherValueType> &src)
|
||||||
|
: StartingValue(src.StartingValue),
|
||||||
|
NumberOfValues(src.NumberOfValues)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
template<typename OtherValueType>
|
||||||
|
VTKM_EXEC_CONT_EXPORT
|
||||||
|
ArrayPortalCounting<ValueType> &operator=(
|
||||||
|
const ArrayPortalCounting<OtherValueType> &src)
|
||||||
|
{
|
||||||
|
this->StartingValue = src.StartingValue;
|
||||||
|
this->NumberOfValues = src.NumberOfValues;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT_EXPORT
|
||||||
|
vtkm::Id GetNumberOfValues() const { return this->NumberOfValues; }
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT_EXPORT
|
||||||
|
ValueType Get(vtkm::Id index) const { return StartingValue+index; }
|
||||||
|
|
||||||
|
typedef vtkm::cont::internal::IteratorFromArrayPortal<
|
||||||
|
ArrayPortalCounting < CountingValueType> > IteratorType;
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
IteratorType GetIteratorBegin() const
|
||||||
|
{
|
||||||
|
return IteratorType(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
IteratorType GetIteratorEnd() const
|
||||||
|
{
|
||||||
|
return IteratorType(*this, this->NumberOfValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
CountingValueType StartingValue;
|
||||||
|
vtkm::Id NumberOfValues;
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A convenience class that provides a typedef to the appropriate tag for
|
||||||
|
/// a counting array container.
|
||||||
|
template<typename ConstantValueType>
|
||||||
|
struct ArrayHandleCountingTraits
|
||||||
|
{
|
||||||
|
typedef vtkm::cont::ArrayContainerControlTagImplicit<
|
||||||
|
vtkm::cont::internal::ArrayPortalCounting<ConstantValueType> > Tag;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
/// ArrayHandleCountings is a specialization of ArrayHandle. By default it
|
||||||
|
/// contains a increment value, that is increment for each step between zero
|
||||||
|
/// and the passed in length
|
||||||
|
template <typename CountingValueType>
|
||||||
|
class ArrayHandleCounting
|
||||||
|
: public vtkm::cont::ArrayHandle <
|
||||||
|
CountingValueType,
|
||||||
|
typename internal::ArrayHandleCountingTraits<CountingValueType>::Tag
|
||||||
|
>
|
||||||
|
{
|
||||||
|
typedef vtkm::cont::ArrayHandle <
|
||||||
|
CountingValueType,
|
||||||
|
typename internal::ArrayHandleCountingTraits<CountingValueType>::Tag
|
||||||
|
> Superclass;
|
||||||
|
public:
|
||||||
|
|
||||||
|
ArrayHandleCounting(CountingValueType startingValue, vtkm::Id length)
|
||||||
|
:Superclass(typename Superclass::PortalConstControl(startingValue, length))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayHandleCounting():Superclass() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A convenience function for creating an ArrayHandleCounting. It takes the
|
||||||
|
/// value to start counting from and and the number of times to increment.
|
||||||
|
template<typename CountingValueType>
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
vtkm::cont::ArrayHandleCounting<CountingValueType>
|
||||||
|
make_ArrayHandleCounting(CountingValueType startingValue,
|
||||||
|
vtkm::Id length)
|
||||||
|
{
|
||||||
|
return vtkm::cont::ArrayHandleCounting<CountingValueType>(startingValue,
|
||||||
|
length);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace vtkm::cont
|
||||||
|
|
||||||
|
#endif //vtkm_cont_ArrayHandleCounting_h
|
@ -27,6 +27,8 @@ set(headers
|
|||||||
ArrayHandle.h
|
ArrayHandle.h
|
||||||
ArrayPortal.h
|
ArrayPortal.h
|
||||||
Assert.h
|
Assert.h
|
||||||
|
DeviceAdapter.h
|
||||||
|
DeviceAdapterSerial.h
|
||||||
Error.h
|
Error.h
|
||||||
ErrorControl.h
|
ErrorControl.h
|
||||||
ErrorControlAssert.h
|
ErrorControlAssert.h
|
||||||
|
73
vtkm/cont/DeviceAdapter.h
Normal file
73
vtkm/cont/DeviceAdapter.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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 2014 Sandia Corporation.
|
||||||
|
// Copyright 2014 UT-Battelle, LLC.
|
||||||
|
// Copyright 2014. Los Alamos National Security
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// 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 vtkm_cont_DeviceAdapter_h
|
||||||
|
#define vtkm_cont_DeviceAdapter_h
|
||||||
|
|
||||||
|
// These are listed in non-alphabetical order because this is the conceptual
|
||||||
|
// order in which the sub-files are loaded. (But the compile should still
|
||||||
|
// succeed of the order is changed.)
|
||||||
|
|
||||||
|
#include <vtkm/cont/internal/DeviceAdapterTag.h>
|
||||||
|
#include <vtkm/cont/internal/ArrayManagerExecution.h>
|
||||||
|
#include <vtkm/cont/internal/DeviceAdapterAlgorithm.h>
|
||||||
|
|
||||||
|
namespace vtkm {
|
||||||
|
namespace cont {
|
||||||
|
|
||||||
|
#ifdef VTKM_DOXYGEN_ONLY
|
||||||
|
/// \brief A tag specifying the interface between the control and execution environments.
|
||||||
|
///
|
||||||
|
/// A DeviceAdapter tag specifies a set of functions and classes that provide
|
||||||
|
/// mechanisms to run algorithms on a type of parallel device. The tag
|
||||||
|
/// DeviceAdapterTag___ does not actually exist. Rather, this documentation is
|
||||||
|
/// provided to describe the interface for a DeviceAdapter. Loading the
|
||||||
|
/// dax/cont/DeviceAdapter.h header file will set a default device adapter
|
||||||
|
/// appropriate for the current compile environment. You can specify the
|
||||||
|
/// default device adapter by first setting the \c VTKM_DEVICE_ADAPTER macro.
|
||||||
|
/// Valid values for \c VTKM_DEVICE_ADAPTER are the following:
|
||||||
|
///
|
||||||
|
/// \li \c VTKM_DEVICE_ADAPTER_SERIAL Runs all algorithms in serial. Can be
|
||||||
|
/// helpful for debugging.
|
||||||
|
/// \li \c VTKM_DEVICE_ADAPTER_CUDA Dispatches and runs algorithms on a GPU
|
||||||
|
/// using CUDA. Must be compiling with a CUDA compiler (nvcc).
|
||||||
|
/// \li \c VTKM_DEVICE_ADAPTER_OPENMP Dispatches an algorithm over multiple
|
||||||
|
/// CPU cores using OpenMP compiler directives. Must be compiling with an
|
||||||
|
/// OpenMP-compliant compiler with OpenMP pragmas enabled.
|
||||||
|
/// \li \c VTKM_DEVICE_ADAPTER_TBB Dispatches and runs algorithms on multiple
|
||||||
|
/// threads using the Intel Threading Building Blocks (TBB) libraries. Must
|
||||||
|
/// have the TBB headers available and the resulting code must be linked with
|
||||||
|
/// the TBB libraries.
|
||||||
|
///
|
||||||
|
/// See the ArrayManagerExecution.h and DeviceAdapterAlgorithm.h files for
|
||||||
|
/// documentation on all the functions and classes that must be
|
||||||
|
/// overloaded/specialized to create a new device adapter.
|
||||||
|
///
|
||||||
|
struct DeviceAdapterTag___ { };
|
||||||
|
#endif //VTKM_DOXYGEN_ONLY
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
} // namespace internal
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace vtkm::cont
|
||||||
|
|
||||||
|
|
||||||
|
#endif //vtkm_cont_DeviceAdapter_h
|
27
vtkm/cont/DeviceAdapterSerial.h
Normal file
27
vtkm/cont/DeviceAdapterSerial.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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 2014 Sandia Corporation.
|
||||||
|
// Copyright 2014 UT-Battelle, LLC.
|
||||||
|
// Copyright 2014. Los Alamos National Security
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// 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 vtkm_cont_DeviceAdapterSerial_h
|
||||||
|
#define vtkm_cont_DeviceAdapterSerial_h
|
||||||
|
|
||||||
|
#include <vtkm/cont/internal/DeviceAdapterTagSerial.h>
|
||||||
|
#include <vtkm/cont/internal/ArrayManagerExecutionSerial.h>
|
||||||
|
#include <vtkm/cont/internal/DeviceAdapterAlgorithmSerial.h>
|
||||||
|
|
||||||
|
#endif //vtkm_cont_DeviceAdapterSerial_h
|
@ -26,6 +26,13 @@ set(headers
|
|||||||
ArrayPortalFromIterators.h
|
ArrayPortalFromIterators.h
|
||||||
ArrayPortalShrink.h
|
ArrayPortalShrink.h
|
||||||
ArrayTransfer.h
|
ArrayTransfer.h
|
||||||
|
DeviceAdapterAlgorithm.h
|
||||||
|
DeviceAdapterAlgorithmGeneral.h
|
||||||
|
DeviceAdapterAlgorithmSerial.h
|
||||||
|
DeviceAdapterError.h
|
||||||
|
DeviceAdapterTag.h
|
||||||
|
DeviceAdapterTagSerial.h
|
||||||
|
IteratorFromArrayPortal.h
|
||||||
)
|
)
|
||||||
|
|
||||||
vtkm_declare_headers(${headers})
|
vtkm_declare_headers(${headers})
|
||||||
|
404
vtkm/cont/internal/DeviceAdapterAlgorithm.h
Normal file
404
vtkm/cont/internal/DeviceAdapterAlgorithm.h
Normal file
@ -0,0 +1,404 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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 2014 Sandia Corporation.
|
||||||
|
// Copyright 2014 UT-Battelle, LLC.
|
||||||
|
// Copyright 2014. Los Alamos National Security
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// 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 vtkm_cont_internal_DeviceAdapterAlgorithm_h
|
||||||
|
#define vtkm_cont_internal_DeviceAdapterAlgorithm_h
|
||||||
|
|
||||||
|
#include <vtkm/Types.h>
|
||||||
|
|
||||||
|
#include <vtkm/cont/internal/ArrayManagerExecution.h>
|
||||||
|
#include <vtkm/cont/internal/DeviceAdapterTag.h>
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <limits.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace vtkm {
|
||||||
|
namespace cont {
|
||||||
|
|
||||||
|
/// \brief Struct containing device adapter algorithms.
|
||||||
|
///
|
||||||
|
/// This struct, templated on the device adapter tag, comprises static methods
|
||||||
|
/// that implement the algorithms provided by the device adapter. The default
|
||||||
|
/// struct is not implemented. Device adapter implementations must specialize
|
||||||
|
/// the template.
|
||||||
|
///
|
||||||
|
template<class DeviceAdapterTag>
|
||||||
|
struct DeviceAdapterAlgorithm
|
||||||
|
#ifdef VTKM_DOXYGEN_ONLY
|
||||||
|
{
|
||||||
|
/// \brief Copy the contents of one ArrayHandle to another
|
||||||
|
///
|
||||||
|
/// Copies the contents of \c input to \c output. The array \c to will be
|
||||||
|
/// allocated to the appropriate size.
|
||||||
|
///
|
||||||
|
template<typename T, class CIn, class COut>
|
||||||
|
VTKM_CONT_EXPORT static void Copy(
|
||||||
|
const vtkm::cont::ArrayHandle<T, CIn, DeviceAdapterTag> &input,
|
||||||
|
vtkm::cont::ArrayHandle<T, COut, DeviceAdapterTag> &output);
|
||||||
|
|
||||||
|
/// \brief Output is the first index in input for each item in values that wouldn't alter the ordering of input
|
||||||
|
///
|
||||||
|
/// LowerBounds is a vectorized search. From each value in \c values it finds
|
||||||
|
/// the first place the item can be inserted in the ordered \c input array and
|
||||||
|
/// stores the index in \c output.
|
||||||
|
///
|
||||||
|
/// \par Requirements:
|
||||||
|
/// \arg \c input must already be sorted
|
||||||
|
///
|
||||||
|
template<typename T, class CIn, class CVal, class COut>
|
||||||
|
VTKM_CONT_EXPORT static void LowerBounds(
|
||||||
|
const vtkm::cont::ArrayHandle<T,CIn,DeviceAdapterTag>& input,
|
||||||
|
const vtkm::cont::ArrayHandle<T,CVal,DeviceAdapterTag>& values,
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id,COut,DeviceAdapterTag>& output);
|
||||||
|
|
||||||
|
/// \brief Output is the first index in input for each item in values that wouldn't alter the ordering of input
|
||||||
|
///
|
||||||
|
/// LowerBounds is a vectorized search. From each value in \c values it finds
|
||||||
|
/// the first place the item can be inserted in the ordered \c input array and
|
||||||
|
/// stores the index in \c output. Uses the custom comparison functor to
|
||||||
|
/// determine the correct location for each item.
|
||||||
|
///
|
||||||
|
/// \par Requirements:
|
||||||
|
/// \arg \c input must already be sorted
|
||||||
|
///
|
||||||
|
template<typename T, class CIn, class CVal, class COut, class Compare>
|
||||||
|
VTKM_CONT_EXPORT static void LowerBounds(
|
||||||
|
const vtkm::cont::ArrayHandle<T,CIn,DeviceAdapterTag>& input,
|
||||||
|
const vtkm::cont::ArrayHandle<T,CVal,DeviceAdapterTag>& values,
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id,COut,DeviceAdapterTag>& output,
|
||||||
|
Compare comp);
|
||||||
|
|
||||||
|
/// \brief A special version of LowerBounds that does an in place operation.
|
||||||
|
///
|
||||||
|
/// This version of lower bounds performs an in place operation where each
|
||||||
|
/// value in the \c values_output array is replaced by the index in \c input
|
||||||
|
/// where it occurs. Because this is an in place operation, the type of the
|
||||||
|
/// arrays is limited to vtkm::Id.
|
||||||
|
///
|
||||||
|
template<class CIn, class COut>
|
||||||
|
VTKM_CONT_EXPORT static void LowerBounds(
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::Id,CIn,DeviceAdapterTag>& input,
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id,COut,DeviceAdapterTag>& values_output);
|
||||||
|
|
||||||
|
/// \brief Compute an inclusive prefix sum operation on the input ArrayHandle.
|
||||||
|
///
|
||||||
|
/// Computes an inclusive prefix sum operation on the \c input ArrayHandle,
|
||||||
|
/// storing the results in the \c output ArrayHandle. InclusiveScan is
|
||||||
|
/// similiar to the stl partial sum function, exception that InclusiveScan
|
||||||
|
/// doesn't do a serial sumnation. This means that if you have defined a
|
||||||
|
/// custom plus operator for T it must be associative, or you will get
|
||||||
|
/// inconsistent results. When the input and output ArrayHandles are the same
|
||||||
|
/// ArrayHandle the operation will be done inplace.
|
||||||
|
///
|
||||||
|
/// \return The total sum.
|
||||||
|
///
|
||||||
|
template<typename T, class CIn, class COut>
|
||||||
|
VTKM_CONT_EXPORT static T ScanInclusive(
|
||||||
|
const vtkm::cont::ArrayHandle<T,CIn,DeviceAdapterTag> &input,
|
||||||
|
vtkm::cont::ArrayHandle<T,COut,DeviceAdapterTag>& output);
|
||||||
|
|
||||||
|
/// \brief Compute an exclusive prefix sum operation on the input ArrayHandle.
|
||||||
|
///
|
||||||
|
/// Computes an exclusive prefix sum operation on the \c input ArrayHandle,
|
||||||
|
/// storing the results in the \c output ArrayHandle. ExclusiveScan is
|
||||||
|
/// similiar to the stl partial sum function, exception that ExclusiveScan
|
||||||
|
/// doesn't do a serial sumnation. This means that if you have defined a
|
||||||
|
/// custom plus operator for T it must be associative, or you will get
|
||||||
|
/// inconsistent results. When the input and output ArrayHandles are the same
|
||||||
|
/// ArrayHandle the operation will be done inplace.
|
||||||
|
///
|
||||||
|
/// \return The total sum.
|
||||||
|
///
|
||||||
|
template<typename T, class CIn, class COut>
|
||||||
|
VTKM_CONT_EXPORT static T ScanExclusive(
|
||||||
|
const vtkm::cont::ArrayHandle<T,CIn,DeviceAdapterTag> &input,
|
||||||
|
vtkm::cont::ArrayHandle<T,COut,DeviceAdapterTag>& output);
|
||||||
|
|
||||||
|
/// \brief Schedule many instances of a function to run on concurrent threads.
|
||||||
|
///
|
||||||
|
/// Calls the \c functor on several threads. This is the function used in the
|
||||||
|
/// control environment to spawn activity in the execution environment. \c
|
||||||
|
/// functor is a function-like object that can be invoked with the calling
|
||||||
|
/// specification <tt>functor(vtkm::Id index)</tt>. It also has a method called
|
||||||
|
/// from the control environment to establish the error reporting buffer with
|
||||||
|
/// the calling specification <tt>functor.SetErrorMessageBuffer(const
|
||||||
|
/// vtkm::exec::internal::ErrorMessageBuffer &errorMessage)</tt>. This object
|
||||||
|
/// can be stored in the functor's state such that if RaiseError is called on
|
||||||
|
/// it in the execution environment, an ErrorExecution will be thrown from
|
||||||
|
/// Schedule.
|
||||||
|
///
|
||||||
|
/// The argument of the invoked functor uniquely identifies the thread or
|
||||||
|
/// instance of the invocation. There should be one invocation for each index
|
||||||
|
/// in the range [0, \c numInstances].
|
||||||
|
///
|
||||||
|
template<class Functor>
|
||||||
|
VTKM_CONT_EXPORT static void Schedule(Functor functor,
|
||||||
|
vtkm::Id numInstances);
|
||||||
|
|
||||||
|
/// \brief Schedule many instances of a function to run on concurrent threads.
|
||||||
|
///
|
||||||
|
/// Calls the \c functor on several threads. This is the function used in the
|
||||||
|
/// control environment to spawn activity in the execution environment. \c
|
||||||
|
/// functor is a function-like object that can be invoked with the calling
|
||||||
|
/// specification <tt>functor(vtkm::Id3 index)</tt> or <tt>functor(vtkm::Id
|
||||||
|
/// index)</tt>. It also has a method called from the control environment to
|
||||||
|
/// establish the error reporting buffer with the calling specification
|
||||||
|
/// <tt>functor.SetErrorMessageBuffer(const
|
||||||
|
/// vtkm::exec::internal::ErrorMessageBuffer &errorMessage)</tt>. This object
|
||||||
|
/// can be stored in the functor's state such that if RaiseError is called on
|
||||||
|
/// it in the execution environment, an ErrorExecution will be thrown from
|
||||||
|
/// Schedule.
|
||||||
|
///
|
||||||
|
/// The argument of the invoked functor uniquely identifies the thread or
|
||||||
|
/// instance of the invocation. It is at the device adapter's discretion
|
||||||
|
/// whether to schedule on 1D or 3D indices, so the functor should have an
|
||||||
|
/// operator() overload for each index type. If 3D indices are used, there is
|
||||||
|
/// one invocation for every i, j, k value between [0, 0, 0] and \c rangeMax.
|
||||||
|
/// If 1D indices are used, this Schedule behaves as if <tt>Schedule(functor,
|
||||||
|
/// rangeMax[0]*rangeMax[1]*rangeMax[2])</tt> were called.
|
||||||
|
///
|
||||||
|
template<class Functor, class IndiceType>
|
||||||
|
VTKM_CONT_EXPORT static void Schedule(Functor functor,
|
||||||
|
vtkm::Id3 rangeMax);
|
||||||
|
|
||||||
|
/// \brief Unstable ascending sort of input array.
|
||||||
|
///
|
||||||
|
/// Sorts the contents of \c values so that they in ascending value. Doesn't
|
||||||
|
/// guarantee stability
|
||||||
|
///
|
||||||
|
template<typename T, class Container>
|
||||||
|
VTKM_CONT_EXPORT static void Sort(
|
||||||
|
vtkm::cont::ArrayHandle<T,Container,DeviceAdapterTag> &values);
|
||||||
|
|
||||||
|
/// \brief Unstable ascending sort of input array.
|
||||||
|
///
|
||||||
|
/// Sorts the contents of \c values so that they in ascending value based
|
||||||
|
/// on the custom compare functor.
|
||||||
|
///
|
||||||
|
template<typename T, class Container, class Compare>
|
||||||
|
VTKM_CONT_EXPORT static void Sort(
|
||||||
|
vtkm::cont::ArrayHandle<T,Container,DeviceAdapterTag> &values,
|
||||||
|
Compare comp);
|
||||||
|
|
||||||
|
/// \brief Performs stream compaction to remove unwanted elements in the input array. Output becomes the index values of input that are valid.
|
||||||
|
///
|
||||||
|
/// Calls the parallel primitive function of stream compaction on the \c
|
||||||
|
/// input to remove unwanted elements. The result of the stream compaction is
|
||||||
|
/// placed in \c output. The \c input values are used as the stream
|
||||||
|
/// compaction stencil while \c input indices are used as the values to place
|
||||||
|
/// into \c ouput. The size of \c output will be modified after this call as
|
||||||
|
/// we can't know the number of elements that will be removed by the stream
|
||||||
|
/// compaction algorithm.
|
||||||
|
///
|
||||||
|
template<typename T, class CStencil, class COut>
|
||||||
|
VTKM_CONT_EXPORT static void StreamCompact(
|
||||||
|
const vtkm::cont::ArrayHandle<T,CStencil,DeviceAdapterTag> &stencil,
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id,COut,DeviceAdapterTag> &output);
|
||||||
|
|
||||||
|
/// \brief Performs stream compaction to remove unwanted elements in the input array.
|
||||||
|
///
|
||||||
|
/// Calls the parallel primitive function of stream compaction on the \c
|
||||||
|
/// input to remove unwanted elements. The result of the stream compaction is
|
||||||
|
/// placed in \c output. The values in \c stencil are used as the stream
|
||||||
|
/// compaction stencil while \c input values are placed into \c ouput. The
|
||||||
|
/// size of \c output will be modified after this call as we can't know the
|
||||||
|
/// number of elements that will be removed by the stream compaction
|
||||||
|
/// algorithm.
|
||||||
|
///
|
||||||
|
template<typename T, typename U, class CIn, class CStencil, class COut>
|
||||||
|
VTKM_CONT_EXPORT static void StreamCompact(
|
||||||
|
const vtkm::cont::ArrayHandle<T,CIn,DeviceAdapterTag> &input,
|
||||||
|
const vtkm::cont::ArrayHandle<U,CStencil,DeviceAdapterTag> &stencil,
|
||||||
|
vtkm::cont::ArrayHandle<T,COut,DeviceAdapterTag> &output);
|
||||||
|
|
||||||
|
/// \brief Completes any asynchronous operations running on the device.
|
||||||
|
///
|
||||||
|
/// Waits for any asynchronous operations running on the device to complete.
|
||||||
|
///
|
||||||
|
VTKM_CONT_EXPORT static void Synchronize();
|
||||||
|
|
||||||
|
/// \brief Reduce an array to only the unique values it contains
|
||||||
|
///
|
||||||
|
/// Removes all duplicate values in \c values that are adjacent to each
|
||||||
|
/// other. Which means you should sort the input array unless you want
|
||||||
|
/// duplicate values that aren't adjacent. Note the values array size might
|
||||||
|
/// be modified by this operation.
|
||||||
|
///
|
||||||
|
template<typename T, class Container>
|
||||||
|
VTKM_CONT_EXPORT static void Unique(
|
||||||
|
vtkm::cont::ArrayHandle<T,Container,DeviceAdapterTag>& values);
|
||||||
|
|
||||||
|
/// \brief Reduce an array to only the unique values it contains
|
||||||
|
///
|
||||||
|
/// Removes all duplicate values in \c values that are adjacent to each
|
||||||
|
/// other. Which means you should sort the input array unless you want
|
||||||
|
/// duplicate values that aren't adjacent. Note the values array size might
|
||||||
|
/// be modified by this operation.
|
||||||
|
///
|
||||||
|
/// Uses the custom binary predicate Comparison to determine if something
|
||||||
|
/// is unique. The predicate must return true if the two items are the same.
|
||||||
|
///
|
||||||
|
template<typename T, class Container, class Compare>
|
||||||
|
VTKM_CONT_EXPORT static void Unique(
|
||||||
|
vtkm::cont::ArrayHandle<T,Container,DeviceAdapterTag>& values,
|
||||||
|
Compare comp);
|
||||||
|
|
||||||
|
/// \brief Output is the last index in input for each item in values that wouldn't alter the ordering of input
|
||||||
|
///
|
||||||
|
/// UpperBounds is a vectorized search. From each value in \c values it finds
|
||||||
|
/// the last place the item can be inserted in the ordered \c input array and
|
||||||
|
/// stores the index in \c output.
|
||||||
|
///
|
||||||
|
/// \par Requirements:
|
||||||
|
/// \arg \c input must already be sorted
|
||||||
|
///
|
||||||
|
template<typename T, class CIn, class CVal, class COut>
|
||||||
|
VTKM_CONT_EXPORT static void UpperBounds(
|
||||||
|
const vtkm::cont::ArrayHandle<T,CIn,DeviceAdapterTag___>& input,
|
||||||
|
const vtkm::cont::ArrayHandle<T,CVal,DeviceAdapterTag___>& values,
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id,COut,DeviceAdapterTag___>& output);
|
||||||
|
|
||||||
|
/// \brief Output is the last index in input for each item in values that wouldn't alter the ordering of input
|
||||||
|
///
|
||||||
|
/// LowerBounds is a vectorized search. From each value in \c values it finds
|
||||||
|
/// the last place the item can be inserted in the ordered \c input array and
|
||||||
|
/// stores the index in \c output. Uses the custom comparison functor to
|
||||||
|
/// determine the correct location for each item.
|
||||||
|
///
|
||||||
|
/// \par Requirements:
|
||||||
|
/// \arg \c input must already be sorted
|
||||||
|
///
|
||||||
|
template<typename T, class CIn, class CVal, class COut, class Compare>
|
||||||
|
VTKM_CONT_EXPORT static void UpperBounds(
|
||||||
|
const vtkm::cont::ArrayHandle<T,CIn,DeviceAdapterTag>& input,
|
||||||
|
const vtkm::cont::ArrayHandle<T,CVal,DeviceAdapterTag>& values,
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id,COut,DeviceAdapterTag>& output,
|
||||||
|
Compare comp);
|
||||||
|
|
||||||
|
/// \brief A special version of UpperBounds that does an in place operation.
|
||||||
|
///
|
||||||
|
/// This version of lower bounds performs an in place operation where each
|
||||||
|
/// value in the \c values_output array is replaced by the last index in
|
||||||
|
/// \c input where it occurs. Because this is an in place operation, the type
|
||||||
|
/// of the arrays is limited to vtkm::Id.
|
||||||
|
///
|
||||||
|
template<class CIn, class COut>
|
||||||
|
VTKM_CONT_EXPORT static void UpperBounds(
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::Id,CIn,DeviceAdapterTag___>& input,
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id,COut,DeviceAdapterTag___>& values_output);
|
||||||
|
};
|
||||||
|
#else // VTKM_DOXYGEN_ONLY
|
||||||
|
;
|
||||||
|
#endif //VTKM_DOXYGEN_ONLY
|
||||||
|
|
||||||
|
/// \brief Class providing a device-specific timer.
|
||||||
|
///
|
||||||
|
/// The class provide the actual implementation used by vtkm::cont::Timer.
|
||||||
|
/// A default implementation is provided but device adapters should provide
|
||||||
|
/// one (in conjunction with DeviceAdapterAlgorithm) where appropriate. The
|
||||||
|
/// interface for this class is exactly the same as vtkm::cont::Timer.
|
||||||
|
///
|
||||||
|
template<class DeviceAdapterTag>
|
||||||
|
class DeviceAdapterTimerImplementation
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/// When a timer is constructed, all threads are synchronized and the
|
||||||
|
/// current time is marked so that GetElapsedTime returns the number of
|
||||||
|
/// seconds elapsed since the construction.
|
||||||
|
VTKM_CONT_EXPORT DeviceAdapterTimerImplementation()
|
||||||
|
{
|
||||||
|
this->Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resets the timer. All further calls to GetElapsedTime will report the
|
||||||
|
/// number of seconds elapsed since the call to this. This method
|
||||||
|
/// synchronizes all asynchronous operations.
|
||||||
|
///
|
||||||
|
VTKM_CONT_EXPORT void Reset()
|
||||||
|
{
|
||||||
|
this->StartTime = this->GetCurrentTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the elapsed time in seconds between the construction of this
|
||||||
|
/// class or the last call to Reset and the time this function is called. The
|
||||||
|
/// time returned is measured in wall time. GetElapsedTime may be called any
|
||||||
|
/// number of times to get the progressive time. This method synchronizes all
|
||||||
|
/// asynchronous operations.
|
||||||
|
///
|
||||||
|
VTKM_CONT_EXPORT vtkm::Scalar GetElapsedTime()
|
||||||
|
{
|
||||||
|
TimeStamp currentTime = this->GetCurrentTime();
|
||||||
|
|
||||||
|
vtkm::Scalar elapsedTime;
|
||||||
|
elapsedTime = currentTime.Seconds - this->StartTime.Seconds;
|
||||||
|
elapsedTime += ((currentTime.Microseconds - this->StartTime.Microseconds)
|
||||||
|
/vtkm::Scalar(1000000));
|
||||||
|
|
||||||
|
return elapsedTime;
|
||||||
|
}
|
||||||
|
struct TimeStamp {
|
||||||
|
vtkm::internal::Int64Type Seconds;
|
||||||
|
vtkm::internal::Int64Type Microseconds;
|
||||||
|
};
|
||||||
|
TimeStamp StartTime;
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT TimeStamp GetCurrentTime()
|
||||||
|
{
|
||||||
|
vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapterTag>
|
||||||
|
::Synchronize();
|
||||||
|
|
||||||
|
TimeStamp retval;
|
||||||
|
#ifdef _WIN32
|
||||||
|
timeb currentTime;
|
||||||
|
::ftime(¤tTime);
|
||||||
|
retval.Seconds = currentTime.time;
|
||||||
|
retval.Microseconds = 1000*currentTime.millitm;
|
||||||
|
#else
|
||||||
|
timeval currentTime;
|
||||||
|
gettimeofday(¤tTime, NULL);
|
||||||
|
retval.Seconds = currentTime.tv_sec;
|
||||||
|
retval.Microseconds = currentTime.tv_usec;
|
||||||
|
#endif
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace vtkm::cont
|
||||||
|
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// These includes are intentionally placed here after the declaration of the
|
||||||
|
// DeviceAdapterAlgorithm template prototype, which all the implementations
|
||||||
|
// need.
|
||||||
|
|
||||||
|
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_SERIAL
|
||||||
|
#include <vtkm/cont/internal/DeviceAdapterAlgorithmSerial.h>
|
||||||
|
// #elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_CUDA
|
||||||
|
// #include <vtkm/cuda/cont/internal/DeviceAdapterAlgorithmCuda.h>
|
||||||
|
// #elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_OPENMP
|
||||||
|
// #include <vtkm/openmp/cont/internal/DeviceAdapterAlgorithmOpenMP.h>
|
||||||
|
// #elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_TBB
|
||||||
|
// #include <vtkm/tbb/cont/internal/DeviceAdapterAlgorithmTBB.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif //vtkm_cont_DeviceAdapterAlgorithm_h
|
993
vtkm/cont/internal/DeviceAdapterAlgorithmGeneral.h
Normal file
993
vtkm/cont/internal/DeviceAdapterAlgorithmGeneral.h
Normal file
@ -0,0 +1,993 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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 2014 Sandia Corporation.
|
||||||
|
// Copyright 2014 UT-Battelle, LLC.
|
||||||
|
// Copyright 2014. Los Alamos National Security
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// 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 vtkm_cont_internal_DeviceAdapterAlgorithmGeneral_h
|
||||||
|
#define vtkm_cont_internal_DeviceAdapterAlgorithmGeneral_h
|
||||||
|
|
||||||
|
#include <vtkm/cont/ArrayHandle.h>
|
||||||
|
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||||
|
#include <vtkm/cont/ArrayContainerControlBasic.h>
|
||||||
|
|
||||||
|
#include <vtkm/exec/internal/ErrorMessageBuffer.h>
|
||||||
|
#include <vtkm/exec/internal/WorkletBase.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
/// Predicate that takes a single argument \c x, and returns
|
||||||
|
/// True if it isn't the identity of the Type \p T.
|
||||||
|
template<typename T>
|
||||||
|
struct not_default_constructor
|
||||||
|
{
|
||||||
|
VTKM_EXEC_CONT_EXPORT bool operator()(const T &x)
|
||||||
|
{
|
||||||
|
return (x != T());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace vtkm {
|
||||||
|
namespace cont {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
/// \brief
|
||||||
|
///
|
||||||
|
/// This struct provides algorithms that implement "general" device adapter
|
||||||
|
/// algorithms. If a device adapter provides implementations for Schedule,
|
||||||
|
/// and Synchronize, the rest of the algorithms can be implemented by calling
|
||||||
|
/// these functions.
|
||||||
|
///
|
||||||
|
/// It should be noted that we recommend that you also implement Sort,
|
||||||
|
/// ScanInclusive, and ScanExclusive for improved performance.
|
||||||
|
///
|
||||||
|
/// An easy way to implement the DeviceAdapterAlgorithm specialization is to
|
||||||
|
/// subclass this and override the implementation of methods as necessary.
|
||||||
|
/// As an example, the code would look something like this.
|
||||||
|
///
|
||||||
|
/// \code{.cpp}
|
||||||
|
/// template<>
|
||||||
|
/// struct DeviceAdapterAlgorithm<DeviceAdapterTagFoo>
|
||||||
|
/// : DeviceAdapterAlgorithmGeneral<DeviceAdapterAlgorithm<DeviceAdapterTagFoo>,
|
||||||
|
/// DeviceAdapterTagFoo>
|
||||||
|
/// {
|
||||||
|
/// template<class Functor>
|
||||||
|
/// VTKM_CONT_EXPORT static void Schedule(Functor functor,
|
||||||
|
/// vtkm::Id numInstances)
|
||||||
|
/// {
|
||||||
|
/// ...
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// template<class Functor>
|
||||||
|
/// VTKM_CONT_EXPORT static void Schedule(Functor functor,
|
||||||
|
/// vtkm::Id3 maxRange)
|
||||||
|
/// {
|
||||||
|
/// ...
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// VTKM_CONT_EXPORT static void Synchronize()
|
||||||
|
/// {
|
||||||
|
/// ...
|
||||||
|
/// }
|
||||||
|
/// };
|
||||||
|
/// \endcode
|
||||||
|
///
|
||||||
|
/// You might note that DeviceAdapterAlgorithmGeneral has two template
|
||||||
|
/// parameters that are redundant. Although the first parameter, the class for
|
||||||
|
/// the actual DeviceAdapterAlgorithm class containing Schedule, and
|
||||||
|
/// Synchronize is the same as DeviceAdapterAlgorithm<DeviceAdapterTag>, it is
|
||||||
|
/// made a separate template parameter to avoid a recursive dependence between
|
||||||
|
/// DeviceAdapterAlgorithmGeneral.h and DeviceAdapterAlgorithm.h
|
||||||
|
///
|
||||||
|
template<class DerivedAlgorithm, class DeviceAdapterTag>
|
||||||
|
struct DeviceAdapterAlgorithmGeneral
|
||||||
|
{
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Get Execution Value
|
||||||
|
// This method is used internally to get a single element from the execution
|
||||||
|
// array. Might want to expose this and/or allow actual device adapter
|
||||||
|
// implementations to provide one.
|
||||||
|
private:
|
||||||
|
template<typename T, class CIn>
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
static T GetExecutionValue(const vtkm::cont::ArrayHandle<T, CIn> &input,
|
||||||
|
vtkm::Id index)
|
||||||
|
{
|
||||||
|
typedef vtkm::cont::ArrayHandle<T,CIn> InputArrayType;
|
||||||
|
typedef vtkm::cont::ArrayHandle<T,vtkm::cont::ArrayContainerControlTagBasic>
|
||||||
|
OutputArrayType;
|
||||||
|
|
||||||
|
OutputArrayType output;
|
||||||
|
|
||||||
|
CopyKernel<
|
||||||
|
typename InputArrayType::template ExecutionTypes<DeviceAdapterTag>::PortalConst,
|
||||||
|
typename OutputArrayType::template ExecutionTypes<DeviceAdapterTag>::Portal>
|
||||||
|
kernel(input.PrepareForInput(DeviceAdapterTag()),
|
||||||
|
output.PrepareForOutput(1, DeviceAdapterTag()),
|
||||||
|
index);
|
||||||
|
|
||||||
|
DerivedAlgorithm::Schedule(kernel, 1);
|
||||||
|
|
||||||
|
return output.GetPortalConstControl().Get(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Copy
|
||||||
|
private:
|
||||||
|
template<class InputPortalType, class OutputPortalType>
|
||||||
|
struct CopyKernel {
|
||||||
|
InputPortalType InputPortal;
|
||||||
|
OutputPortalType OutputPortal;
|
||||||
|
vtkm::Id InputOffset;
|
||||||
|
vtkm::Id OutputOffset;
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
CopyKernel(InputPortalType inputPortal,
|
||||||
|
OutputPortalType outputPortal,
|
||||||
|
vtkm::Id inputOffset = 0,
|
||||||
|
vtkm::Id outputOffset = 0)
|
||||||
|
: InputPortal(inputPortal),
|
||||||
|
OutputPortal(outputPortal),
|
||||||
|
InputOffset(inputOffset),
|
||||||
|
OutputOffset(outputOffset)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
void operator()(vtkm::Id index) const {
|
||||||
|
this->OutputPortal.Set(
|
||||||
|
index + this->OutputOffset,
|
||||||
|
this->InputPortal.Get(index + this->InputOffset));
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer &)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
template<typename T, class CIn, class COut>
|
||||||
|
VTKM_CONT_EXPORT static void Copy(const vtkm::cont::ArrayHandle<T, CIn> &input,
|
||||||
|
vtkm::cont::ArrayHandle<T, COut> &output)
|
||||||
|
{
|
||||||
|
vtkm::Id arraySize = input.GetNumberOfValues();
|
||||||
|
|
||||||
|
CopyKernel<
|
||||||
|
typename vtkm::cont::ArrayHandle<T,CIn>::template ExecutionTypes<DeviceAdapterTag>::PortalConst,
|
||||||
|
typename vtkm::cont::ArrayHandle<T,COut>::template ExecutionTypes<DeviceAdapterTag>::Portal>
|
||||||
|
kernel(input.PrepareForInput(DeviceAdapterTag()),
|
||||||
|
output.PrepareForOutput(arraySize, DeviceAdapterTag()));
|
||||||
|
|
||||||
|
DerivedAlgorithm::Schedule(kernel, arraySize);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Lower Bounds
|
||||||
|
private:
|
||||||
|
template<class InputPortalType,class ValuesPortalType,class OutputPortalType>
|
||||||
|
struct LowerBoundsKernel {
|
||||||
|
InputPortalType InputPortal;
|
||||||
|
ValuesPortalType ValuesPortal;
|
||||||
|
OutputPortalType OutputPortal;
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
LowerBoundsKernel(InputPortalType inputPortal,
|
||||||
|
ValuesPortalType valuesPortal,
|
||||||
|
OutputPortalType outputPortal)
|
||||||
|
: InputPortal(inputPortal),
|
||||||
|
ValuesPortal(valuesPortal),
|
||||||
|
OutputPortal(outputPortal) { }
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
void operator()(vtkm::Id index) const {
|
||||||
|
// This method assumes that (1) InputPortalType can return working
|
||||||
|
// iterators in the execution environment and that (2) methods not
|
||||||
|
// specified with VTKM_EXEC_EXPORT (such as the STL algorithms) can be
|
||||||
|
// called from the execution environment. Neither one of these is
|
||||||
|
// necessarily true, but it is true for the current uses of this general
|
||||||
|
// function and I don't want to compete with STL if I don't have to.
|
||||||
|
|
||||||
|
typename InputPortalType::IteratorType resultPos =
|
||||||
|
std::lower_bound(this->InputPortal.GetIteratorBegin(),
|
||||||
|
this->InputPortal.GetIteratorEnd(),
|
||||||
|
this->ValuesPortal.Get(index));
|
||||||
|
|
||||||
|
vtkm::Id resultIndex =
|
||||||
|
static_cast<vtkm::Id>(
|
||||||
|
std::distance(this->InputPortal.GetIteratorBegin(), resultPos));
|
||||||
|
this->OutputPortal.Set(index, resultIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer &)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class InputPortalType,class ValuesPortalType,class OutputPortalType,class Compare>
|
||||||
|
struct LowerBoundsComparisonKernel {
|
||||||
|
InputPortalType InputPortal;
|
||||||
|
ValuesPortalType ValuesPortal;
|
||||||
|
OutputPortalType OutputPortal;
|
||||||
|
Compare CompareFunctor;
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
LowerBoundsComparisonKernel(InputPortalType inputPortal,
|
||||||
|
ValuesPortalType valuesPortal,
|
||||||
|
OutputPortalType outputPortal,
|
||||||
|
Compare comp)
|
||||||
|
: InputPortal(inputPortal),
|
||||||
|
ValuesPortal(valuesPortal),
|
||||||
|
OutputPortal(outputPortal),
|
||||||
|
CompareFunctor(comp) { }
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
void operator()(vtkm::Id index) const {
|
||||||
|
// This method assumes that (1) InputPortalType can return working
|
||||||
|
// iterators in the execution environment and that (2) methods not
|
||||||
|
// specified with VTKM_EXEC_EXPORT (such as the STL algorithms) can be
|
||||||
|
// called from the execution environment. Neither one of these is
|
||||||
|
// necessarily true, but it is true for the current uses of this general
|
||||||
|
// function and I don't want to compete with STL if I don't have to.
|
||||||
|
|
||||||
|
typename InputPortalType::IteratorType resultPos =
|
||||||
|
std::lower_bound(this->InputPortal.GetIteratorBegin(),
|
||||||
|
this->InputPortal.GetIteratorEnd(),
|
||||||
|
this->ValuesPortal.Get(index),
|
||||||
|
this->CompareFunctor);
|
||||||
|
|
||||||
|
vtkm::Id resultIndex =
|
||||||
|
static_cast<vtkm::Id>(
|
||||||
|
std::distance(this->InputPortal.GetIteratorBegin(), resultPos));
|
||||||
|
this->OutputPortal.Set(index, resultIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer &)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
template<typename T, class CIn, class CVal, class COut>
|
||||||
|
VTKM_CONT_EXPORT static void LowerBounds(
|
||||||
|
const vtkm::cont::ArrayHandle<T,CIn> &input,
|
||||||
|
const vtkm::cont::ArrayHandle<T,CVal> &values,
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id,COut> &output)
|
||||||
|
{
|
||||||
|
vtkm::Id arraySize = values.GetNumberOfValues();
|
||||||
|
|
||||||
|
LowerBoundsKernel<
|
||||||
|
typename vtkm::cont::ArrayHandle<T,CIn>::template ExecutionTypes<DeviceAdapterTag>::PortalConst,
|
||||||
|
typename vtkm::cont::ArrayHandle<T,CVal>::template ExecutionTypes<DeviceAdapterTag>::PortalConst,
|
||||||
|
typename vtkm::cont::ArrayHandle<vtkm::Id,COut>::template ExecutionTypes<DeviceAdapterTag>::Portal>
|
||||||
|
kernel(input.PrepareForInput(DeviceAdapterTag()),
|
||||||
|
values.PrepareForInput(DeviceAdapterTag()),
|
||||||
|
output.PrepareForOutput(arraySize, DeviceAdapterTag()));
|
||||||
|
|
||||||
|
DerivedAlgorithm::Schedule(kernel, arraySize);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, class CIn, class CVal, class COut, class Compare>
|
||||||
|
VTKM_CONT_EXPORT static void LowerBounds(
|
||||||
|
const vtkm::cont::ArrayHandle<T,CIn> &input,
|
||||||
|
const vtkm::cont::ArrayHandle<T,CVal> &values,
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id,COut> &output,
|
||||||
|
Compare comp)
|
||||||
|
{
|
||||||
|
vtkm::Id arraySize = values.GetNumberOfValues();
|
||||||
|
|
||||||
|
LowerBoundsComparisonKernel<
|
||||||
|
typename vtkm::cont::ArrayHandle<T,CIn>::template ExecutionTypes<DeviceAdapterTag>::PortalConst,
|
||||||
|
typename vtkm::cont::ArrayHandle<T,CVal>::template ExecutionTypes<DeviceAdapterTag>::PortalConst,
|
||||||
|
typename vtkm::cont::ArrayHandle<vtkm::Id,COut>::template ExecutionTypes<DeviceAdapterTag>::Portal,
|
||||||
|
Compare>
|
||||||
|
kernel(input.PrepareForInput(DeviceAdapterTag()),
|
||||||
|
values.PrepareForInput(DeviceAdapterTag()),
|
||||||
|
output.PrepareForOutput(arraySize, DeviceAdapterTag()),
|
||||||
|
comp);
|
||||||
|
|
||||||
|
DerivedAlgorithm::Schedule(kernel, arraySize);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class CIn, class COut>
|
||||||
|
VTKM_CONT_EXPORT static void LowerBounds(
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::Id,CIn> &input,
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id,COut> &values_output)
|
||||||
|
{
|
||||||
|
DeviceAdapterAlgorithmGeneral<
|
||||||
|
DerivedAlgorithm,DeviceAdapterTag>::LowerBounds(input,
|
||||||
|
values_output,
|
||||||
|
values_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Scan Exclusive
|
||||||
|
private:
|
||||||
|
template<typename PortalType>
|
||||||
|
struct SetConstantKernel
|
||||||
|
{
|
||||||
|
typedef typename PortalType::ValueType ValueType;
|
||||||
|
PortalType Portal;
|
||||||
|
ValueType Value;
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
SetConstantKernel(const PortalType &portal, ValueType value)
|
||||||
|
: Portal(portal), Value(value) { }
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
void operator()(vtkm::Id index) const
|
||||||
|
{
|
||||||
|
this->Portal.Set(index, this->Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer &)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
template<typename T, class CIn, class COut>
|
||||||
|
VTKM_CONT_EXPORT static T ScanExclusive(
|
||||||
|
const vtkm::cont::ArrayHandle<T,CIn> &input,
|
||||||
|
vtkm::cont::ArrayHandle<T,COut>& output)
|
||||||
|
{
|
||||||
|
typedef vtkm::cont::ArrayHandle<T,vtkm::cont::ArrayContainerControlTagBasic>
|
||||||
|
TempArrayType;
|
||||||
|
typedef vtkm::cont::ArrayHandle<T,COut> OutputArrayType;
|
||||||
|
|
||||||
|
TempArrayType inclusiveScan;
|
||||||
|
T result = DerivedAlgorithm::ScanInclusive(input, inclusiveScan);
|
||||||
|
|
||||||
|
vtkm::Id numValues = inclusiveScan.GetNumberOfValues();
|
||||||
|
if (numValues < 1)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef typename TempArrayType::template ExecutionTypes<DeviceAdapterTag>
|
||||||
|
::PortalConst SrcPortalType;
|
||||||
|
SrcPortalType srcPortal = inclusiveScan.PrepareForInput(DeviceAdapterTag());
|
||||||
|
|
||||||
|
typedef typename OutputArrayType::template ExecutionTypes<DeviceAdapterTag>
|
||||||
|
::Portal DestPortalType;
|
||||||
|
DestPortalType destPortal = output.PrepareForOutput(numValues,
|
||||||
|
DeviceAdapterTag());
|
||||||
|
|
||||||
|
// Set first value in output (always 0).
|
||||||
|
DerivedAlgorithm::Schedule(
|
||||||
|
SetConstantKernel<DestPortalType>(destPortal,0), 1);
|
||||||
|
// Shift remaining values over by one.
|
||||||
|
DerivedAlgorithm::Schedule(
|
||||||
|
CopyKernel<SrcPortalType,DestPortalType>(srcPortal,
|
||||||
|
destPortal,
|
||||||
|
0,
|
||||||
|
1),
|
||||||
|
numValues - 1);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Scan Inclusive
|
||||||
|
private:
|
||||||
|
template<typename PortalType>
|
||||||
|
struct ScanKernel : vtkm::exec::internal::WorkletBase
|
||||||
|
{
|
||||||
|
PortalType Portal;
|
||||||
|
vtkm::Id Stride;
|
||||||
|
vtkm::Id Offset;
|
||||||
|
vtkm::Id Distance;
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ScanKernel(const PortalType &portal, vtkm::Id stride, vtkm::Id offset)
|
||||||
|
: Portal(portal),
|
||||||
|
Stride(stride),
|
||||||
|
Offset(offset),
|
||||||
|
Distance(stride/2)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
void operator()(vtkm::Id index) const
|
||||||
|
{
|
||||||
|
typedef typename PortalType::ValueType ValueType;
|
||||||
|
|
||||||
|
vtkm::Id leftIndex = this->Offset + index*this->Stride;
|
||||||
|
vtkm::Id rightIndex = leftIndex + this->Distance;
|
||||||
|
|
||||||
|
if (rightIndex < this->Portal.GetNumberOfValues())
|
||||||
|
{
|
||||||
|
ValueType leftValue = this->Portal.Get(leftIndex);
|
||||||
|
ValueType rightValue = this->Portal.Get(rightIndex);
|
||||||
|
this->Portal.Set(rightIndex, leftValue+rightValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
template<typename T, class CIn, class COut>
|
||||||
|
VTKM_CONT_EXPORT static T ScanInclusive(
|
||||||
|
const vtkm::cont::ArrayHandle<T,CIn> &input,
|
||||||
|
vtkm::cont::ArrayHandle<T,COut>& output)
|
||||||
|
{
|
||||||
|
typedef typename
|
||||||
|
vtkm::cont::ArrayHandle<T,COut>
|
||||||
|
::template ExecutionTypes<DeviceAdapterTag>::Portal PortalType;
|
||||||
|
|
||||||
|
DerivedAlgorithm::Copy(input, output);
|
||||||
|
|
||||||
|
vtkm::Id numValues = output.GetNumberOfValues();
|
||||||
|
if (numValues < 1)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
PortalType portal = output.PrepareForInPlace(DeviceAdapterTag());
|
||||||
|
|
||||||
|
vtkm::Id stride;
|
||||||
|
for (stride = 2; stride-1 < numValues; stride *= 2)
|
||||||
|
{
|
||||||
|
ScanKernel<PortalType> kernel(portal, stride, stride/2 - 1);
|
||||||
|
DerivedAlgorithm::Schedule(kernel, numValues/stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do reverse operation on odd indices. Start at stride we were just at.
|
||||||
|
for (stride /= 2; stride > 1; stride /= 2)
|
||||||
|
{
|
||||||
|
ScanKernel<PortalType> kernel(portal, stride, stride - 1);
|
||||||
|
DerivedAlgorithm::Schedule(kernel, numValues/stride);
|
||||||
|
}
|
||||||
|
|
||||||
|
return GetExecutionValue(output, numValues-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Sort
|
||||||
|
private:
|
||||||
|
template<typename PortalType, typename CompareType>
|
||||||
|
struct BitonicSortMergeKernel : vtkm::exec::internal::WorkletBase
|
||||||
|
{
|
||||||
|
PortalType Portal;
|
||||||
|
CompareType Compare;
|
||||||
|
vtkm::Id GroupSize;
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
BitonicSortMergeKernel(const PortalType &portal,
|
||||||
|
const CompareType &compare,
|
||||||
|
vtkm::Id groupSize)
|
||||||
|
: Portal(portal), Compare(compare), GroupSize(groupSize) { }
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
void operator()(vtkm::Id index) const {
|
||||||
|
typedef typename PortalType::ValueType ValueType;
|
||||||
|
|
||||||
|
vtkm::Id groupIndex = index%this->GroupSize;
|
||||||
|
vtkm::Id blockSize = 2*this->GroupSize;
|
||||||
|
vtkm::Id blockIndex = index/this->GroupSize;
|
||||||
|
|
||||||
|
vtkm::Id lowIndex = blockIndex * blockSize + groupIndex;
|
||||||
|
vtkm::Id highIndex = lowIndex + this->GroupSize;
|
||||||
|
|
||||||
|
if (highIndex < this->Portal.GetNumberOfValues())
|
||||||
|
{
|
||||||
|
ValueType lowValue = this->Portal.Get(lowIndex);
|
||||||
|
ValueType highValue = this->Portal.Get(highIndex);
|
||||||
|
if (this->Compare(highValue, lowValue))
|
||||||
|
{
|
||||||
|
this->Portal.Set(highIndex, lowValue);
|
||||||
|
this->Portal.Set(lowIndex, highValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename PortalType, typename CompareType>
|
||||||
|
struct BitonicSortCrossoverKernel : vtkm::exec::internal::WorkletBase
|
||||||
|
{
|
||||||
|
PortalType Portal;
|
||||||
|
CompareType Compare;
|
||||||
|
vtkm::Id GroupSize;
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
BitonicSortCrossoverKernel(const PortalType &portal,
|
||||||
|
const CompareType &compare,
|
||||||
|
vtkm::Id groupSize)
|
||||||
|
: Portal(portal), Compare(compare), GroupSize(groupSize) { }
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
void operator()(vtkm::Id index) const {
|
||||||
|
typedef typename PortalType::ValueType ValueType;
|
||||||
|
|
||||||
|
vtkm::Id groupIndex = index%this->GroupSize;
|
||||||
|
vtkm::Id blockSize = 2*this->GroupSize;
|
||||||
|
vtkm::Id blockIndex = index/this->GroupSize;
|
||||||
|
|
||||||
|
vtkm::Id lowIndex = blockIndex*blockSize + groupIndex;
|
||||||
|
vtkm::Id highIndex = blockIndex*blockSize + (blockSize - groupIndex - 1);
|
||||||
|
|
||||||
|
if (highIndex < this->Portal.GetNumberOfValues())
|
||||||
|
{
|
||||||
|
ValueType lowValue = this->Portal.Get(lowIndex);
|
||||||
|
ValueType highValue = this->Portal.Get(highIndex);
|
||||||
|
if (this->Compare(highValue, lowValue))
|
||||||
|
{
|
||||||
|
this->Portal.Set(highIndex, lowValue);
|
||||||
|
this->Portal.Set(lowIndex, highValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DefaultCompareFunctor
|
||||||
|
{
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
bool operator()(const T& first, const T& second) const
|
||||||
|
{
|
||||||
|
return first < second;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
template<typename T, class Container, class CompareType>
|
||||||
|
VTKM_CONT_EXPORT static void Sort(
|
||||||
|
vtkm::cont::ArrayHandle<T,Container> &values,
|
||||||
|
CompareType compare)
|
||||||
|
{
|
||||||
|
typedef typename vtkm::cont::ArrayHandle<T,Container> ArrayType;
|
||||||
|
typedef typename ArrayType::template ExecutionTypes<DeviceAdapterTag>
|
||||||
|
::Portal PortalType;
|
||||||
|
|
||||||
|
vtkm::Id numValues = values.GetNumberOfValues();
|
||||||
|
if (numValues < 2) { return; }
|
||||||
|
|
||||||
|
PortalType portal = values.PrepareForInPlace(DeviceAdapterTag());
|
||||||
|
|
||||||
|
vtkm::Id numThreads = 1;
|
||||||
|
while (numThreads < numValues) { numThreads *= 2; }
|
||||||
|
numThreads /= 2;
|
||||||
|
|
||||||
|
typedef BitonicSortMergeKernel<PortalType,CompareType> MergeKernel;
|
||||||
|
typedef BitonicSortCrossoverKernel<PortalType,CompareType> CrossoverKernel;
|
||||||
|
|
||||||
|
for (vtkm::Id crossoverSize = 1;
|
||||||
|
crossoverSize < numValues;
|
||||||
|
crossoverSize *= 2)
|
||||||
|
{
|
||||||
|
DerivedAlgorithm::Schedule(CrossoverKernel(portal,compare,crossoverSize),
|
||||||
|
numThreads);
|
||||||
|
for (vtkm::Id mergeSize = crossoverSize/2; mergeSize > 0; mergeSize /= 2)
|
||||||
|
{
|
||||||
|
DerivedAlgorithm::Schedule(MergeKernel(portal,compare,mergeSize),
|
||||||
|
numThreads);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, class Container>
|
||||||
|
VTKM_CONT_EXPORT static void Sort(
|
||||||
|
vtkm::cont::ArrayHandle<T,Container> &values)
|
||||||
|
{
|
||||||
|
DerivedAlgorithm::Sort(values, DefaultCompareFunctor());
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Stream Compact
|
||||||
|
private:
|
||||||
|
template<class StencilPortalType, class OutputPortalType>
|
||||||
|
struct StencilToIndexFlagKernel
|
||||||
|
{
|
||||||
|
typedef typename StencilPortalType::ValueType StencilValueType;
|
||||||
|
StencilPortalType StencilPortal;
|
||||||
|
OutputPortalType OutputPortal;
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
StencilToIndexFlagKernel(StencilPortalType stencilPortal,
|
||||||
|
OutputPortalType outputPortal)
|
||||||
|
: StencilPortal(stencilPortal), OutputPortal(outputPortal) { }
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
void operator()(vtkm::Id index) const
|
||||||
|
{
|
||||||
|
StencilValueType value = this->StencilPortal.Get(index);
|
||||||
|
bool flag = not_default_constructor<StencilValueType>()(value);
|
||||||
|
this->OutputPortal.Set(index, flag ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer &)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class InputPortalType,
|
||||||
|
class StencilPortalType,
|
||||||
|
class IndexPortalType,
|
||||||
|
class OutputPortalType>
|
||||||
|
struct CopyIfKernel
|
||||||
|
{
|
||||||
|
InputPortalType InputPortal;
|
||||||
|
StencilPortalType StencilPortal;
|
||||||
|
IndexPortalType IndexPortal;
|
||||||
|
OutputPortalType OutputPortal;
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
CopyIfKernel(InputPortalType inputPortal,
|
||||||
|
StencilPortalType stencilPortal,
|
||||||
|
IndexPortalType indexPortal,
|
||||||
|
OutputPortalType outputPortal)
|
||||||
|
: InputPortal(inputPortal),
|
||||||
|
StencilPortal(stencilPortal),
|
||||||
|
IndexPortal(indexPortal),
|
||||||
|
OutputPortal(outputPortal) { }
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
void operator()(vtkm::Id index) const
|
||||||
|
{
|
||||||
|
typedef typename StencilPortalType::ValueType StencilValueType;
|
||||||
|
StencilValueType stencilValue = this->StencilPortal.Get(index);
|
||||||
|
if (not_default_constructor<StencilValueType>()(stencilValue))
|
||||||
|
{
|
||||||
|
vtkm::Id outputIndex = this->IndexPortal.Get(index);
|
||||||
|
|
||||||
|
typedef typename OutputPortalType::ValueType OutputValueType;
|
||||||
|
OutputValueType value = this->InputPortal.Get(index);
|
||||||
|
|
||||||
|
this->OutputPortal.Set(outputIndex, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer &)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
template<typename T, typename U, class CIn, class CStencil, class COut>
|
||||||
|
VTKM_CONT_EXPORT static void StreamCompact(
|
||||||
|
const vtkm::cont::ArrayHandle<T,CIn>& input,
|
||||||
|
const vtkm::cont::ArrayHandle<U,CStencil>& stencil,
|
||||||
|
vtkm::cont::ArrayHandle<T,COut>& output)
|
||||||
|
{
|
||||||
|
VTKM_ASSERT_CONT(input.GetNumberOfValues() == stencil.GetNumberOfValues());
|
||||||
|
vtkm::Id arrayLength = stencil.GetNumberOfValues();
|
||||||
|
|
||||||
|
typedef vtkm::cont::ArrayHandle<
|
||||||
|
vtkm::Id, vtkm::cont::ArrayContainerControlTagBasic> IndexArrayType;
|
||||||
|
IndexArrayType indices;
|
||||||
|
|
||||||
|
typedef typename vtkm::cont::ArrayHandle<U,CStencil>
|
||||||
|
::template ExecutionTypes<DeviceAdapterTag>::PortalConst
|
||||||
|
StencilPortalType;
|
||||||
|
StencilPortalType stencilPortal =
|
||||||
|
stencil.PrepareForInput(DeviceAdapterTag());
|
||||||
|
|
||||||
|
typedef typename IndexArrayType
|
||||||
|
::template ExecutionTypes<DeviceAdapterTag>::Portal IndexPortalType;
|
||||||
|
IndexPortalType indexPortal =
|
||||||
|
indices.PrepareForOutput(arrayLength, DeviceAdapterTag());
|
||||||
|
|
||||||
|
StencilToIndexFlagKernel<
|
||||||
|
StencilPortalType, IndexPortalType> indexKernel(stencilPortal,
|
||||||
|
indexPortal);
|
||||||
|
|
||||||
|
DerivedAlgorithm::Schedule(indexKernel, arrayLength);
|
||||||
|
|
||||||
|
vtkm::Id outArrayLength = DerivedAlgorithm::ScanExclusive(indices, indices);
|
||||||
|
|
||||||
|
typedef typename vtkm::cont::ArrayHandle<T,CIn>
|
||||||
|
::template ExecutionTypes<DeviceAdapterTag>::PortalConst
|
||||||
|
InputPortalType;
|
||||||
|
InputPortalType inputPortal = input.PrepareForInput(DeviceAdapterTag());
|
||||||
|
|
||||||
|
typedef typename vtkm::cont::ArrayHandle<T,COut>
|
||||||
|
::template ExecutionTypes<DeviceAdapterTag>::Portal OutputPortalType;
|
||||||
|
OutputPortalType outputPortal =
|
||||||
|
output.PrepareForOutput(outArrayLength, DeviceAdapterTag());
|
||||||
|
|
||||||
|
CopyIfKernel<
|
||||||
|
InputPortalType,
|
||||||
|
StencilPortalType,
|
||||||
|
IndexPortalType,
|
||||||
|
OutputPortalType>copyKernel(inputPortal,
|
||||||
|
stencilPortal,
|
||||||
|
indexPortal,
|
||||||
|
outputPortal);
|
||||||
|
DerivedAlgorithm::Schedule(copyKernel, arrayLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, class CStencil, class COut>
|
||||||
|
VTKM_CONT_EXPORT static void StreamCompact(
|
||||||
|
const vtkm::cont::ArrayHandle<T,CStencil> &stencil,
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id,COut> &output)
|
||||||
|
{
|
||||||
|
typedef vtkm::cont::ArrayHandleCounting<vtkm::Id> CountingHandleType;
|
||||||
|
|
||||||
|
CountingHandleType input =
|
||||||
|
vtkm::cont::make_ArrayHandleCounting(vtkm::Id(0),
|
||||||
|
stencil.GetNumberOfValues());
|
||||||
|
DerivedAlgorithm::StreamCompact(input, stencil, output);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Unique
|
||||||
|
private:
|
||||||
|
template<class InputPortalType, class StencilPortalType>
|
||||||
|
struct ClassifyUniqueKernel {
|
||||||
|
InputPortalType InputPortal;
|
||||||
|
StencilPortalType StencilPortal;
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ClassifyUniqueKernel(InputPortalType inputPortal,
|
||||||
|
StencilPortalType stencilPortal)
|
||||||
|
: InputPortal(inputPortal), StencilPortal(stencilPortal) { }
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
void operator()(vtkm::Id index) const {
|
||||||
|
typedef typename StencilPortalType::ValueType ValueType;
|
||||||
|
if (index == 0)
|
||||||
|
{
|
||||||
|
// Always copy first value.
|
||||||
|
this->StencilPortal.Set(index, ValueType(1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ValueType flag = ValueType(this->InputPortal.Get(index-1)
|
||||||
|
!= this->InputPortal.Get(index));
|
||||||
|
this->StencilPortal.Set(index, flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer &)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class InputPortalType, class StencilPortalType, class Compare>
|
||||||
|
struct ClassifyUniqueComparisonKernel {
|
||||||
|
InputPortalType InputPortal;
|
||||||
|
StencilPortalType StencilPortal;
|
||||||
|
Compare CompareFunctor;
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
ClassifyUniqueComparisonKernel(InputPortalType inputPortal,
|
||||||
|
StencilPortalType stencilPortal,
|
||||||
|
Compare comp):
|
||||||
|
InputPortal(inputPortal),
|
||||||
|
StencilPortal(stencilPortal),
|
||||||
|
CompareFunctor(comp) { }
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
void operator()(vtkm::Id index) const {
|
||||||
|
typedef typename StencilPortalType::ValueType ValueType;
|
||||||
|
if (index == 0)
|
||||||
|
{
|
||||||
|
// Always copy first value.
|
||||||
|
this->StencilPortal.Set(index, ValueType(1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//comparison predicate returns true when they match
|
||||||
|
const bool same = !(this->CompareFunctor(this->InputPortal.Get(index-1),
|
||||||
|
this->InputPortal.Get(index)));
|
||||||
|
ValueType flag = ValueType(same);
|
||||||
|
this->StencilPortal.Set(index, flag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer &)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
template<typename T, class Container>
|
||||||
|
VTKM_CONT_EXPORT static void Unique(
|
||||||
|
vtkm::cont::ArrayHandle<T,Container> &values)
|
||||||
|
{
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id, vtkm::cont::ArrayContainerControlTagBasic>
|
||||||
|
stencilArray;
|
||||||
|
vtkm::Id inputSize = values.GetNumberOfValues();
|
||||||
|
|
||||||
|
ClassifyUniqueKernel<
|
||||||
|
typename vtkm::cont::ArrayHandle<T,Container>::template ExecutionTypes<DeviceAdapterTag>::PortalConst,
|
||||||
|
typename vtkm::cont::ArrayHandle<vtkm::Id,vtkm::cont::ArrayContainerControlTagBasic>::template ExecutionTypes<DeviceAdapterTag>::Portal>
|
||||||
|
classifyKernel(values.PrepareForInput(DeviceAdapterTag()),
|
||||||
|
stencilArray.PrepareForOutput(inputSize, DeviceAdapterTag()));
|
||||||
|
DerivedAlgorithm::Schedule(classifyKernel, inputSize);
|
||||||
|
|
||||||
|
vtkm::cont::ArrayHandle<T, vtkm::cont::ArrayContainerControlTagBasic>
|
||||||
|
outputArray;
|
||||||
|
|
||||||
|
DerivedAlgorithm::StreamCompact(values, stencilArray, outputArray);
|
||||||
|
|
||||||
|
DerivedAlgorithm::Copy(outputArray, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, class Container, class Compare>
|
||||||
|
VTKM_CONT_EXPORT static void Unique(
|
||||||
|
vtkm::cont::ArrayHandle<T,Container> &values,
|
||||||
|
Compare comp)
|
||||||
|
{
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id, vtkm::cont::ArrayContainerControlTagBasic>
|
||||||
|
stencilArray;
|
||||||
|
vtkm::Id inputSize = values.GetNumberOfValues();
|
||||||
|
|
||||||
|
ClassifyUniqueComparisonKernel<
|
||||||
|
typename vtkm::cont::ArrayHandle<T,Container>::template ExecutionTypes<DeviceAdapterTag>::PortalConst,
|
||||||
|
typename vtkm::cont::ArrayHandle<vtkm::Id,vtkm::cont::ArrayContainerControlTagBasic>::template ExecutionTypes<DeviceAdapterTag>::Portal,
|
||||||
|
Compare>
|
||||||
|
classifyKernel(values.PrepareForInput(DeviceAdapterTag()),
|
||||||
|
stencilArray.PrepareForOutput(inputSize, DeviceAdapterTag()),
|
||||||
|
comp);
|
||||||
|
DerivedAlgorithm::Schedule(classifyKernel, inputSize);
|
||||||
|
|
||||||
|
vtkm::cont::ArrayHandle<T, vtkm::cont::ArrayContainerControlTagBasic>
|
||||||
|
outputArray;
|
||||||
|
|
||||||
|
DerivedAlgorithm::StreamCompact(values, stencilArray, outputArray);
|
||||||
|
|
||||||
|
DerivedAlgorithm::Copy(outputArray, values);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------
|
||||||
|
// Upper bounds
|
||||||
|
private:
|
||||||
|
template<class InputPortalType,class ValuesPortalType,class OutputPortalType>
|
||||||
|
struct UpperBoundsKernel {
|
||||||
|
InputPortalType InputPortal;
|
||||||
|
ValuesPortalType ValuesPortal;
|
||||||
|
OutputPortalType OutputPortal;
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
UpperBoundsKernel(InputPortalType inputPortal,
|
||||||
|
ValuesPortalType valuesPortal,
|
||||||
|
OutputPortalType outputPortal)
|
||||||
|
: InputPortal(inputPortal),
|
||||||
|
ValuesPortal(valuesPortal),
|
||||||
|
OutputPortal(outputPortal) { }
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
void operator()(vtkm::Id index) const {
|
||||||
|
// This method assumes that (1) InputPortalType can return working
|
||||||
|
// iterators in the execution environment and that (2) methods not
|
||||||
|
// specified with VTKM_EXEC_EXPORT (such as the STL algorithms) can be
|
||||||
|
// called from the execution environment. Neither one of these is
|
||||||
|
// necessarily true, but it is true for the current uses of this general
|
||||||
|
// function and I don't want to compete with STL if I don't have to.
|
||||||
|
|
||||||
|
typename InputPortalType::IteratorType resultPos =
|
||||||
|
std::upper_bound(this->InputPortal.GetIteratorBegin(),
|
||||||
|
this->InputPortal.GetIteratorEnd(),
|
||||||
|
this->ValuesPortal.Get(index));
|
||||||
|
|
||||||
|
vtkm::Id resultIndex =
|
||||||
|
static_cast<vtkm::Id>(
|
||||||
|
std::distance(this->InputPortal.GetIteratorBegin(), resultPos));
|
||||||
|
this->OutputPortal.Set(index, resultIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer &)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<class InputPortalType,class ValuesPortalType,class OutputPortalType,class Compare>
|
||||||
|
struct UpperBoundsKernelComparisonKernel {
|
||||||
|
InputPortalType InputPortal;
|
||||||
|
ValuesPortalType ValuesPortal;
|
||||||
|
OutputPortalType OutputPortal;
|
||||||
|
Compare CompareFunctor;
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
UpperBoundsKernelComparisonKernel(InputPortalType inputPortal,
|
||||||
|
ValuesPortalType valuesPortal,
|
||||||
|
OutputPortalType outputPortal,
|
||||||
|
Compare comp)
|
||||||
|
: InputPortal(inputPortal),
|
||||||
|
ValuesPortal(valuesPortal),
|
||||||
|
OutputPortal(outputPortal),
|
||||||
|
CompareFunctor(comp) { }
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT
|
||||||
|
void operator()(vtkm::Id index) const {
|
||||||
|
// This method assumes that (1) InputPortalType can return working
|
||||||
|
// iterators in the execution environment and that (2) methods not
|
||||||
|
// specified with VTKM_EXEC_EXPORT (such as the STL algorithms) can be
|
||||||
|
// called from the execution environment. Neither one of these is
|
||||||
|
// necessarily true, but it is true for the current uses of this general
|
||||||
|
// function and I don't want to compete with STL if I don't have to.
|
||||||
|
|
||||||
|
typename InputPortalType::IteratorType resultPos =
|
||||||
|
std::upper_bound(this->InputPortal.GetIteratorBegin(),
|
||||||
|
this->InputPortal.GetIteratorEnd(),
|
||||||
|
this->ValuesPortal.Get(index),
|
||||||
|
this->CompareFunctor);
|
||||||
|
|
||||||
|
vtkm::Id resultIndex =
|
||||||
|
static_cast<vtkm::Id>(
|
||||||
|
std::distance(this->InputPortal.GetIteratorBegin(), resultPos));
|
||||||
|
this->OutputPortal.Set(index, resultIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer &)
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
template<typename T, class CIn, class CVal, class COut>
|
||||||
|
VTKM_CONT_EXPORT static void UpperBounds(
|
||||||
|
const vtkm::cont::ArrayHandle<T,CIn> &input,
|
||||||
|
const vtkm::cont::ArrayHandle<T,CVal> &values,
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id,COut> &output)
|
||||||
|
{
|
||||||
|
vtkm::Id arraySize = values.GetNumberOfValues();
|
||||||
|
|
||||||
|
UpperBoundsKernel<
|
||||||
|
typename vtkm::cont::ArrayHandle<T,CIn>::template ExecutionTypes<DeviceAdapterTag>::PortalConst,
|
||||||
|
typename vtkm::cont::ArrayHandle<T,CVal>::template ExecutionTypes<DeviceAdapterTag>::PortalConst,
|
||||||
|
typename vtkm::cont::ArrayHandle<T,COut>::template ExecutionTypes<DeviceAdapterTag>::Portal>
|
||||||
|
kernel(input.PrepareForInput(DeviceAdapterTag()),
|
||||||
|
values.PrepareForInput(DeviceAdapterTag()),
|
||||||
|
output.PrepareForOutput(arraySize, DeviceAdapterTag()));
|
||||||
|
|
||||||
|
DerivedAlgorithm::Schedule(kernel, arraySize);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, class CIn, class CVal, class COut, class Compare>
|
||||||
|
VTKM_CONT_EXPORT static void UpperBounds(
|
||||||
|
const vtkm::cont::ArrayHandle<T,CIn> &input,
|
||||||
|
const vtkm::cont::ArrayHandle<T,CVal> &values,
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id,COut> &output,
|
||||||
|
Compare comp)
|
||||||
|
{
|
||||||
|
vtkm::Id arraySize = values.GetNumberOfValues();
|
||||||
|
|
||||||
|
UpperBoundsKernelComparisonKernel<
|
||||||
|
typename vtkm::cont::ArrayHandle<T,CIn>::template ExecutionTypes<DeviceAdapterTag>::PortalConst,
|
||||||
|
typename vtkm::cont::ArrayHandle<T,CVal>::template ExecutionTypes<DeviceAdapterTag>::PortalConst,
|
||||||
|
typename vtkm::cont::ArrayHandle<T,COut>::template ExecutionTypes<DeviceAdapterTag>::Portal,
|
||||||
|
Compare>
|
||||||
|
kernel(input.PrepareForInput(DeviceAdapterTag()),
|
||||||
|
values.PrepareForInput(DeviceAdapterTag()),
|
||||||
|
output.PrepareForOutput(arraySize, DeviceAdapterTag()),
|
||||||
|
comp);
|
||||||
|
|
||||||
|
DerivedAlgorithm::Schedule(kernel, arraySize);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class CIn, class COut>
|
||||||
|
VTKM_CONT_EXPORT static void UpperBounds(
|
||||||
|
const vtkm::cont::ArrayHandle<vtkm::Id,CIn> &input,
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id,COut> &values_output)
|
||||||
|
{
|
||||||
|
DeviceAdapterAlgorithmGeneral<DerivedAlgorithm,
|
||||||
|
DeviceAdapterTag>::UpperBounds(input, values_output, values_output);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace vtkm::cont::internal
|
||||||
|
|
||||||
|
#endif //vtkm_cont_internal_DeviceAdapterAlgorithmGeneral_h
|
190
vtkm/cont/internal/DeviceAdapterAlgorithmSerial.h
Normal file
190
vtkm/cont/internal/DeviceAdapterAlgorithmSerial.h
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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 2014 Sandia Corporation.
|
||||||
|
// Copyright 2014 UT-Battelle, LLC.
|
||||||
|
// Copyright 2014. Los Alamos National Security
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// 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 vtkm_cont_internal_DeviceAdapterAlgorithmSerial_h
|
||||||
|
#define vtkm_cont_internal_DeviceAdapterAlgorithmSerial_h
|
||||||
|
|
||||||
|
#include <vtkm/cont/ArrayHandle.h>
|
||||||
|
#include <vtkm/cont/ErrorExecution.h>
|
||||||
|
#include <vtkm/cont/internal/DeviceAdapterAlgorithm.h>
|
||||||
|
#include <vtkm/cont/internal/DeviceAdapterAlgorithmGeneral.h>
|
||||||
|
#include <vtkm/cont/internal/DeviceAdapterTagSerial.h>
|
||||||
|
|
||||||
|
#include <vtkm/exec/internal/ErrorMessageBuffer.h>
|
||||||
|
|
||||||
|
#include <boost/iterator/counting_iterator.hpp>
|
||||||
|
#include <boost/utility/enable_if.hpp>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
|
namespace vtkm {
|
||||||
|
namespace cont {
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct DeviceAdapterAlgorithm<vtkm::cont::DeviceAdapterTagSerial> :
|
||||||
|
vtkm::cont::internal::DeviceAdapterAlgorithmGeneral<
|
||||||
|
DeviceAdapterAlgorithm<vtkm::cont::DeviceAdapterTagSerial>,
|
||||||
|
vtkm::cont::DeviceAdapterTagSerial>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef vtkm::cont::DeviceAdapterTagSerial Device;
|
||||||
|
|
||||||
|
public:
|
||||||
|
template<typename T, class CIn, class COut>
|
||||||
|
VTKM_CONT_EXPORT static T ScanInclusive(
|
||||||
|
const vtkm::cont::ArrayHandle<T,CIn> &input,
|
||||||
|
vtkm::cont::ArrayHandle<T,COut>& output)
|
||||||
|
{
|
||||||
|
typedef typename vtkm::cont::ArrayHandle<T,COut>
|
||||||
|
::template ExecutionTypes<Device>::Portal PortalOut;
|
||||||
|
typedef typename vtkm::cont::ArrayHandle<T,CIn>
|
||||||
|
::template ExecutionTypes<Device>::PortalConst PortalIn;
|
||||||
|
|
||||||
|
vtkm::Id numberOfValues = input.GetNumberOfValues();
|
||||||
|
|
||||||
|
PortalIn inputPortal = input.PrepareForInput(Device());
|
||||||
|
PortalOut outputPortal = output.PrepareForOutput(numberOfValues, Device());
|
||||||
|
|
||||||
|
if (numberOfValues <= 0) { return 0; }
|
||||||
|
|
||||||
|
std::partial_sum(inputPortal.GetIteratorBegin(),
|
||||||
|
inputPortal.GetIteratorEnd(),
|
||||||
|
outputPortal.GetIteratorBegin());
|
||||||
|
|
||||||
|
// Return the value at the last index in the array, which is the full sum.
|
||||||
|
return outputPortal.Get(numberOfValues - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, class CIn, class COut>
|
||||||
|
VTKM_CONT_EXPORT static T ScanExclusive(
|
||||||
|
const vtkm::cont::ArrayHandle<T,CIn> &input,
|
||||||
|
vtkm::cont::ArrayHandle<T,COut>& output)
|
||||||
|
{
|
||||||
|
typedef typename vtkm::cont::ArrayHandle<T,COut>
|
||||||
|
::template ExecutionTypes<Device>::Portal PortalOut;
|
||||||
|
typedef typename vtkm::cont::ArrayHandle<T,CIn>
|
||||||
|
::template ExecutionTypes<Device>::PortalConst PortalIn;
|
||||||
|
|
||||||
|
vtkm::Id numberOfValues = input.GetNumberOfValues();
|
||||||
|
|
||||||
|
PortalIn inputPortal = input.PrepareForInput(Device());
|
||||||
|
PortalOut outputPortal = output.PrepareForOutput(numberOfValues, Device());
|
||||||
|
|
||||||
|
if (numberOfValues <= 0) { return 0; }
|
||||||
|
|
||||||
|
std::partial_sum(inputPortal.GetIteratorBegin(),
|
||||||
|
inputPortal.GetIteratorEnd(),
|
||||||
|
outputPortal.GetIteratorBegin());
|
||||||
|
|
||||||
|
T fullSum = outputPortal.Get(numberOfValues - 1);
|
||||||
|
|
||||||
|
// Shift right by one
|
||||||
|
std::copy_backward(outputPortal.GetIteratorBegin(),
|
||||||
|
outputPortal.GetIteratorEnd()-1,
|
||||||
|
outputPortal.GetIteratorEnd());
|
||||||
|
outputPortal.Set(0, 0);
|
||||||
|
return fullSum;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// This runs in the execution environment.
|
||||||
|
template<class FunctorType>
|
||||||
|
class ScheduleKernel
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ScheduleKernel(const FunctorType &functor)
|
||||||
|
: Functor(functor) { }
|
||||||
|
|
||||||
|
//needed for when calling from schedule on a range
|
||||||
|
VTKM_EXEC_EXPORT void operator()(vtkm::Id index) const
|
||||||
|
{
|
||||||
|
this->Functor(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const FunctorType Functor;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
template<class Functor>
|
||||||
|
VTKM_CONT_EXPORT static void Schedule(Functor functor,
|
||||||
|
vtkm::Id numInstances)
|
||||||
|
{
|
||||||
|
const vtkm::Id MESSAGE_SIZE = 1024;
|
||||||
|
char errorString[MESSAGE_SIZE];
|
||||||
|
errorString[0] = '\0';
|
||||||
|
vtkm::exec::internal::ErrorMessageBuffer
|
||||||
|
errorMessage(errorString, MESSAGE_SIZE);
|
||||||
|
|
||||||
|
functor.SetErrorMessageBuffer(errorMessage);
|
||||||
|
|
||||||
|
DeviceAdapterAlgorithm<Device>::ScheduleKernel<Functor> kernel(functor);
|
||||||
|
|
||||||
|
std::for_each(
|
||||||
|
::boost::counting_iterator<vtkm::Id>(0),
|
||||||
|
::boost::counting_iterator<vtkm::Id>(numInstances),
|
||||||
|
kernel);
|
||||||
|
|
||||||
|
if (errorMessage.IsErrorRaised())
|
||||||
|
{
|
||||||
|
throw vtkm::cont::ErrorExecution(errorString);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class FunctorType>
|
||||||
|
VTKM_CONT_EXPORT
|
||||||
|
static void Schedule(FunctorType functor, vtkm::Id3 rangeMax)
|
||||||
|
{
|
||||||
|
DeviceAdapterAlgorithm<Device>::Schedule(functor,
|
||||||
|
rangeMax[0] * rangeMax[1] * rangeMax[2] );
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, class Container>
|
||||||
|
VTKM_CONT_EXPORT static void Sort(vtkm::cont::ArrayHandle<T,Container>& values)
|
||||||
|
{
|
||||||
|
typedef typename vtkm::cont::ArrayHandle<T,Container>
|
||||||
|
::template ExecutionTypes<Device>::Portal PortalType;
|
||||||
|
|
||||||
|
PortalType arrayPortal = values.PrepareForInPlace(Device());
|
||||||
|
std::sort(arrayPortal.GetIteratorBegin(), arrayPortal.GetIteratorEnd());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, class Container, class Compare>
|
||||||
|
VTKM_CONT_EXPORT static void Sort(vtkm::cont::ArrayHandle<T,Container>& values,
|
||||||
|
Compare comp)
|
||||||
|
{
|
||||||
|
typedef typename vtkm::cont::ArrayHandle<T,Container>
|
||||||
|
::template ExecutionTypes<Device>::Portal PortalType;
|
||||||
|
|
||||||
|
PortalType arrayPortal = values.PrepareForInPlace(Device());
|
||||||
|
std::sort(arrayPortal.GetIteratorBegin(), arrayPortal.GetIteratorEnd(),comp);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT static void Synchronize()
|
||||||
|
{
|
||||||
|
// Nothing to do. This device is serial and has no asynchronous operations.
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace vtkm::cont
|
||||||
|
|
||||||
|
#endif //vtkm_cont_internal_DeviceAdapterAlgorithmSerial_h
|
32
vtkm/cont/internal/DeviceAdapterError.h
Normal file
32
vtkm/cont/internal/DeviceAdapterError.h
Normal file
@ -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.
|
||||||
|
//
|
||||||
|
// Copyright 2014 Sandia Corporation.
|
||||||
|
// Copyright 2014 UT-Battelle, LLC.
|
||||||
|
// Copyright 2014. Los Alamos National Security
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// 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 vtkm_cont_internal_DeviceAdapterError_h
|
||||||
|
#define vtkm_cont_internal_DeviceAdapterError_h
|
||||||
|
|
||||||
|
#include <vtkm/cont/internal/DeviceAdapterTag.h>
|
||||||
|
|
||||||
|
/// This is an invalid DeviceAdapter. The point of this class is to include the
|
||||||
|
/// header file to make this invalid class the default DeviceAdapter. From that
|
||||||
|
/// point, you have to specify an appropriate DeviceAdapter or else get a
|
||||||
|
/// compile error.
|
||||||
|
///
|
||||||
|
VTKM_CREATE_DEVICE_ADAPTER(Error);
|
||||||
|
|
||||||
|
#endif //vtkm_cont_internal_DeviceAdapterError_h
|
@ -91,6 +91,11 @@ struct DeviceAdapterTagCheck
|
|||||||
#include <vtkm/cont/internal/DeviceAdapterTagSerial.h>
|
#include <vtkm/cont/internal/DeviceAdapterTagSerial.h>
|
||||||
#define VTKM_DEFAULT_DEVICE_ADAPTER_TAG ::vtkm::cont::DeviceAdapterTagSerial
|
#define VTKM_DEFAULT_DEVICE_ADAPTER_TAG ::vtkm::cont::DeviceAdapterTagSerial
|
||||||
|
|
||||||
|
#elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_ERROR
|
||||||
|
|
||||||
|
#include <vtkm/cont/internal/DeviceAdapterError.h>
|
||||||
|
#define VTKM_DEFAULT_DEVICE_ADAPTER_TAG ::vtkm::cont::DeviceAdapterTagError
|
||||||
|
|
||||||
#elif (VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_UNDEFINED) || !defined(VTKM_DEVICE_ADAPTER)
|
#elif (VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_UNDEFINED) || !defined(VTKM_DEVICE_ADAPTER)
|
||||||
|
|
||||||
#ifndef VTKM_DEFAULT_DEVICE_ADAPTER_TAG
|
#ifndef VTKM_DEFAULT_DEVICE_ADAPTER_TAG
|
||||||
|
@ -22,6 +22,6 @@
|
|||||||
set(unit_tests
|
set(unit_tests
|
||||||
UnitTestArrayManagerExecutionShareWithControl.cxx
|
UnitTestArrayManagerExecutionShareWithControl.cxx
|
||||||
UnitTestArrayPortalFromIterators.cxx
|
UnitTestArrayPortalFromIterators.cxx
|
||||||
# UnitTestIteratorFromArrayPortal.cxx
|
UnitTestIteratorFromArrayPortal.cxx
|
||||||
)
|
)
|
||||||
vtkm_unit_tests(SOURCES ${unit_tests})
|
vtkm_unit_tests(SOURCES ${unit_tests})
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
set(headers
|
set(headers
|
||||||
Testing.h
|
Testing.h
|
||||||
|
TestingDeviceAdapter.h
|
||||||
)
|
)
|
||||||
|
|
||||||
vtkm_declare_headers(${headers})
|
vtkm_declare_headers(${headers})
|
||||||
@ -28,7 +29,11 @@ set(unit_tests
|
|||||||
UnitTestArrayContainerControlBasic.cxx
|
UnitTestArrayContainerControlBasic.cxx
|
||||||
UnitTestArrayContainerControlImplicit.cxx
|
UnitTestArrayContainerControlImplicit.cxx
|
||||||
UnitTestArrayHandle.cxx
|
UnitTestArrayHandle.cxx
|
||||||
|
UnitTestArrayHandleCounting.cxx
|
||||||
UnitTestContTesting.cxx
|
UnitTestContTesting.cxx
|
||||||
|
UnitTestDeviceAdapterAlgorithmDependency.cxx
|
||||||
|
UnitTestDeviceAdapterAlgorithmGeneral.cxx
|
||||||
|
UnitTestDeviceAdapterSerial.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
vtkm_unit_tests(SOURCES ${unit_tests})
|
vtkm_unit_tests(SOURCES ${unit_tests})
|
||||||
|
1330
vtkm/cont/testing/TestingDeviceAdapter.h
Normal file
1330
vtkm/cont/testing/TestingDeviceAdapter.h
Normal file
File diff suppressed because it is too large
Load Diff
125
vtkm/cont/testing/UnitTestArrayHandleCounting.cxx
Normal file
125
vtkm/cont/testing/UnitTestArrayHandleCounting.cxx
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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 2014 Sandia Corporation.
|
||||||
|
// Copyright 2014 UT-Battelle, LLC.
|
||||||
|
// Copyright 2014. Los Alamos National Security
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// 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.
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_SERIAL
|
||||||
|
|
||||||
|
#include <vtkm/cont/ArrayHandleCounting.h>
|
||||||
|
|
||||||
|
#include <vtkm/cont/testing/Testing.h>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
const vtkm::Id ARRAY_SIZE = 10;
|
||||||
|
|
||||||
|
//increments by two instead of one wrapper
|
||||||
|
template<typename T>
|
||||||
|
struct CountByTwo
|
||||||
|
{
|
||||||
|
CountByTwo(): Value() {}
|
||||||
|
explicit CountByTwo(T t): Value(t) {}
|
||||||
|
|
||||||
|
bool operator==(const T& other) const
|
||||||
|
{ return Value == other; }
|
||||||
|
|
||||||
|
bool operator==(const CountByTwo<T>& other) const
|
||||||
|
{ return Value == other.Value; }
|
||||||
|
|
||||||
|
CountByTwo<T> operator+(vtkm::Id count) const
|
||||||
|
{ return CountByTwo<T>(Value+(count*2)); }
|
||||||
|
|
||||||
|
CountByTwo<T>& operator++()
|
||||||
|
{ ++Value; ++Value; return *this; }
|
||||||
|
|
||||||
|
friend std::ostream& operator<< (std::ostream& os, const CountByTwo<T>& obj)
|
||||||
|
{ os << obj.Value; return os; }
|
||||||
|
T Value;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template< typename ValueType>
|
||||||
|
struct TemplatedTests
|
||||||
|
{
|
||||||
|
typedef vtkm::cont::ArrayHandleCounting<ValueType> ArrayHandleType;
|
||||||
|
|
||||||
|
typedef vtkm::cont::ArrayHandle<ValueType,
|
||||||
|
typename vtkm::cont::internal::ArrayHandleCountingTraits<ValueType>::Tag>
|
||||||
|
ArrayHandleType2;
|
||||||
|
|
||||||
|
typedef typename ArrayHandleType::PortalConstControl PortalType;
|
||||||
|
|
||||||
|
void operator()( const ValueType startingValue )
|
||||||
|
{
|
||||||
|
ArrayHandleType arrayConst(startingValue, ARRAY_SIZE);
|
||||||
|
|
||||||
|
ArrayHandleType arrayMake = vtkm::cont::make_ArrayHandleCounting(startingValue,ARRAY_SIZE);
|
||||||
|
|
||||||
|
ArrayHandleType2 arrayHandle =
|
||||||
|
ArrayHandleType2(PortalType(startingValue, ARRAY_SIZE));
|
||||||
|
|
||||||
|
VTKM_TEST_ASSERT(arrayConst.GetNumberOfValues() == ARRAY_SIZE,
|
||||||
|
"Counting array using constructor has wrong size.");
|
||||||
|
|
||||||
|
VTKM_TEST_ASSERT(arrayMake.GetNumberOfValues() == ARRAY_SIZE,
|
||||||
|
"Counting array using make has wrong size.");
|
||||||
|
|
||||||
|
VTKM_TEST_ASSERT(arrayHandle.GetNumberOfValues() == ARRAY_SIZE,
|
||||||
|
"Counting array using raw array handle + tag has wrong size.");
|
||||||
|
|
||||||
|
ValueType properValue = startingValue;
|
||||||
|
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
|
||||||
|
{
|
||||||
|
VTKM_TEST_ASSERT(arrayConst.GetPortalConstControl().Get(index) == properValue,
|
||||||
|
"Counting array using constructor has unexpected value.");
|
||||||
|
VTKM_TEST_ASSERT(arrayMake.GetPortalConstControl().Get(index) == properValue,
|
||||||
|
"Counting array using make has unexpected value.");
|
||||||
|
|
||||||
|
VTKM_TEST_ASSERT(arrayHandle.GetPortalConstControl().Get(index) == properValue,
|
||||||
|
"Counting array using raw array handle + tag has unexpected value.");
|
||||||
|
++properValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TestFunctor
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
void operator()(const T t)
|
||||||
|
{
|
||||||
|
TemplatedTests<T> tests;
|
||||||
|
tests(t);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void TestArrayHandleCounting()
|
||||||
|
{
|
||||||
|
TestFunctor()(vtkm::Id(0));
|
||||||
|
TestFunctor()(vtkm::Scalar(0));
|
||||||
|
TestFunctor()( CountByTwo<vtkm::Id>(12) );
|
||||||
|
TestFunctor()( CountByTwo<vtkm::Scalar>(1.2f) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // annonymous namespace
|
||||||
|
|
||||||
|
int UnitTestArrayHandleCounting(int, char *[])
|
||||||
|
{
|
||||||
|
return vtkm::cont::testing::Testing::Run(TestArrayHandleCounting);
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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 2014 Sandia Corporation.
|
||||||
|
// Copyright 2014 UT-Battelle, LLC.
|
||||||
|
// Copyright 2014. Los Alamos National Security
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// 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.
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
// This tests a previous problem where code templated on the device adapter and
|
||||||
|
// used one of the device adapter algorithms (for example, the dispatcher) had
|
||||||
|
// to be declared after any device adapter it was ever used with.
|
||||||
|
|
||||||
|
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_ERROR
|
||||||
|
|
||||||
|
#include <vtkm/cont/DeviceAdapter.h>
|
||||||
|
|
||||||
|
#include <vtkm/cont/testing/Testing.h>
|
||||||
|
|
||||||
|
#include <vtkm/cont/ArrayHandle.h>
|
||||||
|
|
||||||
|
// Important for this test!
|
||||||
|
//This file must be included after ArrayHandle.h
|
||||||
|
#include <vtkm/cont/DeviceAdapterSerial.h>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
struct ExampleWorklet
|
||||||
|
{
|
||||||
|
template <typename T>
|
||||||
|
void operator()(T vtkmNotUsed(v)) const { }
|
||||||
|
};
|
||||||
|
|
||||||
|
void CheckPostDefinedDeviceAdapter()
|
||||||
|
{
|
||||||
|
// Nothing to really check. If this compiles, then the test is probably
|
||||||
|
// successful.
|
||||||
|
vtkm::cont::ArrayHandle<vtkm::Id> test;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
int UnitTestDeviceAdapterAlgorithmDependency(int, char *[])
|
||||||
|
{
|
||||||
|
return vtkm::cont::testing::Testing::Run(CheckPostDefinedDeviceAdapter);
|
||||||
|
}
|
106
vtkm/cont/testing/UnitTestDeviceAdapterAlgorithmGeneral.cxx
Normal file
106
vtkm/cont/testing/UnitTestDeviceAdapterAlgorithmGeneral.cxx
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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 2014 Sandia Corporation.
|
||||||
|
// Copyright 2014 UT-Battelle, LLC.
|
||||||
|
// Copyright 2014. Los Alamos National Security
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// 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.
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
// This test makes sure that the algorithms specified in
|
||||||
|
// DeviceAdapterAlgorithmGeneral.h are working correctly. It does this by
|
||||||
|
// creating a test device adapter that uses the serial device adapter for the
|
||||||
|
// base schedule/scan/sort algorithms and using the general algorithms for
|
||||||
|
// everything else. Because this test is based of the serial device adapter,
|
||||||
|
// make sure that UnitTestDeviceAdapterSerial is working before trying to debug
|
||||||
|
// this one.
|
||||||
|
|
||||||
|
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_ERROR
|
||||||
|
|
||||||
|
#include <vtkm/cont/DeviceAdapterSerial.h>
|
||||||
|
#include <vtkm/cont/internal/DeviceAdapterAlgorithmGeneral.h>
|
||||||
|
|
||||||
|
#include <vtkm/cont/testing/TestingDeviceAdapter.h>
|
||||||
|
|
||||||
|
VTKM_CREATE_DEVICE_ADAPTER(TestAlgorithmGeneral);
|
||||||
|
|
||||||
|
namespace vtkm {
|
||||||
|
namespace cont {
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct DeviceAdapterAlgorithm<
|
||||||
|
vtkm::cont::DeviceAdapterTagTestAlgorithmGeneral> :
|
||||||
|
vtkm::cont::internal::DeviceAdapterAlgorithmGeneral<
|
||||||
|
DeviceAdapterAlgorithm<
|
||||||
|
vtkm::cont::DeviceAdapterTagTestAlgorithmGeneral>,
|
||||||
|
vtkm::cont::DeviceAdapterTagTestAlgorithmGeneral>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
typedef vtkm::cont::DeviceAdapterAlgorithm<
|
||||||
|
vtkm::cont::DeviceAdapterTagSerial> Algorithm;
|
||||||
|
|
||||||
|
typedef vtkm::cont::DeviceAdapterTagTestAlgorithmGeneral
|
||||||
|
DeviceAdapterTagTestAlgorithmGeneral;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
template<class Functor>
|
||||||
|
VTKM_CONT_EXPORT static void Schedule(Functor functor,
|
||||||
|
vtkm::Id numInstances)
|
||||||
|
{
|
||||||
|
Algorithm::Schedule(functor, numInstances);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<class Functor>
|
||||||
|
VTKM_CONT_EXPORT static void Schedule(Functor functor,
|
||||||
|
vtkm::Id3 rangeMax)
|
||||||
|
{
|
||||||
|
Algorithm::Schedule(functor, rangeMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_CONT_EXPORT static void Synchronize()
|
||||||
|
{
|
||||||
|
Algorithm::Synchronize();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
template <typename T, class ArrayContainerControlTag>
|
||||||
|
class ArrayManagerExecution
|
||||||
|
<T,
|
||||||
|
ArrayContainerControlTag,
|
||||||
|
vtkm::cont::DeviceAdapterTagTestAlgorithmGeneral>
|
||||||
|
: public vtkm::cont::internal::ArrayManagerExecution
|
||||||
|
<T, ArrayContainerControlTag, vtkm::cont::DeviceAdapterTagSerial>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef vtkm::cont::internal::ArrayManagerExecution
|
||||||
|
<T, ArrayContainerControlTag, vtkm::cont::DeviceAdapterTagSerial>
|
||||||
|
Superclass;
|
||||||
|
typedef typename Superclass::ValueType ValueType;
|
||||||
|
typedef typename Superclass::PortalType PortalType;
|
||||||
|
typedef typename Superclass::PortalConstType PortalConstType;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace vtkm::cont::testing
|
||||||
|
|
||||||
|
int UnitTestDeviceAdapterAlgorithmGeneral(int, char *[])
|
||||||
|
{
|
||||||
|
return vtkm::cont::testing::TestingDeviceAdapter
|
||||||
|
<vtkm::cont::DeviceAdapterTagTestAlgorithmGeneral>::Run();
|
||||||
|
}
|
31
vtkm/cont/testing/UnitTestDeviceAdapterSerial.cxx
Normal file
31
vtkm/cont/testing/UnitTestDeviceAdapterSerial.cxx
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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 2014 Sandia Corporation.
|
||||||
|
// Copyright 2014 UT-Battelle, LLC.
|
||||||
|
// Copyright 2014. Los Alamos National Security
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// 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.
|
||||||
|
//============================================================================
|
||||||
|
|
||||||
|
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_ERROR
|
||||||
|
|
||||||
|
#include <vtkm/cont/DeviceAdapterSerial.h>
|
||||||
|
|
||||||
|
#include <vtkm/cont/testing/TestingDeviceAdapter.h>
|
||||||
|
|
||||||
|
int UnitTestDeviceAdapterSerial(int, char *[])
|
||||||
|
{
|
||||||
|
return vtkm::cont::testing::TestingDeviceAdapter
|
||||||
|
<vtkm::cont::DeviceAdapterTagSerial>::Run();
|
||||||
|
}
|
94
vtkm/exec/internal/ErrorMessageBuffer.h
Normal file
94
vtkm/exec/internal/ErrorMessageBuffer.h
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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 2014 Sandia Corporation.
|
||||||
|
// Copyright 2014 UT-Battelle, LLC.
|
||||||
|
// Copyright 2014. Los Alamos National Security
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// 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 vtkm_exec_internal_ErrorMessageBuffer_h
|
||||||
|
#define vtkm_exec_internal_ErrorMessageBuffer_h
|
||||||
|
|
||||||
|
#include <vtkm/Types.h>
|
||||||
|
|
||||||
|
namespace vtkm {
|
||||||
|
namespace exec {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
/// Used to hold an error in the execution environment until the parallel
|
||||||
|
/// execution can complete. This is to be used in conjunction with a
|
||||||
|
/// DeviceAdapter's Schedule function to implement errors in execution
|
||||||
|
/// environments that cannot throw errors. This string should be global to all
|
||||||
|
/// threads. If the first entry in the string is '\0' (the C string
|
||||||
|
/// terminator), then we consider it as no error. Otherwise, the array contains
|
||||||
|
/// the string describing the error.
|
||||||
|
///
|
||||||
|
/// Before scheduling worklets, the global array should be cleared to have no
|
||||||
|
/// error. This can only be reliably done by the device adapter.
|
||||||
|
///
|
||||||
|
class ErrorMessageBuffer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VTKM_EXEC_CONT_EXPORT ErrorMessageBuffer()
|
||||||
|
: MessageBuffer(), MessageBufferSize(0) { }
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT_EXPORT
|
||||||
|
ErrorMessageBuffer(char *messageBuffer, vtkm::Id bufferSize)
|
||||||
|
: MessageBuffer(messageBuffer), MessageBufferSize(bufferSize) { }
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT void RaiseError(const char *message) const
|
||||||
|
{
|
||||||
|
// Only raise the error if one has not been raised yet. This check is not
|
||||||
|
// guaranteed to work across threads. However, chances are that if two or
|
||||||
|
// more threads simultaneously pass this test, they will be writing the
|
||||||
|
// same error, which is fine. Even in the much less likely case that two
|
||||||
|
// threads simultaneously write different error messages, the worst case is
|
||||||
|
// that you get a mangled message. That's not good (and it's what we are
|
||||||
|
// trying to avoid), but it's not critical.
|
||||||
|
if (this->IsErrorRaised()) { return; }
|
||||||
|
|
||||||
|
// Safely copy message into array.
|
||||||
|
for (vtkm::Id index = 0; index < this->MessageBufferSize; index++)
|
||||||
|
{
|
||||||
|
this->MessageBuffer[index] = message[index];
|
||||||
|
if (message[index] == '\0') { break; }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure message is null terminated.
|
||||||
|
this->MessageBuffer[this->MessageBufferSize-1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
VTKM_EXEC_CONT_EXPORT bool IsErrorRaised() const
|
||||||
|
{
|
||||||
|
if (this->MessageBufferSize > 0)
|
||||||
|
{
|
||||||
|
return (this->MessageBuffer[0] != '\0');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If there is no buffer set, then always report an error.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
char *MessageBuffer;
|
||||||
|
vtkm::Id MessageBufferSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace vtkm::exec::internal
|
||||||
|
|
||||||
|
#endif // vtkm_exec_internal_ErrorMessageBuffer_h
|
64
vtkm/exec/internal/WorkletBase.h
Normal file
64
vtkm/exec/internal/WorkletBase.h
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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 2014 Sandia Corporation.
|
||||||
|
// Copyright 2014 UT-Battelle, LLC.
|
||||||
|
// Copyright 2014. Los Alamos National Security
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// 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 vtkm_exec_WorkletBase_h
|
||||||
|
#define vtkm_exec_WorkletBase_h
|
||||||
|
|
||||||
|
#include <vtkm/Types.h>
|
||||||
|
|
||||||
|
#include <vtkm/exec/internal/ErrorMessageBuffer.h>
|
||||||
|
|
||||||
|
namespace vtkm {
|
||||||
|
namespace exec {
|
||||||
|
namespace internal {
|
||||||
|
|
||||||
|
/// Base class for all worklet classes. Worklet classes are subclasses and a
|
||||||
|
/// operator() const is added to implement an algorithm in Dax. Different
|
||||||
|
/// worklets have different calling semantics.
|
||||||
|
///
|
||||||
|
class WorkletBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
VTKM_EXEC_CONT_EXPORT WorkletBase() { }
|
||||||
|
|
||||||
|
VTKM_EXEC_EXPORT void RaiseError(const char *message) const
|
||||||
|
{
|
||||||
|
this->ErrorMessage.RaiseError(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the error message buffer so that running algorithms can report
|
||||||
|
/// errors. This is supposed to be set by the dispatcher. This method may be
|
||||||
|
/// replaced as the execution semantics change.
|
||||||
|
///
|
||||||
|
VTKM_CONT_EXPORT void SetErrorMessageBuffer(
|
||||||
|
const vtkm::exec::internal::ErrorMessageBuffer &buffer)
|
||||||
|
{
|
||||||
|
this->ErrorMessage = buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
vtkm::exec::internal::ErrorMessageBuffer ErrorMessage;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace vtkm::exec::internal
|
||||||
|
|
||||||
|
#endif //vtkm_exec_WorkletBase_h
|
@ -29,6 +29,7 @@ set(unit_tests
|
|||||||
UnitTestTesting.cxx
|
UnitTestTesting.cxx
|
||||||
UnitTestTypes.cxx
|
UnitTestTypes.cxx
|
||||||
UnitTestTypeTraits.cxx
|
UnitTestTypeTraits.cxx
|
||||||
|
UnitTestVectorTraits.cxx
|
||||||
)
|
)
|
||||||
|
|
||||||
VTKM_unit_tests(SOURCES ${unit_tests})
|
VTKM_unit_tests(SOURCES ${unit_tests})
|
||||||
|
63
vtkm/testing/UnitTestVectorTraits.cxx
Normal file
63
vtkm/testing/UnitTestVectorTraits.cxx
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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 2014 Sandia Corporation.
|
||||||
|
// Copyright 2014 UT-Battelle, LLC.
|
||||||
|
// Copyright 2014. Los Alamos National Security
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// 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.
|
||||||
|
//============================================================================
|
||||||
|
#include <vtkm/testing/VectorTraitsTests.h>
|
||||||
|
|
||||||
|
#include <vtkm/testing/Testing.h>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
static const vtkm::Id MAX_VECTOR_SIZE = 5;
|
||||||
|
static const vtkm::Id VectorInit[MAX_VECTOR_SIZE] = { 42, 54, 67, 12, 78 };
|
||||||
|
|
||||||
|
struct TestVectorTypeFunctor
|
||||||
|
{
|
||||||
|
template <typename T> void operator()(const T&) const {
|
||||||
|
typedef vtkm::VectorTraits<T> Traits;
|
||||||
|
VTKM_TEST_ASSERT(Traits::NUM_COMPONENTS <= MAX_VECTOR_SIZE,
|
||||||
|
"Need to update test for larger vectors.");
|
||||||
|
T vector;
|
||||||
|
for (int index = 0; index < Traits::NUM_COMPONENTS; index++)
|
||||||
|
{
|
||||||
|
Traits::SetComponent(vector, index, VectorInit[index]);
|
||||||
|
}
|
||||||
|
vtkm::testing::TestVectorType(vector);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void TestVectorTraits()
|
||||||
|
{
|
||||||
|
TestVectorTypeFunctor test;
|
||||||
|
vtkm::testing::Testing::TryAllTypes(test);
|
||||||
|
std::cout << "vtkm::Tuple<vtkm::Scalar, 5>" << std::endl;
|
||||||
|
test(vtkm::Tuple<vtkm::Scalar,5>());
|
||||||
|
|
||||||
|
vtkm::testing::TestVectorComponentsTag<vtkm::Id3>();
|
||||||
|
vtkm::testing::TestVectorComponentsTag<vtkm::Vector3>();
|
||||||
|
vtkm::testing::TestVectorComponentsTag<vtkm::Vector4>();
|
||||||
|
vtkm::testing::TestScalarComponentsTag<vtkm::Id>();
|
||||||
|
vtkm::testing::TestScalarComponentsTag<vtkm::Scalar>();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
int UnitTestVectorTraits(int, char *[])
|
||||||
|
{
|
||||||
|
return vtkm::testing::Testing::Run(TestVectorTraits);
|
||||||
|
}
|
157
vtkm/testing/VectorTraitsTests.h
Normal file
157
vtkm/testing/VectorTraitsTests.h
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
//============================================================================
|
||||||
|
// 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 2014 Sandia Corporation.
|
||||||
|
// Copyright 2014 UT-Battelle, LLC.
|
||||||
|
// Copyright 2014. Los Alamos National Security
|
||||||
|
//
|
||||||
|
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
|
||||||
|
// 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 vtkm_testing_VectorTraitsTest_h
|
||||||
|
#define vtkm_testing_VectorTraitsTest_h
|
||||||
|
|
||||||
|
#include <vtkm/VectorTraits.h>
|
||||||
|
|
||||||
|
#include <vtkm/TypeTraits.h>
|
||||||
|
|
||||||
|
#include <vtkm/testing/Testing.h>
|
||||||
|
|
||||||
|
#include <boost/type_traits/remove_const.hpp>
|
||||||
|
|
||||||
|
namespace vtkm {
|
||||||
|
namespace testing {
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
inline void CompareDimensionalityTags(vtkm::TypeTraitsScalarTag,
|
||||||
|
vtkm::VectorTraitsTagSingleComponent)
|
||||||
|
{
|
||||||
|
// If we are here, everything is fine.
|
||||||
|
}
|
||||||
|
inline void CompareDimensionalityTags(vtkm::TypeTraitsVectorTag,
|
||||||
|
vtkm::VectorTraitsTagMultipleComponents)
|
||||||
|
{
|
||||||
|
// If we are here, everything is fine.
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compares some manual arithmetic through type traits to arithmetic with
|
||||||
|
/// the Tuple class.
|
||||||
|
template <class T>
|
||||||
|
static void TestVectorTypeImpl(
|
||||||
|
const typename boost::remove_const<T>::type &vector)
|
||||||
|
{
|
||||||
|
typedef typename vtkm::VectorTraits<T> Traits;
|
||||||
|
typedef typename Traits::ComponentType ComponentType;
|
||||||
|
static const int NUM_COMPONENTS = Traits::NUM_COMPONENTS;
|
||||||
|
typedef typename boost::remove_const<T>::type NonConstT;
|
||||||
|
|
||||||
|
{
|
||||||
|
NonConstT result;
|
||||||
|
const ComponentType multiplier = 4;
|
||||||
|
for (int i = 0; i < NUM_COMPONENTS; i++)
|
||||||
|
{
|
||||||
|
Traits::SetComponent(result, i, multiplier*Traits::GetComponent(vector, i));
|
||||||
|
}
|
||||||
|
VTKM_TEST_ASSERT(test_equal(Traits::ToTuple(result),
|
||||||
|
multiplier*Traits::ToTuple(vector)),
|
||||||
|
"Got bad result for scalar multiple");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
NonConstT result;
|
||||||
|
const ComponentType multiplier = 7;
|
||||||
|
for (int i = 0; i < NUM_COMPONENTS; i++)
|
||||||
|
{
|
||||||
|
Traits::GetComponent(result, i)
|
||||||
|
= multiplier * Traits::GetComponent(vector, i);
|
||||||
|
}
|
||||||
|
VTKM_TEST_ASSERT(test_equal(Traits::ToTuple(result),
|
||||||
|
multiplier*Traits::ToTuple(vector)),
|
||||||
|
"Got bad result for scalar multiple");
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
ComponentType result = 0;
|
||||||
|
for (int i = 0; i < NUM_COMPONENTS; i++)
|
||||||
|
{
|
||||||
|
ComponentType component
|
||||||
|
= Traits::GetComponent(vector, i);
|
||||||
|
result += component * component;
|
||||||
|
}
|
||||||
|
VTKM_TEST_ASSERT(
|
||||||
|
test_equal(result,
|
||||||
|
vtkm::dot(Traits::ToTuple(vector), Traits::ToTuple(vector))),
|
||||||
|
"Got bad result for dot product");
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will fail to compile if the tags are wrong.
|
||||||
|
detail::CompareDimensionalityTags(
|
||||||
|
typename vtkm::TypeTraits<T>::DimensionalityTag(),
|
||||||
|
typename vtkm::VectorTraits<T>::HasMultipleComponents());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void CheckVectorComponentsTag(vtkm::VectorTraitsTagMultipleComponents)
|
||||||
|
{
|
||||||
|
// If we are running here, everything is fine.
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// Checks to make sure that the HasMultipleComponents tag is actually for
|
||||||
|
/// multiple components. Should only be called for vector classes that actually
|
||||||
|
/// have multiple components.
|
||||||
|
///
|
||||||
|
template<class T>
|
||||||
|
inline void TestVectorComponentsTag()
|
||||||
|
{
|
||||||
|
// This will fail to compile if the tag is wrong
|
||||||
|
// (i.e. not vtkm::VectorTraitsTagMultipleComponents)
|
||||||
|
detail::CheckVectorComponentsTag(
|
||||||
|
typename vtkm::VectorTraits<T>::HasMultipleComponents());
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
inline void CheckScalarComponentsTag(vtkm::VectorTraitsTagSingleComponent)
|
||||||
|
{
|
||||||
|
// If we are running here, everything is fine.
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
/// Compares some manual arithmetic through type traits to arithmetic with
|
||||||
|
/// the Tuple class.
|
||||||
|
template <class T>
|
||||||
|
static void TestVectorType(const T &vector)
|
||||||
|
{
|
||||||
|
detail::TestVectorTypeImpl<T>(vector);
|
||||||
|
detail::TestVectorTypeImpl<const T>(vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Checks to make sure that the HasMultipleComponents tag is actually for a
|
||||||
|
/// single component. Should only be called for "vector" classes that actually
|
||||||
|
/// have only a single component (that is, are really scalars).
|
||||||
|
///
|
||||||
|
template<class T>
|
||||||
|
inline void TestScalarComponentsTag()
|
||||||
|
{
|
||||||
|
// This will fail to compile if the tag is wrong
|
||||||
|
// (i.e. not vtkm::VectorTraitsTagSingleComponent)
|
||||||
|
detail::CheckScalarComponentsTag(
|
||||||
|
typename vtkm::VectorTraits<T>::HasMultipleComponents());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
} // namespace vtkm::testing
|
||||||
|
|
||||||
|
#endif //vtkm_testing_VectorTraitsTest_h
|
Loading…
Reference in New Issue
Block a user