Add in the minimum part of the control env to have a testable array handle.

This commit is contained in:
Robert Maynard 2014-02-10 14:53:03 -05:00
parent 24f561f0fe
commit a94abd7a71
37 changed files with 4291 additions and 2 deletions

@ -35,5 +35,4 @@ add_subdirectory(internal)
#-----------------------------------------------------------------------------
#add the control and exec folders
# add_subdirectory(cont)
add_subdirectory(cont)

@ -0,0 +1,168 @@
//============================================================================
// 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__ArrayContainerControl_h
#define vtkm_cont__ArrayContainerControl_h
#define VTKM_ARRAY_CONTAINER_CONTROL_ERROR -1
#define VTKM_ARRAY_CONTAINER_CONTROL_UNDEFINED 0
#define VTKM_ARRAY_CONTAINER_CONTROL_BASIC 1
#ifndef VTKM_ARRAY_CONTAINER_CONTROL
#define VTKM_ARRAY_CONTAINER_CONTROL VTKM_ARRAY_CONTAINER_CONTROL_BASIC
#endif
namespace vtkm {
namespace cont {
#ifdef VTKM_DOXYGEN_ONLY
/// \brief A tag specifying client memory allocation.
///
/// An ArrayContainerControl tag specifies how an ArrayHandle allocates and
/// frees memory. The tag ArrayContainerControlTag___ does not actually exist.
/// Rather, this documentation is provided to describe how array containers are
/// specified. Loading the vtkm/cont/ArrayContainerControl.h header will set a
/// default array container. You can specify the default array container by
/// first setting the VTKM_ARRAY_CONTAINER_CONTROL macro. Currently it can only
/// be set to VTKM_ARRAY_CONTAINER_CONTROL_BASIC.
///
/// User code external to VTKm is free to make its own ArrayContainerControlTag.
/// This is a good way to get VTKm to read data directly in and out of arrays
/// from other libraries. However, care should be taken when creating an
/// ArrayContainerControl. One particular problem that is likely is a container
/// that "constructs" all the items in the array. If done incorrectly, then
/// memory of the array can be incorrectly bound to the wrong process. If you
/// do provide your own ArrayContainerControlTag, please be diligent in
/// comparing its performance to the ArrayContainerControlTagBasic.
///
/// To implement your own ArrayContainerControlTag, you first must create a tag
/// class (an empty struct) defining your tag (i.e. struct
/// ArrayContainerControlTagMyAlloc { };). Then provide a partial template
/// specialization of vtkm::cont::internal::ArrayContainerControl for your new
/// tag.
///
struct ArrayContainerControlTag___ { };
#endif // VTKM_DOXYGEN_ONLY
namespace internal {
/// This templated class must be partially specialized for each
/// ArrayContainerControlTag created, which will define the implementation for
/// that tag.
///
template<typename T, class ArrayContainerControlTag>
class ArrayContainerControl
#ifdef VTKM_DOXYGEN_ONLY
{
public:
/// The type of each item in the array.
///
typedef T ValueType;
/// \brief The type of portal objects for the array.
///
/// The actual portal object can take any form. This is a simple example of a
/// portal to a C array.
///
typedef ::vtkm::cont::internal::ArrayPortalFromIterators<ValueType*> PortalType;
/// \brief The type of portal objects (const version) for the array.
///
/// The actual portal object can take any form. This is a simple example of a
/// portal to a C array.
///
typedef ::vtkm::cont::internal::ArrayPortalFromIterators<const ValueType*> PortalConstType;
/// Returns a portal to the array.
///
VTKM_CONT_EXPORT
PortalType GetPortal();
/// Returns a portal to the array with immutable values.
///
VTKM_CONT_EXPORT
PortalConstType GetPortalConst() const;
/// Retuns the number of entries allocated in the array.
VTKM_CONT_EXPORT
vtkm::Id GetNumberOfValues() const;
/// \brief Allocates an array large enough to hold the given number of values.
///
/// The allocation may be done on an already existing array, but can wipe out
/// any data already in the array. This method can throw
/// ErrorControlOutOfMemory if the array cannot be allocated.
///
VTKM_CONT_EXPORT
void Allocate(vtkm::Id numberOfValues);
/// \brief Reduces the size of the array without changing its values.
///
/// This method allows you to resize the array without reallocating it. The
/// number of entries in the array is changed to \c numberOfValues. The data
/// in the array (from indices 0 to \c numberOfValues - 1) are the same, but
/// \c numberOfValues must be equal or less than the preexisting size
/// (returned from GetNumberOfValues). That is, this method can only be used
/// to shorten the array, not lengthen.
VTKM_CONT_EXPORT
void Shrink(vtkm::Id numberOfValues);
/// \brief Frees any resources (i.e. memory) stored in this array.
///
/// After calling this method GetNumberOfValues will return 0 and
/// GetIteratorBegin and GetIteratorEnd will return the same iterator. The
/// resources should also be released when the ArrayContainerControl class is
/// destroyed.
VTKM_CONT_EXPORT
void ReleaseResources();
};
#else // VTKM_DOXYGEN_ONLY
;
#endif // VTKM_DOXYGEN_ONLY
} // namespace internal
}
} // namespace vtkm::cont
// This is put at the bottom of the header so that the ArrayContainerControl
// template is declared before any implementations are called.
#if VTKM_ARRAY_CONTAINER_CONTROL == VTKM_ARRAY_CONTAINER_CONTROL_BASIC
#include <vtkm/cont/ArrayContainerControlBasic.h>
#define VTKM_DEFAULT_ARRAY_CONTAINER_CONTROL_TAG \
::vtkm::cont::ArrayContainerControlTagBasic
#elif VTKM_ARRAY_CONTAINER_CONTROL == VTKM_ARRAY_CONTAINER_CONTROL_ERROR
#include <vtkm/cont/internal/ArrayContainerControlError.h>
#define VTKM_DEFAULT_ARRAY_CONTAINER_CONTROL_TAG \
::vtkm::cont::internal::ArrayContainerControlTagError
#elif (VTKM_ARRAY_CONTAINER_CONTROL == VTKM_ARRAY_CONTAINER_CONTROL_UNDEFINED) || !defined(VTKM_ARRAY_CONTAINER_CONTROL)
#ifndef VTKM_DEFAULT_ARRAY_CONTAINER_CONTROL_TAG
#warning If array container for control is undefined, VTKM_DEFAULT_ARRAY_CONTAINER_CONTROL_TAG must be defined.
#endif
#endif
#endif //vtkm_cont__ArrayContainerControl_h

@ -0,0 +1,184 @@
//============================================================================
// 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__ArrayContainerControlBasic_h
#define vtkm_cont__ArrayContainerControlBasic_h
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayContainerControl.h>
#include <vtkm/cont/Assert.h>
#include <vtkm/cont/ErrorControlBadValue.h>
#include <vtkm/cont/ErrorControlOutOfMemory.h>
#include <vtkm/cont/internal/ArrayPortalFromIterators.h>
namespace vtkm {
namespace cont {
/// A tag for the basic implementation of an ArrayContainerControl object.
struct ArrayContainerControlTagBasic { };
namespace internal {
/// A basic implementation of an ArrayContainerControl object.
///
/// \todo This container does \em not construct the values within the array.
/// Thus, it is important to not use this class with any type that will fail if
/// not constructed. These are things like basic types (int, float, etc.) and
/// the VTKm Tuple classes. In the future it would be nice to have a compile
/// time check to enforce this.
///
template <typename ValueT>
class ArrayContainerControl<ValueT, vtkm::cont::ArrayContainerControlTagBasic>
{
public:
typedef ValueT ValueType;
typedef vtkm::cont::internal::ArrayPortalFromIterators<ValueType*> PortalType;
typedef vtkm::cont::internal::ArrayPortalFromIterators<const ValueType*> PortalConstType;
private:
/// The original design of this class provided an allocator as a template
/// parameters. That messed things up, though, because other templated
/// classes assume that the \c ArrayContainerControl has one template
/// parameter. There are other ways to allow you to specify the allocator,
/// but it is uncertain whether that would ever be useful. So, instead of
/// jumping through hoops implementing them, just fix the allocator for now.
///
typedef std::allocator<ValueType> AllocatorType;
public:
ArrayContainerControl() : Array(NULL), NumberOfValues(0), AllocatedSize(0) { }
~ArrayContainerControl()
{
this->ReleaseResources();
}
void ReleaseResources()
{
if (this->NumberOfValues > 0)
{
VTKM_ASSERT_CONT(this->Array != NULL);
AllocatorType allocator;
allocator.deallocate(this->Array, this->AllocatedSize);
this->Array = NULL;
this->NumberOfValues = 0;
this->AllocatedSize = 0;
}
else
{
VTKM_ASSERT_CONT(this->Array == NULL);
}
}
void Allocate(vtkm::Id numberOfValues)
{
if (numberOfValues <= this->AllocatedSize)
{
this->NumberOfValues = numberOfValues;
return;
}
this->ReleaseResources();
try
{
if (numberOfValues > 0)
{
AllocatorType allocator;
this->Array = allocator.allocate(numberOfValues);
this->AllocatedSize = numberOfValues;
this->NumberOfValues = numberOfValues;
}
else
{
// ReleaseResources should have already set AllocatedSize to 0.
VTKM_ASSERT_CONT(this->AllocatedSize == 0);
}
}
catch (std::bad_alloc err)
{
// Make sureour state is OK.
this->Array = NULL;
this->NumberOfValues = 0;
this->AllocatedSize = 0;
throw vtkm::cont::ErrorControlOutOfMemory(
"Could not allocate basic control array.");
}
}
vtkm::Id GetNumberOfValues() const
{
return this->NumberOfValues;
}
void Shrink(vtkm::Id numberOfValues)
{
if (numberOfValues > this->GetNumberOfValues())
{
throw vtkm::cont::ErrorControlBadValue(
"Shrink method cannot be used to grow array.");
}
this->NumberOfValues = numberOfValues;
}
PortalType GetPortal()
{
return PortalType(this->Array, this->Array + this->NumberOfValues);
}
PortalConstType GetPortalConst() const
{
return PortalConstType(this->Array, this->Array + this->NumberOfValues);
}
/// \brief Take the reference away from this object.
///
/// This method returns the pointer to the array held by this array. It then
/// clears the internal array pointer to NULL, thereby ensuring that the
/// ArrayContainerControl will never deallocate the array. This is
/// helpful for taking a reference for an array created internally by VTKm and
/// not having to keep a VTKm object around. Obviously the caller becomes
/// responsible for destroying the memory.
///
ValueType *StealArray()
{
ValueType *saveArray = this->Array;
this->Array = NULL;
this->NumberOfValues = 0;
this->AllocatedSize = 0;
return saveArray;
}
private:
// Not implemented.
ArrayContainerControl(const ArrayContainerControl<ValueType, ArrayContainerControlTagBasic> &src);
void operator=(const ArrayContainerControl<ValueType, ArrayContainerControlTagBasic> &src);
ValueType *Array;
vtkm::Id NumberOfValues;
vtkm::Id AllocatedSize;
};
} // namespace internal
}
} // namespace vtkm::cont
#endif //vtkm_cont__ArrayContainerControlBasic_h

@ -0,0 +1,192 @@
//============================================================================
// 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_ArrayContainerControlImplicit
#define vtkm_cont_ArrayContainerControlImplicit
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayContainerControl.h>
#include <vtkm/cont/Assert.h>
#include <vtkm/cont/ErrorControlBadValue.h>
#include <vtkm/cont/internal/ArrayTransfer.h>
namespace vtkm {
namespace cont {
/// \brief An implementation for read-only implicit arrays.
///
/// It is sometimes the case that you want VTKm to operate on an array of
/// implicit values. That is, rather than store the data in an actual array, it
/// is gerenated on the fly by a function. This is handled in VTKm by creating
/// an ArrayHandle in VTKm with an ArrayContainerControlTagImplicit type of
/// ArrayContainerControl. This tag itself is templated to specify an
/// ArrayPortal that generates the desired values. An ArrayHandle created with
/// this tag will raise an error on any operation that tries to modify it.
///
/// \todo The ArrayHandle currently copies the array in cases where the control
/// and environment do not share memory. This is wasteful and should be fixed.
///
template<class ArrayPortalType>
struct ArrayContainerControlTagImplicit {
typedef ArrayPortalType PortalType;
};
namespace internal {
template<class ArrayPortalType>
class ArrayContainerControl<
typename ArrayPortalType::ValueType,
ArrayContainerControlTagImplicit<ArrayPortalType> >
{
public:
typedef typename ArrayPortalType::ValueType ValueType;
typedef ArrayPortalType PortalConstType;
// This is meant to be invalid. Because implicit arrays are read only, you
// should only be able to use the const version.
struct PortalType {
typedef void *ValueType;
typedef void *IteratorType;
};
// All these methods do nothing but raise errors.
PortalType GetPortal() {
throw vtkm::cont::ErrorControlBadValue("Implicit arrays are read-only.");
}
PortalConstType GetPortalConst() const {
// This does not work because the ArrayHandle holds the constant
// ArrayPortal, not the container.
throw vtkm::cont::ErrorControlBadValue(
"Implicit container does not store array portal. "
"Perhaps you did not set the ArrayPortal when "
"constructing the ArrayHandle.");
}
vtkm::Id GetNumberOfValues() const {
// This does not work because the ArrayHandle holds the constant
// ArrayPortal, not the container.
throw vtkm::cont::ErrorControlBadValue(
"Implicit container does not store array portal. "
"Perhaps you did not set the ArrayPortal when "
"constructing the ArrayHandle.");
}
void Allocate(vtkm::Id vtkmNotUsed(numberOfValues)) {
throw vtkm::cont::ErrorControlBadValue("Implicit arrays are read-only.");
}
void Shrink(vtkm::Id vtkmNotUsed(numberOfValues)) {
throw vtkm::cont::ErrorControlBadValue("Implicit arrays are read-only.");
}
void ReleaseResources() {
throw vtkm::cont::ErrorControlBadValue("Implicit arrays are read-only.");
}
};
template<typename T, class ArrayPortalType, class DeviceAdapterTag>
class ArrayTransfer<
T, ArrayContainerControlTagImplicit<ArrayPortalType>, DeviceAdapterTag>
{
private:
typedef ArrayContainerControlTagImplicit<ArrayPortalType>
ArrayContainerControlTag;
typedef vtkm::cont::internal::ArrayContainerControl<T,ArrayContainerControlTag>
ContainerType;
public:
typedef T ValueType;
typedef typename ContainerType::PortalType PortalControl;
typedef typename ContainerType::PortalConstType PortalConstControl;
typedef PortalControl PortalExecution;
typedef PortalConstControl PortalConstExecution;
ArrayTransfer() : PortalValid(false) { }
VTKM_CONT_EXPORT vtkm::Id GetNumberOfValues() const {
VTKM_ASSERT_CONT(this->PortalValid);
return this->Portal.GetNumberOfValues();
}
VTKM_CONT_EXPORT void LoadDataForInput(PortalConstControl portal) {
this->Portal = portal;
this->PortalValid = true;
}
VTKM_CONT_EXPORT void LoadDataForInput(const ContainerType &controlArray) {
this->LoadDataForInput(controlArray.GetPortalConst());
}
VTKM_CONT_EXPORT
void LoadDataForInPlace(ContainerType &vtkmNotUsed(controlArray))
{
throw vtkm::cont::ErrorControlBadValue(
"Implicit arrays cannot be used for output or in place.");
}
VTKM_CONT_EXPORT void AllocateArrayForOutput(
ContainerType &vtkmNotUsed(controlArray),
vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorControlBadValue(
"Implicit arrays cannot be used for output.");
}
VTKM_CONT_EXPORT void RetrieveOutputData(
ContainerType &vtkmNotUsed(controlArray)) const
{
throw vtkm::cont::ErrorControlBadValue(
"Implicit arrays cannot be used for output.");
}
template <class IteratorTypeControl>
VTKM_CONT_EXPORT void CopyInto(IteratorTypeControl dest) const
{
VTKM_ASSERT_CONT(this->PortalValid);
std::copy(this->Portal.GetIteratorBegin(),
this->Portal.GetIteratorEnd(),
dest);
}
VTKM_CONT_EXPORT void Shrink(vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorControlBadValue("Implicit arrays cannot be resized.");
}
VTKM_CONT_EXPORT PortalExecution GetPortalExecution()
{
throw vtkm::cont::ErrorControlBadValue(
"Implicit arrays are read-only. (Get the const portal.)");
}
VTKM_CONT_EXPORT PortalConstExecution GetPortalConstExecution() const
{
VTKM_ASSERT_CONT(this->PortalValid);
return this->Portal;
}
VTKM_CONT_EXPORT void ReleaseResources() { }
private:
PortalConstExecution Portal;
bool PortalValid;
};
} // namespace internal
}
} // namespace vtkm::cont
#endif //vtkm_cont_ArrayContainerControlImplicit

537
vtkm/cont/ArrayHandle.h Normal file

@ -0,0 +1,537 @@
//============================================================================
// 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_ArrayHandle_h
#define vtkm_cont_ArrayHandle_h
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayContainerControl.h>
#include <vtkm/cont/Assert.h>
#include <vtkm/cont/ErrorControlBadValue.h>
#include <vtkm/cont/internal/ArrayHandleExecutionManager.h>
#include <vtkm/cont/internal/ArrayTransfer.h>
#include <vtkm/cont/internal/DeviceAdapterTag.h>
#include <boost/concept_check.hpp>
#include <boost/smart_ptr/scoped_ptr.hpp>
#include <boost/smart_ptr/shared_ptr.hpp>
#include <vector>
namespace vtkm {
namespace cont {
// Forward declaration
namespace internal { class ArrayHandleAccess; }
/// \brief Manages an array-worth of data.
///
/// \c ArrayHandle manages as array of data that can be manipulated by VTKm
/// algorithms. The \c ArrayHandle may have up to two copies of the array, one
/// for the control environment and one for the execution environment, although
/// depending on the device and how the array is being used, the \c ArrayHandle
/// will only have one copy when possible.
///
/// An ArrayHandle can be constructed one of two ways. Its default construction
/// creates an empty, unallocated array that can later be allocated and filled
/// either by the user or a VTKm algorithm. The \c ArrayHandle can also be
/// constructed with iterators to a user's array. In this case the \c
/// ArrayHandle will keep a reference to this array but may drop it if the
/// array is reallocated.
///
/// \c ArrayHandle behaves like a shared smart pointer in that when it is copied
/// each copy holds a reference to the same array. These copies are reference
/// counted so that when all copies of the \c ArrayHandle are destroyed, any
/// allocated memory is released.
///
template<
typename T,
typename ArrayContainerControlTag_ = VTKM_DEFAULT_ARRAY_CONTAINER_CONTROL_TAG>
class ArrayHandle
{
private:
typedef vtkm::cont::internal
::ArrayContainerControl<T,ArrayContainerControlTag_>
ArrayContainerControlType;
typedef vtkm::cont::internal
::ArrayHandleExecutionManagerBase<T,ArrayContainerControlTag_>
ExecutionManagerType;
public:
typedef T ValueType;
typedef ArrayContainerControlTag_ ArrayContainerControlTag;
typedef typename ArrayContainerControlType::PortalType PortalControl;
typedef typename ArrayContainerControlType::PortalConstType
PortalConstControl;
template <typename DeviceAdapterTag>
struct ExecutionTypes {
typedef typename ExecutionManagerType
::template ExecutionTypes<DeviceAdapterTag>::Portal Portal;
typedef typename ExecutionManagerType
::template ExecutionTypes<DeviceAdapterTag>::PortalConst PortalConst;
};
/// Constructs an empty ArrayHandle. Typically used for output or
/// intermediate arrays that will be filled by a VTKm algorithm.
///
VTKM_CONT_EXPORT ArrayHandle() : Internals(new InternalStruct)
{
this->Internals->UserPortalValid = false;
this->Internals->ControlArrayValid = false;
this->Internals->ExecutionArrayValid = false;
}
/// Constructs an ArrayHandle pointing to the data in the given array portal.
///
VTKM_CONT_EXPORT ArrayHandle(PortalConstControl userData)
: Internals(new InternalStruct)
{
this->Internals->UserPortal = userData;
this->Internals->UserPortalValid = true;
this->Internals->ControlArrayValid = false;
this->Internals->ExecutionArrayValid = false;
}
/// Get the array portal of the control array.
///
VTKM_CONT_EXPORT PortalControl GetPortalControl()
{
this->SyncControlArray();
if (this->Internals->UserPortalValid)
{
throw vtkm::cont::ErrorControlBadValue(
"ArrayHandle has a read-only control portal.");
}
else if (this->Internals->ControlArrayValid)
{
// If the user writes into the iterator we return, then the execution
// array will become invalid. Play it safe and release the execution
// resources. (Use the const version to preserve the execution array.)
this->ReleaseResourcesExecution();
return this->Internals->ControlArray.GetPortal();
}
else
{
throw vtkm::cont::ErrorControlBadValue("ArrayHandle contains no data.");
}
}
/// Get the array portal of the control array.
///
VTKM_CONT_EXPORT PortalConstControl GetPortalConstControl() const
{
this->SyncControlArray();
if (this->Internals->UserPortalValid)
{
return this->Internals->UserPortal;
}
else if (this->Internals->ControlArrayValid)
{
return this->Internals->ControlArray.GetPortalConst();
}
else
{
throw vtkm::cont::ErrorControlBadValue("ArrayHandle contains no data.");
}
}
/// Returns the number of entries in the array.
///
VTKM_CONT_EXPORT vtkm::Id GetNumberOfValues() const
{
if (this->Internals->UserPortalValid)
{
return this->Internals->UserPortal.GetNumberOfValues();
}
else if (this->Internals->ControlArrayValid)
{
return this->Internals->ControlArray.GetNumberOfValues();
}
else if (this->Internals->ExecutionArrayValid)
{
return
this->Internals->ExecutionArray->GetNumberOfValues();
}
else
{
return 0;
}
}
/// \brief Reduces the size of the array without changing its values.
///
/// This method allows you to resize the array without reallocating it. The
/// number of entries in the array is changed to \c numberOfValues. The data
/// in the array (from indices 0 to \c numberOfValues - 1) are the same, but
/// \c numberOfValues must be equal or less than the preexisting size
/// (returned from GetNumberOfValues). That is, this method can only be used
/// to shorten the array, not lengthen.
void Shrink(vtkm::Id numberOfValues)
{
vtkm::Id originalNumberOfValues = this->GetNumberOfValues();
if (numberOfValues < originalNumberOfValues)
{
if (this->Internals->UserPortalValid)
{
throw vtkm::cont::ErrorControlBadValue(
"ArrayHandle has a read-only control portal.");
}
if (this->Internals->ControlArrayValid)
{
this->Internals->ControlArray.Shrink(numberOfValues);
}
if (this->Internals->ExecutionArrayValid)
{
this->Internals->ExecutionArray->Shrink(numberOfValues);
}
}
else if (numberOfValues == originalNumberOfValues)
{
// Nothing to do.
}
else // numberOfValues > originalNumberOfValues
{
throw vtkm::cont::ErrorControlBadValue(
"ArrayHandle::Shrink cannot be used to grow array.");
}
VTKM_ASSERT_CONT(this->GetNumberOfValues() == numberOfValues);
}
/// Releases any resources being used in the execution environment (that are
/// not being shared by the control environment).
///
VTKM_CONT_EXPORT void ReleaseResourcesExecution()
{
if (this->Internals->ExecutionArrayValid)
{
this->Internals->ExecutionArray->ReleaseResources();
this->Internals->ExecutionArrayValid = false;
}
}
/// Releases all resources in both the control and execution environments.
///
VTKM_CONT_EXPORT void ReleaseResources()
{
this->ReleaseResourcesExecution();
// Forget about any user iterators.
this->Internals->UserPortalValid = false;
if (this->Internals->ControlArrayValid)
{
this->Internals->ControlArray.ReleaseResources();
this->Internals->ControlArrayValid = false;
}
}
/// Prepares this array to be used as an input to an operation in the
/// execution environment. If necessary, copies data to the execution
/// environment. Can throw an exception if this array does not yet contain
/// any data. Returns a portal that can be used in code running in the
/// execution environment.
///
template<typename DeviceAdapterTag>
VTKM_CONT_EXPORT
typename ExecutionTypes<DeviceAdapterTag>::PortalConst
PrepareForInput(DeviceAdapterTag) const
{
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
if (this->Internals->ExecutionArrayValid)
{
// Nothing to do, data already loaded.
}
else if (this->Internals->UserPortalValid)
{
VTKM_ASSERT_CONT(!this->Internals->ControlArrayValid);
this->PrepareForDevice(DeviceAdapterTag());
this->Internals->ExecutionArray->LoadDataForInput(
this->Internals->UserPortal);
this->Internals->ExecutionArrayValid = true;
}
else if (this->Internals->ControlArrayValid)
{
this->PrepareForDevice(DeviceAdapterTag());
this->Internals->ExecutionArray->LoadDataForInput(
this->Internals->ControlArray);
this->Internals->ExecutionArrayValid = true;
}
else
{
throw vtkm::cont::ErrorControlBadValue(
"ArrayHandle has no data when PrepareForInput called.");
}
return this->Internals->ExecutionArray->GetPortalConstExecution(
DeviceAdapterTag());
}
/// Prepares (allocates) this array to be used as an output from an operation
/// in the execution environment. The internal state of this class is set to
/// have valid data in the execution array with the assumption that the array
/// will be filled soon (i.e. before any other methods of this object are
/// called). Returns a portal that can be used in code running in the
/// execution environment.
///
template<typename DeviceAdapterTag>
VTKM_CONT_EXPORT
typename ExecutionTypes<DeviceAdapterTag>::Portal
PrepareForOutput(vtkm::Id numberOfValues, DeviceAdapterTag)
{
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
// Invalidate any control arrays.
// Should the control array resource be released? Probably not a good
// idea when shared with execution.
this->Internals->UserPortalValid = false;
this->Internals->ControlArrayValid = false;
this->PrepareForDevice(DeviceAdapterTag());
this->Internals->ExecutionArray->AllocateArrayForOutput(
this->Internals->ControlArray, numberOfValues);
// We are assuming that the calling code will fill the array using the
// iterators we are returning, so go ahead and mark the execution array as
// having valid data. (A previous version of this class had a separate call
// to mark the array as filled, but that was onerous to call at the the
// right time and rather pointless since it is basically always the case
// that the array is going to be filled before anything else. In this
// implementation the only access to the array is through the iterators
// returned from this method, so you would have to work to invalidate this
// assumption anyway.)
this->Internals->ExecutionArrayValid = true;
return this->Internals->ExecutionArray->GetPortalExecution(DeviceAdapterTag());
}
/// Prepares this array to be used in an in-place operation (both as input
/// and output) in the execution environment. If necessary, copies data to
/// the execution environment. Can throw an exception if this array does not
/// yet contain any data. Returns a portal that can be used in code running
/// in the execution environment.
///
template<typename DeviceAdapterTag>
VTKM_CONT_EXPORT
typename ExecutionTypes<DeviceAdapterTag>::Portal
PrepareForInPlace(DeviceAdapterTag)
{
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
if (this->Internals->UserPortalValid)
{
throw vtkm::cont::ErrorControlBadValue(
"In place execution cannot be used with an ArrayHandle that has "
"user arrays because this might write data back into user space "
"unexpectedly. Copy the data to a new array first.");
}
// This code is similar to PrepareForInput except that we have to give a
// writable portal instead of the const portal to the execution array
// manager so that the data can (potentially) be written to.
if (this->Internals->ExecutionArrayValid)
{
// Nothing to do, data already loaded.
}
else if (this->Internals->ControlArrayValid)
{
this->PrepareForDevice(DeviceAdapterTag());
this->Internals->ExecutionArray->LoadDataForInPlace(
this->Internals->ControlArray);
this->Internals->ExecutionArrayValid = true;
}
else
{
throw vtkm::cont::ErrorControlBadValue(
"ArrayHandle has no data when PrepareForInput called.");
}
// Invalidate any control arrays since their data will become invalid when
// the execution data is overwritten. Don't actually release the control
// array. It may be shared as the execution array.
this->Internals->ControlArrayValid = false;
return this->Internals->ExecutionArray->GetPortalExecution(DeviceAdapterTag());
}
// protected:
/// Special constructor for subclass specializations that need to set the
/// initial state of the control array. When this constructor is used, it
/// is assumed that the control array is valid.
///
ArrayHandle(const ArrayContainerControlType &container)
: Internals(new InternalStruct)
{
this->Internals->UserPortalValid = false;
this->Internals->ControlArray = container;
this->Internals->ControlArrayValid = true;
this->Internals->ExecutionArrayValid = false;
}
// private:
struct InternalStruct {
PortalConstControl UserPortal;
bool UserPortalValid;
ArrayContainerControlType ControlArray;
bool ControlArrayValid;
boost::scoped_ptr<
vtkm::cont::internal::ArrayHandleExecutionManagerBase<
ValueType,ArrayContainerControlTag> > ExecutionArray;
bool ExecutionArrayValid;
};
ArrayHandle(boost::shared_ptr<InternalStruct> i)
: Internals(i)
{ }
/// Gets this array handle ready to interact with the given device. If the
/// array handle has already interacted with this device, then this method
/// does nothing. Although the internal state of this class can change, the
/// method is declared const because logically the data does not.
///
template<typename DeviceAdapterTag>
VTKM_CONT_EXPORT
void PrepareForDevice(DeviceAdapterTag) const
{
if (this->Internals->ExecutionArray != NULL)
{
if (this->Internals->ExecutionArray->IsDeviceAdapter(DeviceAdapterTag()))
{
// Already have manager for correct device adapter. Nothing to do.
return;
}
else
{
// Have the wrong manager. Delete the old one and create a new one
// of the right type. (BTW, it would be possible for the array handle
// to hold references to execution arrays on multiple devices. However,
// there is not a clear use case for that yet and it is unclear what
// the behavior of "dirty" arrays should be, so it is not currently
// implemented.)
this->SyncControlArray();
// Need to change some state that does not change the logical state from
// an external point of view.
InternalStruct *internals
= const_cast<InternalStruct*>(this->Internals.get());
internals->ExecutionArray.reset();
internals->ExecutionArrayValid = false;
}
}
VTKM_ASSERT_CONT(this->Internals->ExecutionArray == NULL);
VTKM_ASSERT_CONT(this->Internals->ExecutionArrayValid == false);
// Need to change some state that does not change the logical state from
// an external point of view.
InternalStruct *internals
= const_cast<InternalStruct*>(this->Internals.get());
internals->ExecutionArray.reset(
new vtkm::cont::internal::ArrayHandleExecutionManager<
T, ArrayContainerControlTag, DeviceAdapterTag>);
}
/// Synchronizes the control array with the execution array. If either the
/// user array or control array is already valid, this method does nothing
/// (because the data is already available in the control environment).
/// Although the internal state of this class can change, the method is
/// declared const because logically the data does not.
///
VTKM_CONT_EXPORT void SyncControlArray() const
{
if ( !this->Internals->UserPortalValid
&& !this->Internals->ControlArrayValid)
{
// Need to change some state that does not change the logical state from
// an external point of view.
InternalStruct *internals
= const_cast<InternalStruct*>(this->Internals.get());
internals->ExecutionArray->RetrieveOutputData(internals->ControlArray);
internals->ControlArrayValid = true;
}
else
{
// It should never be the case that both the user and control array are
// valid.
VTKM_ASSERT_CONT(!this->Internals->UserPortalValid
|| !this->Internals->ControlArrayValid);
// Nothing to do.
}
}
boost::shared_ptr<InternalStruct> Internals;
};
/// A convenience function for creating an ArrayHandle from a standard C
/// array. Unless properly specialized, this only works with container types
/// that use an array portal that accepts a pair of pointers to signify the
/// beginning and end of the array.
///
template<typename T, typename ArrayContainerControlTag>
VTKM_CONT_EXPORT
vtkm::cont::ArrayHandle<T, ArrayContainerControlTag>
make_ArrayHandle(const T *array,
vtkm::Id length,
ArrayContainerControlTag)
{
typedef vtkm::cont::ArrayHandle<T, ArrayContainerControlTag> ArrayHandleType;
typedef typename ArrayHandleType::PortalConstControl PortalType;
return ArrayHandleType(PortalType(array, array+length));
}
template<typename T>
VTKM_CONT_EXPORT
vtkm::cont::ArrayHandle<T, VTKM_DEFAULT_ARRAY_CONTAINER_CONTROL_TAG>
make_ArrayHandle(const T *array, vtkm::Id length)
{
return make_ArrayHandle(array,
length,
VTKM_DEFAULT_ARRAY_CONTAINER_CONTROL_TAG());
}
/// A convenience function for creating an ArrayHandle from an std::vector.
/// Unless properly specialized, this only works with container types that use
/// an array portal that accepts a pair of pointers to signify the beginning
/// and end of the array.
///
template<typename T,
typename Allocator,
typename ArrayContainerControlTag>
VTKM_CONT_EXPORT
vtkm::cont::ArrayHandle<T, ArrayContainerControlTag>
make_ArrayHandle(const std::vector<T,Allocator> &array,
ArrayContainerControlTag)
{
typedef vtkm::cont::ArrayHandle<T, ArrayContainerControlTag> ArrayHandleType;
typedef typename ArrayHandleType::PortalConstControl PortalType;
return ArrayHandleType(PortalType(&array.front(), &array.back() + 1));
}
template<typename T, typename Allocator>
VTKM_CONT_EXPORT
vtkm::cont::ArrayHandle<T, VTKM_DEFAULT_ARRAY_CONTAINER_CONTROL_TAG>
make_ArrayHandle(const std::vector<T,Allocator> &array)
{
return make_ArrayHandle(array, VTKM_DEFAULT_ARRAY_CONTAINER_CONTROL_TAG());
}
}
}
#endif //vtkm_cont_ArrayHandle_h

107
vtkm/cont/ArrayPortal.h Normal file

@ -0,0 +1,107 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// 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_ArrayPortal_h
#define vtkm_cont_ArrayPortal_h
#include <vtkm/Types.h>
namespace vtkm {
namespace cont {
#ifdef VTKM_DOXYGEN_ONLY
/// \brief A class that points to and access and array of data.
///
/// The ArrayPortal class itself does not exist; this code is provided for
/// documentation purposes only.
///
/// An ArrayPortal object acts like a pointer to a random-access container
/// (that is, an array) and also lets you set and get values in that array. In
/// many respects an ArrayPortal is similar in concept to that of iterators but
/// with a much simpler interface and no internal concept of position.
/// Otherwise, ArrayPortal objects may be passed and copied around so that
/// multiple entities may be accessing the same array.
///
/// An ArrayPortal differs from an ArrayHandle in that the ArrayPortal is a
/// much lighterweight object and that it does not manage things like
/// allocation and control/execution sharing. An ArrayPortal also differs from
/// an ArrayContainer in that it does not actually contain the data but rather
/// points to it. In this way the ArrayPortal can be copied and passed and
/// still point to the same data.
///
/// Most VTKm users generally do not need to do much or anything with
/// ArrayPortal objects. It is mostly an internal mechanism. However, an
/// ArrayPortal can be used to pass constant input data to an ArrayHandle.
///
/// Although this documentation is given for the control environment, there are
/// instances of an identical concept in the execution environment, although
/// some features are missing there.
///
template<typename T>
class ArrayPortal
{
public:
/// The type of each value in the array.
///
typedef T ValueType;
/// The total number of values in the array. They are index from 0 to
/// GetNumberOfValues()-1.
///
VTKM_CONT_EXPORT
vtkm::Id GetNumberOfValues() const;
/// Gets a value from the array.
///
VTKM_CONT_EXPORT
ValueType Get(vtkm::Id index) const;
/// Sets a value in the array. This function may not exist for an ArrayPortal
/// pointing to a const array.
///
VTKM_CONT_EXPORT
void Set(vtkm::Id index, const ValueType &value) const;
/// An iterator type that can be used as an alternate way to access the data.
/// If the container being pointed to has a natural iterator that can be
/// used, then use that. Otherwise, use IteratorForArrayPortal. Iterators are
/// not necessary for array portals in the execution environment.
///
typedef ValueType *IteratorType;
/// Returns an iterator to the beginning of the array. Iterators are not
/// necessary for array portals in the execution environment.
///
VTKM_CONT_EXPORT
IteratorType GetIteratorBegin() const;
/// Returns an iterator to the end of the array. Iterators are not necessary
/// for array portals in the execution environment.
///
VTKM_CONT_EXPORT
IteratorType GetIteratorEnd() const;
};
#endif // VTKM_DOXYGEN_ONLY
}
} // namespace vtkm::cont
#endif //vtkm_cont_ArrayPortal_h

64
vtkm/cont/Assert.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_cont_Assert_h
#define vtkm_cont_Assert_h
#include <vtkm/cont/ErrorControlAssert.h>
// Stringify macros for VTKM_ASSERT_CONT
#define __VTKM_ASSERT_CONT_STRINGIFY_2ND(s) #s
#define __VTKM_ASSERT_CONT_STRINGIFY(s) __VTKM_ASSERT_CONT_STRINGIFY_2ND(s)
/// \def VTKM_ASSERT_CONT(condition)
///
/// Asserts that \a condition resolves to true. If \a condition is false,
/// then an error is raised. This macro is meant to work in the VTKm control
/// environment and throws an ErrorControlAssert object on failure.
#ifndef NDEBUG
#define VTKM_ASSERT_CONT(condition) \
if (!(condition)) \
::vtkm::cont::Assert(condition, __FILE__, __LINE__, #condition)
#else
#define VTKM_ASSERT_CONT(condition)
#endif
namespace vtkm {
namespace cont {
VTKM_CONT_EXPORT void Assert(bool condition,
const std::string &file,
vtkm::Id line,
const std::string &message)
{
if (condition)
{
// Do nothing.
}
else
{
throw vtkm::cont::ErrorControlAssert(file, line, message);
}
}
}
} // namespace vtkm::cont
#endif //vtkm_cont_Assert_h

46
vtkm/cont/CMakeLists.txt Normal file

@ -0,0 +1,46 @@
##============================================================================
## 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_directories(${Boost_INCLUDE_DIRS})
set(headers
ArrayContainerControl.h
ArrayContainerControlBasic.h
ArrayContainerControlImplicit.h
ArrayHandle.h
ArrayPortal.h
Assert.h
Error.h
ErrorControl.h
ErrorControlAssert.h
ErrorControlBadValue.h
ErrorControlInternal.h
ErrorControlOutOfMemory.h
ErrorExecution.h
)
#-----------------------------------------------------------------------------
add_subdirectory(internal)
vtkm_declare_headers(${impl_headers} ${headers})
#-----------------------------------------------------------------------------
add_subdirectory(testing)

54
vtkm/cont/Error.h Normal file

@ -0,0 +1,54 @@
//============================================================================
// 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_Error_h
#define vtkm_cont_Error_h
// Note that this class and (most likely) all of its subclasses are not
// templated. If there is any reason to create a VTKm control library,
// this class and its subclasses should probably go there.
#include <string>
namespace vtkm {
namespace cont {
/// The superclass of all exceptions thrown by any VTKm function or method.
///
class Error
{
public:
const std::string &GetMessage() const { return this->Message; }
protected:
Error() { }
Error(const std::string message) : Message(message) { }
void SetMessage(const std::string &message) {
this->Message = message;
}
private:
std::string Message;
};
}
} // namespace vtkm::cont
#endif //vtkm_cont_Error_h

41
vtkm/cont/ErrorControl.h Normal file

@ -0,0 +1,41 @@
//============================================================================
// 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_ErrorControl_h
#define vtkm_cont_ErrorControl_h
#include <vtkm/cont/Error.h>
namespace vtkm {
namespace cont {
/// The superclass of all exceptions thrown from within the VTKm control
/// environment.
///
class ErrorControl : public vtkm::cont::Error
{
protected:
ErrorControl() { }
ErrorControl(const std::string message) : Error(message) { }
};
}
} // namespace vtkm::cont
#endif //vtkm_cont_ErrorControl_h

@ -0,0 +1,56 @@
//============================================================================
// 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_ErrorControlAssert_h
#define vtkm_cont_ErrorControlAssert_h
#include <vtkm/Types.h>
#include <vtkm/cont/ErrorControl.h>
#include <sstream>
namespace vtkm {
namespace cont {
/// This error is thrown whenever VTKM_ASSERT_CONT fails.
///
class ErrorControlAssert : public vtkm::cont::ErrorControl
{
public:
ErrorControlAssert(const std::string &file,
vtkm::Id line,
const std::string &condition)
: ErrorControl(), File(file), Line(line), Condition(condition)
{
std::stringstream message;
message << this->File << ":" << this->Line
<< ": Assert Failed (" << this->Condition << ")";
this->SetMessage(message.str());
}
private:
std::string File;
vtkm::Id Line;
std::string Condition;
};
}
}
#endif //vtkm_cont_ErrorControlAssert_h

@ -0,0 +1,41 @@
//============================================================================
// 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_ErrorControlBadValue_h
#define vtkm_cont_ErrorControlBadValue_h
#include <vtkm/cont/ErrorControl.h>
namespace vtkm {
namespace cont {
/// This class is thrown when a VTKm function or method encounters an invalid
/// value that inhibits progress.
///
class ErrorControlBadValue : public ErrorControl
{
public:
ErrorControlBadValue(const std::string &message)
: ErrorControl(message) { }
};
}
} // namespace vtkm::cont
#endif //vtkm_cont_ErrorControlBadValue_h

@ -0,0 +1,42 @@
//============================================================================
// 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_ErrorControlInternal_h
#define vtkm_cont_ErrorControlInternal_h
#include <vtkm/cont/ErrorControl.h>
namespace vtkm {
namespace cont {
/// This class is thrown when VTKm detects an internal state that should never
/// be reached. This error usually indicates a bug in vtkm or, at best, VTKm
/// failed to detect an invalid input it should have.
///
class ErrorControlInternal : public ErrorControl
{
public:
ErrorControlInternal(const std::string &message)
: ErrorControl(message) { }
};
}
} // namespace vtkm::cont
#endif //vtkm_cont_ErrorControlInternal_h

@ -0,0 +1,41 @@
//============================================================================
// 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_ErrorControlOutOfMemory_h
#define vtkm_cont_ErrorControlOutOfMemory_h
#include <vtkm/cont/ErrorControl.h>
namespace vtkm {
namespace cont {
/// This class is thrown when a vtkm function or method tries to allocate an
/// array and fails.
///
class ErrorControlOutOfMemory : public ErrorControl
{
public:
ErrorControlOutOfMemory(const std::string &message)
: ErrorControl(message) { }
};
}
} // namespace vtkm::cont
#endif //vtkm_cont_ErrorControlOutOfMemory_h

@ -0,0 +1,41 @@
//============================================================================
// 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_ErrorExecution_h
#define vtkm_cont_ErrorExecution_h
#include <vtkm/cont/Error.h>
namespace vtkm {
namespace cont {
/// This class is thrown in the control environment whenever an error occurs in
/// the execution environment.
///
class ErrorExecution : public vtkm::cont::Error
{
public:
ErrorExecution(const std::string message)
: Error(message) { }
};
}
} // namespace vtkm::cont
#endif //vtkm_cont_ErrorExecution_h

@ -0,0 +1,42 @@
//============================================================================
// 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_ArrayContainerControlError_h
#define vtkm_cont_internal_ArrayContainerControlError_h
namespace vtkm {
namespace cont {
namespace internal {
/// This is an invalid ArrayContainerControl. The point of this class is to
/// include the header file to make this invalid class the default
/// ArrayContainerControl. From that point, you have to specify an appropriate
/// ArrayContainerControl or else get a compile error.
///
struct ArrayContainerControlTagError
{
// Not implemented.
};
}
}
} // namespace vtkm::cont::internal
#endif //vtkm_cont_internal_ArrayContainerControlError_h

@ -0,0 +1,286 @@
//============================================================================
// 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_exec_ArrayHandleExecutionManager_h
#define vtkm_cont_exec_ArrayHandleExecutionManager_h
#include <vtkm/cont/ArrayContainerControl.h>
#include <vtkm/cont/ErrorControlInternal.h>
#include <vtkm/cont/internal/ArrayTransfer.h>
namespace vtkm {
namespace cont {
namespace internal {
/// The common base for ArrayHandleExecutionManager. This is the interface
/// used when the type of the device is not known at run time.
///
template<typename T, typename Container>
class ArrayHandleExecutionManagerBase
{
private:
typedef vtkm::cont::internal::ArrayContainerControl<T,Container>
ContainerType;
public:
template <typename DeviceAdapter>
struct ExecutionTypes {
private:
typedef vtkm::cont::internal::ArrayTransfer<T,Container,DeviceAdapter>
ArrayTransferType;
public:
typedef typename ArrayTransferType::PortalExecution Portal;
typedef typename ArrayTransferType::PortalConstExecution PortalConst;
};
/// The type of value held in the array (vtkm::Scalar, vtkm::Vector3, etc.)
///
typedef T ValueType;
/// An array portal that can be used in the control environment.
///
typedef typename ContainerType::PortalType PortalControl;
typedef typename ContainerType::PortalConstType PortalConstControl;
VTKM_CONT_EXPORT
virtual ~ArrayHandleExecutionManagerBase() { }
/// Returns the number of values stored in the array. Results are undefined
/// if data has not been loaded or allocated.
///
virtual vtkm::Id GetNumberOfValues() const = 0;
/// Allocates a large enough array in the execution environment and copies
/// the given data to that array. The allocated array can later be accessed
/// via the GetPortalConstExecution method. If control and execution share
/// arrays, then this method may save the iterators to be returned in the \c
/// GetPortalConst methods.
///
virtual void LoadDataForInput(PortalConstControl portal) = 0;
/// Allocates a large enough array in the execution environment and copies
/// the given data to that array. The allocated array can later be accessed
/// via the GetPortalConstExecution method. If control and execution share
/// arrays, then this method may save the iterators to be returned in the \c
/// GetPortalConst methods.
///
virtual void LoadDataForInput(const ContainerType &controlArray) = 0;
/// Allocates a large enough array in the execution environment and copies
/// the given data to that array. The allocated array can later be accessed
/// via the GetPortalExection method. If control and execution share arrays,
/// then this method may save the iterators of the container to be returned
/// in the \c GetPortal* methods.
///
virtual void LoadDataForInPlace(ContainerType &controlArray) = 0;
/// Allocates an array in the execution environment of the specified size.
/// If control and execution share arrays, then this class can allocate
/// data using the given ArrayContainerExecution and remember its iterators
/// so that it can be used directly in the execution environment.
///
virtual void AllocateArrayForOutput(ContainerType &controlArray,
vtkm::Id numberOfValues) = 0;
/// Allocates data in the given ArrayContainerControl and copies data held
/// in the execution environment (managed by this class) into the control
/// array. If control and execution share arrays, this can be no operation.
/// This method should only be called after AllocateArrayForOutput is
/// called.
///
virtual void RetrieveOutputData(ContainerType &controlArray) const = 0;
/// \brief Reduces the size of the array without changing its values.
///
/// This method allows you to resize the array without reallocating it. The
/// number of entries in the array is changed to \c numberOfValues. The data
/// in the array (from indices 0 to \c numberOfValues - 1) are the same, but
/// \c numberOfValues must be equal or less than the preexisting size
/// (returned from GetNumberOfValues). That is, this method can only be used
/// to shorten the array, not lengthen.
///
virtual void Shrink(vtkm::Id numberOfValues) = 0;
/// Returns an array portal that can be used in the execution environment.
/// This portal was defined in either LoadDataForInput or
/// AllocateArrayForOutput. If control and environment share memory space,
/// this class may return the iterator from the \c controlArray.
///
template<typename DeviceAdapter>
VTKM_CONT_EXPORT
typename ExecutionTypes<DeviceAdapter>::Portal
GetPortalExecution(DeviceAdapter device)
{
this->VerifyDeviceAdapter(device);
typename ExecutionTypes<DeviceAdapter>::Portal portal;
this->GetPortalExecutionImpl(&portal);
return portal;
}
/// Const version of GetPortal.
///
template<typename DeviceAdapter>
VTKM_CONT_EXPORT
typename ExecutionTypes<DeviceAdapter>::PortalConst
GetPortalConstExecution(DeviceAdapter device) const
{
this->VerifyDeviceAdapter(device);
typename ExecutionTypes<DeviceAdapter>::PortalConst portal;
this->GetPortalConstExecutionImpl(&portal);
return portal;
}
/// Frees any resources (i.e. memory) allocated for the exeuction
/// environment, if any.
///
virtual void ReleaseResources() = 0;
template<typename DeviceAdapter>
VTKM_CONT_EXPORT
bool IsDeviceAdapter(DeviceAdapter) const
{
return this->IsDeviceAdapterImpl(
vtkm::cont::internal::DeviceAdapterTraits<DeviceAdapter>::GetId());
}
protected:
virtual void GetPortalExecutionImpl(void *portalExecution) = 0;
virtual void GetPortalConstExecutionImpl(
void *portalConstExecution) const = 0;
virtual bool IsDeviceAdapterImpl(
const vtkm::cont::internal::DeviceAdapterId &id) const = 0;
private:
template<typename DeviceAdapter>
VTKM_CONT_EXPORT
void VerifyDeviceAdapter(DeviceAdapter device) const
{
if (!this->IsDeviceAdapter(device))
{
throw vtkm::cont::ErrorControlInternal("Device Adapter Mismatch");
}
}
};
/// \brief Used by ArrayHandle to manage execution arrays
///
/// This is an internal class used by ArrayHandle to manage execution arrays.
/// This class uses virtual method polymorphism to allocate and transfer data
/// in the execution environment. This virtual method polymorphism allows the
/// ArrayHandle to change its device at run time.
///
template<typename T,
typename Container,
typename DeviceAdapter>
class ArrayHandleExecutionManager
: public ArrayHandleExecutionManagerBase<T, Container>
{
typedef ArrayHandleExecutionManagerBase<T, Container> Superclass;
typedef vtkm::cont::internal::ArrayTransfer<T,Container,DeviceAdapter>
ArrayTransferType;
typedef vtkm::cont::internal::ArrayContainerControl<T,Container> ContainerType;
public:
typedef typename ArrayTransferType::PortalControl PortalControl;
typedef typename ArrayTransferType::PortalConstControl PortalConstControl;
VTKM_CONT_EXPORT
vtkm::Id GetNumberOfValues() const
{
return this->Transfer.GetNumberOfValues();
}
VTKM_CONT_EXPORT
void LoadDataForInput(PortalConstControl portal)
{
this->Transfer.LoadDataForInput(portal);
}
VTKM_CONT_EXPORT
void LoadDataForInput(const ContainerType &controlArray)
{
this->Transfer.LoadDataForInput(controlArray);
}
VTKM_CONT_EXPORT
void LoadDataForInPlace(ContainerType &controlArray)
{
this->Transfer.LoadDataForInPlace(controlArray);
}
VTKM_CONT_EXPORT
void AllocateArrayForOutput(ContainerType &controlArray, Id numberOfValues)
{
this->Transfer.AllocateArrayForOutput(controlArray, numberOfValues);
}
VTKM_CONT_EXPORT
void RetrieveOutputData(ContainerType &controlArray) const
{
this->Transfer.RetrieveOutputData(controlArray);
}
VTKM_CONT_EXPORT
void Shrink(Id numberOfValues)
{
this->Transfer.Shrink(numberOfValues);
}
VTKM_CONT_EXPORT
void ReleaseResources()
{
this->Transfer.ReleaseResources();
}
protected:
VTKM_CONT_EXPORT
void GetPortalExecutionImpl(void *portalExecutionVoid)
{
typedef typename ArrayTransferType::PortalExecution PortalType;
PortalType portalExecution = this->Transfer.GetPortalExecution();
*reinterpret_cast<PortalType *>(portalExecutionVoid) = portalExecution;
}
VTKM_CONT_EXPORT
void GetPortalConstExecutionImpl(void *portalExecutionVoid) const
{
typedef typename ArrayTransferType::PortalConstExecution PortalType;
PortalType portalExecution = this->Transfer.GetPortalConstExecution();
*reinterpret_cast<PortalType *>(portalExecutionVoid) = portalExecution;
}
VTKM_CONT_EXPORT
bool IsDeviceAdapterImpl(const DeviceAdapterId &id) const
{
return id == vtkm::cont::internal::DeviceAdapterTraits<DeviceAdapter>::GetId();
}
private:
ArrayTransferType Transfer;
};
}
}
} // namespace vtkm::cont::internal
#endif //vtkm_cont_exec_ArrayHandleExecutionManager_h

@ -0,0 +1,172 @@
//============================================================================
// 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_ArrayManagerExecution_h
#define vtkm_cont_internal_ArrayManagerExecution_h
#include <vtkm/cont/internal/DeviceAdapterTag.h>
namespace vtkm {
namespace cont {
namespace internal {
/// \brief Class that manages data in the execution environment.
///
/// This templated class must be partially specialized for each
/// DeviceAdapterTag crated, which will define the implementation for that tag.
///
/// This is a class that is responsible for allocating data in the execution
/// environment and copying data back and forth between control and
/// execution. It is also expected that this class will automatically release
/// any resources in its destructor.
///
/// This class typically takes on one of two forms. If the control and
/// execution environments have seperate memory spaces, then this class
/// behaves how you would expect. It allocates/deallocates arrays and copies
/// data. However, if the control and execution environments share the same
/// memory space, this class should delegate all its operations to the
/// ArrayContainerControl. The latter can probably be implemented with a
/// trivial subclass of
/// vtkm::cont::internal::ArrayManagerExecutionShareWithControl.
///
template<typename T, class ArrayContainerControlTag, class DeviceAdapterTag>
class ArrayManagerExecution
#ifdef VTKM_DOXYGEN_ONLY
{
private:
typedef vtkm::cont::internal::ArrayContainerControl<T,ArrayContainerControlTag>
ContainerType;
public:
/// The type of value held in the array (vtkm::Scalar, vtkm::Vector3, etc.)
///
typedef T ValueType;
/// An array portal that can be used in the execution environment to access
/// portions of the arrays. This example defines the portal with a pointer,
/// but any portal with methods that can be called and data that can be
/// accessed from the execution environment can be used.
///
typedef vtkm::exec::internal::ArrayPortalFromIterators<ValueType*> PortalType;
/// Const version of PortalType. You must be able to cast PortalType to
/// PortalConstType.
///
typedef vtkm::exec::internal::ArrayPortalFromIterators<const ValueType*>
PortalConstType;
/// Returns the number of values stored in the array. Results are undefined
/// if data has not been loaded or allocated.
///
VTKM_CONT_EXPORT vtkm::Id GetNumberOfValues() const;
/// Allocates a large enough array in the execution environment and copies
/// the given data to that array. The allocated array can later be accessed
/// via the GetPortalConst method. If control and execution share arrays,
/// then this method may save the iterators to be returned in the \c
/// GetPortalConst method.
///
VTKM_CONT_EXPORT void LoadDataForInput(
typename ContainerType::PortalConstType portal);
/// Allocates a large enough array in the execution environment and copies
/// the given data to that array. The allocated array can later be accessed
/// via the GetPortal method. If control and execution share arrays, then
/// this method may save the iterators of the container to be returned in the
/// \c GetPortal* methods.
///
VTKM_CONT_EXPORT void LoadDataForInPlace(PortalType portal);
/// Allocates an array in the execution environment of the specified size.
/// If control and execution share arrays, then this class can allocate
/// data using the given ArrayContainerExecution and remember its iterators
/// so that it can be used directly in the execution environment.
///
VTKM_CONT_EXPORT void AllocateArrayForOutput(ContainerType &controlArray,
vtkm::Id numberOfValues);
/// Allocates data in the given ArrayContainerControl and copies data held
/// in the execution environment (managed by this class) into the control
/// array. If control and execution share arrays, this can be no operation.
/// This method should only be called after AllocateArrayForOutput is
/// called.
///
VTKM_CONT_EXPORT void RetrieveOutputData(ContainerType &controlArray) const;
/// Similar to RetrieveOutputData except that instead of writing to the
/// controlArray itself, it writes to the given control environment
/// iterator. This allows the user to retrieve data without necessarily
/// allocating an array in the ArrayContainerControl (assuming that control
/// and exeuction have seperate memory spaces).
///
template <class IteratorTypeControl>
VTKM_CONT_EXPORT void CopyInto(IteratorTypeControl dest) const;
/// \brief Reduces the size of the array without changing its values.
///
/// This method allows you to resize the array without reallocating it. The
/// number of entries in the array is changed to \c numberOfValues. The data
/// in the array (from indices 0 to \c numberOfValues - 1) are the same, but
/// \c numberOfValues must be equal or less than the preexisting size
/// (returned from GetNumberOfValues). That is, this method can only be used
/// to shorten the array, not lengthen.
///
VTKM_CONT_EXPORT void Shrink(vtkm::Id numberOfValues);
/// Returns an array portal that can be used in the execution environment.
/// This portal was defined in either LoadDataForInput or
/// AllocateArrayForOutput. If control and environment share memory space,
/// this class may return the iterator from the \c controlArray.
///
VTKM_CONT_EXPORT PortalType GetPortal();
/// Const version of GetPortal.
///
VTKM_CONT_EXPORT PortalConstType GetPortalConst() const;
/// Frees any resources (i.e. memory) allocated for the exeuction
/// environment, if any.
///
VTKM_CONT_EXPORT void ReleaseResources();
};
#else // VTKM_DOXGEN_ONLY
;
#endif // VTKM_DOXYGEN_ONLY
}
}
} // namespace vtkm::cont::internal
//-----------------------------------------------------------------------------
// These includes are intentionally placed here after the declaration of the
// ArrayManagerExecution template prototype, which all the implementations
// need.
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_SERIAL
#include <vtkm/cont/internal/ArrayManagerExecutionSerial.h>
// #elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_CUDA
// #include <vtkm/cuda/cont/internal/ArrayManagerExecutionCuda.h>
// #elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_OPENMP
// #include <vtkm/openmp/cont/internal/ArrayManagerExecutionOpenMP.h>
// #elif VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_TBB
// #include <vtkm/tbb/cont/internal/ArrayManagerExecutionTBB.h>
#endif
#endif //vtkm_cont_internal_ArrayManagerExecution_h

@ -0,0 +1,49 @@
//============================================================================
// 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_ArrayManagerExecutionSerial_h
#define vtkm_cont_internal_ArrayManagerExecutionSerial_h
#include <vtkm/cont/internal/ArrayManagerExecution.h>
#include <vtkm/cont/internal/ArrayManagerExecutionShareWithControl.h>
#include <vtkm/cont/internal/DeviceAdapterTagSerial.h>
namespace vtkm {
namespace cont {
namespace internal {
template <typename T, class ArrayContainerControlTag>
class ArrayManagerExecution
<T, ArrayContainerControlTag, vtkm::cont::DeviceAdapterTagSerial>
: public vtkm::cont::internal::ArrayManagerExecutionShareWithControl
<T, ArrayContainerControlTag>
{
public:
typedef vtkm::cont::internal::ArrayManagerExecutionShareWithControl
<T, ArrayContainerControlTag> Superclass;
typedef typename Superclass::ValueType ValueType;
typedef typename Superclass::PortalType PortalType;
typedef typename Superclass::PortalConstType PortalConstType;
};
}
}
} // namespace vtkm::cont::internal
#endif //vtkm_cont_internal_ArrayManagerExecutionSerial_h

@ -0,0 +1,176 @@
//============================================================================
// 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_ArrayManagerExecutionShareWithControl_h
#define vtkm_cont_internal_ArrayManagerExecutionShareWithControl_h
#include <vtkm/Types.h>
#include <vtkm/cont/Assert.h>
#include <vtkm/cont/ArrayContainerControl.h>
#include <vtkm/cont/internal/ArrayPortalShrink.h>
#include <algorithm>
namespace vtkm {
namespace cont {
namespace internal {
/// \c ArrayManagerExecutionShareWithControl provides an implementation for a
/// \c ArrayManagerExecution class for a device adapter when the execution
/// and control environments share memory. This class basically defers all its
/// calls to an \c ArrayContainerControl class and uses the array allocated
/// there.
///
template<typename T, class ArrayContainerControlTag>
class ArrayManagerExecutionShareWithControl
{
public:
typedef T ValueType;
typedef vtkm::cont::internal
::ArrayContainerControl<ValueType, ArrayContainerControlTag>
ContainerType;
typedef vtkm::cont::internal::ArrayPortalShrink<
typename ContainerType::PortalType> PortalType;
typedef vtkm::cont::internal::ArrayPortalShrink<
typename ContainerType::PortalConstType> PortalConstType;
VTKM_CONT_EXPORT ArrayManagerExecutionShareWithControl()
: PortalValid(false), ConstPortalValid(false) { }
/// Returns the size of the saved portal.
///
VTKM_CONT_EXPORT vtkm::Id GetNumberOfValues() const {
VTKM_ASSERT_CONT(this->ConstPortalValid);
return this->ConstPortal.GetNumberOfValues();
}
/// Saves the given iterators to be returned later.
///
VTKM_CONT_EXPORT void LoadDataForInput(PortalConstType portal)
{
this->ConstPortal = portal;
this->ConstPortalValid = true;
// Non-const versions not defined.
this->PortalValid = false;
}
/// Saves the given iterators to be returned later.
///
VTKM_CONT_EXPORT void LoadDataForInPlace(PortalType portal)
{
// This only works if there is a valid cast from non-const to const
// iterator.
this->LoadDataForInput(portal);
this->Portal = portal;
this->PortalValid = true;
}
/// Actually just allocates memory in the given \p controlArray.
///
VTKM_CONT_EXPORT void AllocateArrayForOutput(ContainerType &controlArray,
vtkm::Id numberOfValues)
{
controlArray.Allocate(numberOfValues);
this->Portal = controlArray.GetPortal();
this->PortalValid = true;
this->ConstPortal = controlArray.GetPortalConst();
this->ConstPortalValid = true;
}
/// This method is a no-op (except for a few checks). Any data written to
/// this class's iterators should already be written to the given \c
/// controlArray (under correct operation).
///
VTKM_CONT_EXPORT void RetrieveOutputData(ContainerType &controlArray) const
{
VTKM_ASSERT_CONT(this->ConstPortalValid);
VTKM_ASSERT_CONT(controlArray.GetPortalConst().GetIteratorBegin() ==
this->ConstPortal.GetIteratorBegin());
controlArray.Shrink(this->ConstPortal.GetNumberOfValues());
}
/// This methods copies data from the execution array into the given
/// iterator.
///
template <class IteratorTypeControl>
VTKM_CONT_EXPORT void CopyInto(IteratorTypeControl dest) const
{
VTKM_ASSERT_CONT(this->ConstPortalValid);
std::copy(this->ConstPortal.GetIteratorBegin(),
this->ConstPortal.GetIteratorEnd(),
dest);
}
/// Adjusts saved end iterators to resize array.
///
VTKM_CONT_EXPORT void Shrink(vtkm::Id numberOfValues)
{
VTKM_ASSERT_CONT(this->ConstPortalValid);
this->ConstPortal.Shrink(numberOfValues);
if (this->PortalValid)
{
this->Portal.Shrink(numberOfValues);
}
}
/// Returns the portal previously saved from an \c ArrayContainerControl.
///
VTKM_CONT_EXPORT PortalType GetPortal()
{
VTKM_ASSERT_CONT(this->PortalValid);
return this->Portal;
}
/// Const version of GetPortal.
///
VTKM_CONT_EXPORT PortalConstType GetPortalConst() const
{
VTKM_ASSERT_CONT(this->ConstPortalValid);
return this->ConstPortal;
}
/// A no-op.
///
VTKM_CONT_EXPORT void ReleaseResources() { }
private:
// Not implemented.
ArrayManagerExecutionShareWithControl(
ArrayManagerExecutionShareWithControl<T, ArrayContainerControlTag> &);
void operator=(
ArrayManagerExecutionShareWithControl<T, ArrayContainerControlTag> &);
PortalType Portal;
bool PortalValid;
PortalConstType ConstPortal;
bool ConstPortalValid;
};
}
}
} // namespace vtkm::cont::internal
#endif //vtkm_cont_internal_ArrayManagerExecutionShareWithControl_h

@ -0,0 +1,101 @@
//============================================================================
// 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_ArrayPortalFromIterators_h
#define vtkm_cont_internal_ArrayPortalFromIterators_h
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayPortal.h>
#include <vtkm/cont/Assert.h>
#include <iterator>
namespace vtkm {
namespace cont {
namespace internal {
/// This templated implementation of an ArrayPortal allows you to adapt a pair
/// of begin/end iterators to an ArrayPortal interface.
///
template<class IteratorT>
class ArrayPortalFromIterators
{
public:
typedef IteratorT IteratorType;
typedef typename std::iterator_traits<IteratorType>::value_type ValueType;
VTKM_CONT_EXPORT ArrayPortalFromIterators() { }
VTKM_CONT_EXPORT
ArrayPortalFromIterators(IteratorType begin, IteratorType end)
: BeginIterator(begin), EndIterator(end)
{
VTKM_ASSERT_CONT(this->GetNumberOfValues() >= 0);
}
/// Copy constructor for any other ArrayPortalFromIterators with an iterator
/// type that can be copied to this iterator type. This allows us to do any
/// type casting that the iterators do (like the non-const to const cast).
///
template<class OtherIteratorT>
VTKM_CONT_EXPORT
ArrayPortalFromIterators(const ArrayPortalFromIterators<OtherIteratorT> &src)
: BeginIterator(src.GetIteratorBegin()),
EndIterator(src.GetIteratorEnd())
{ }
VTKM_CONT_EXPORT
vtkm::Id GetNumberOfValues() const {
return std::distance(this->BeginIterator, this->EndIterator);
}
VTKM_CONT_EXPORT
ValueType Get(vtkm::Id index) const {
return *this->IteratorAt(index);
}
VTKM_CONT_EXPORT
void Set(vtkm::Id index, ValueType value) const {
*this->IteratorAt(index) = value;
}
VTKM_CONT_EXPORT
IteratorType GetIteratorBegin() const { return this->BeginIterator; }
VTKM_CONT_EXPORT
IteratorType GetIteratorEnd() const { return this->EndIterator; }
private:
IteratorType BeginIterator;
IteratorType EndIterator;
VTKM_CONT_EXPORT
IteratorType IteratorAt(vtkm::Id index) const {
VTKM_ASSERT_CONT(index >= 0);
VTKM_ASSERT_CONT(index < this->GetNumberOfValues());
return this->BeginIterator + index;
}
};
}
}
} // namespace vtkm::cont::internal
#endif //vtkm_cont_internal_ArrayPortalFromIterators_h

@ -0,0 +1,121 @@
//============================================================================
// 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_ArrayPortalShrink_h
#define vtkm_cont_internal_ArrayPortalShrink_h
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayPortal.h>
#include <vtkm/cont/Assert.h>
namespace vtkm {
namespace cont {
namespace internal {
/// This ArrayPortal adapter is a utility that allows you to shrink the
/// (reported) array size without actually modifying the underlying allocation.
///
template<class PortalT>
class ArrayPortalShrink
{
public:
typedef PortalT DelegatePortalType;
typedef typename DelegatePortalType::ValueType ValueType;
typedef typename DelegatePortalType::IteratorType IteratorType;
VTKM_CONT_EXPORT ArrayPortalShrink() : NumberOfValues(0) { }
VTKM_CONT_EXPORT ArrayPortalShrink(const DelegatePortalType &delegatePortal)
: DelegatePortal(delegatePortal),
NumberOfValues(delegatePortal.GetNumberOfValues())
{ }
VTKM_CONT_EXPORT ArrayPortalShrink(const DelegatePortalType &delegatePortal,
vtkm::Id numberOfValues)
: DelegatePortal(delegatePortal), NumberOfValues(numberOfValues)
{
VTKM_ASSERT_CONT(numberOfValues <= delegatePortal.GetNumberOfValues());
}
/// Copy constructor for any other ArrayPortalShrink with a delegate type
/// that can be copied to this type. This allows us to do any type casting
/// the delegates can do (like the non-const to const cast).
///
template<class OtherDelegateType>
VTKM_CONT_EXPORT
ArrayPortalShrink(const ArrayPortalShrink<OtherDelegateType> &src)
: DelegatePortal(src.GetDelegatePortal()),
NumberOfValues(src.GetNumberOfValues())
{ }
VTKM_CONT_EXPORT
vtkm::Id GetNumberOfValues() const { return this->NumberOfValues; }
VTKM_CONT_EXPORT
ValueType Get(vtkm::Id index) const {
VTKM_ASSERT_CONT(index >= 0);
VTKM_ASSERT_CONT(index < this->GetNumberOfValues());
return this->DelegatePortal.Get(index);
}
VTKM_CONT_EXPORT
void Set(vtkm::Id index, ValueType value) const {
VTKM_ASSERT_CONT(index >= 0);
VTKM_ASSERT_CONT(index < this->GetNumberOfValues());
this->DelegatePortal.Set(index, value);
}
VTKM_CONT_EXPORT
IteratorType GetIteratorBegin() const {
return this->DelegatePortal.GetIteratorBegin();
}
VTKM_CONT_EXPORT
IteratorType GetIteratorEnd() const {
IteratorType iterator = this->DelegatePortal.GetIteratorBegin();
std::advance(iterator, this->GetNumberOfValues());
return iterator;
}
/// Special method in this ArrayPortal that allows you to shrink the
/// (exposed) array.
///
VTKM_CONT_EXPORT
void Shrink(vtkm::Id numberOfValues) {
VTKM_ASSERT_CONT(numberOfValues < this->GetNumberOfValues());
this->NumberOfValues = numberOfValues;
}
/// Get a copy of the delegate portal. Although safe, this is probably only
/// useful internally. (It is exposed as public for the templated copy
/// constructor.)
///
DelegatePortalType GetDelegatePortal() const { return this->DelegatePortal; }
private:
DelegatePortalType DelegatePortal;
vtkm::Id NumberOfValues;
};
}
}
} // namespace vtkm::cont::internal
#endif //vtkm_cont_internal_ArrayPortalShrink_h

@ -0,0 +1,193 @@
//============================================================================
// 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_ArrayTransfer_h
#define vtkm_cont_internal_ArrayTransfer_h
#include <vtkm/cont/ArrayContainerControl.h>
#include <vtkm/cont/internal/ArrayManagerExecution.h>
namespace vtkm {
namespace cont {
namespace internal {
/// \brief Class that manages the transfer of data between control and execution.
///
/// This templated class provides a mechanism (used by the ArrayHandle) to
/// transfer data from the control environment to the execution environment and
/// back. The interface for ArrayTransfer is nearly identical to that of
/// ArrayManagerExecution and the default implementation simply delegates all
/// calls to that class.
///
/// The primary motivation for having a separate class is that the
/// ArrayManagerExecution is meant to be specialized for each device adapter
/// whee as the ArrayTransfer is meant to be specialized for each array
/// container (or specific combination of container and device adapter). Thus,
/// transfers for most containers will be delegated through the
/// ArrayManagerExecution, but some containers, like implicit containers, will
/// be specialized to transfer through a different path.
///
template<typename T, class ArrayContainerControlTag, class DeviceAdapterTag>
class ArrayTransfer
{
private:
typedef vtkm::cont::internal::ArrayContainerControl<T,ArrayContainerControlTag>
ContainerType;
typedef vtkm::cont::internal::ArrayManagerExecution<
T,ArrayContainerControlTag,DeviceAdapterTag> ArrayManagerType;
public:
/// The type of value held in the array (vtkm::Scalar, vtkm::Vector3, etc.)
///
typedef T ValueType;
/// An array portal that can be used in the control environment.
///
typedef typename ContainerType::PortalType PortalControl;
typedef typename ContainerType::PortalConstType PortalConstControl;
/// An array portal that can be used in the execution environment.
///
typedef typename ArrayManagerType::PortalType PortalExecution;
typedef typename ArrayManagerType::PortalConstType PortalConstExecution;
/// Returns the number of values stored in the array. Results are undefined
/// if data has not been loaded or allocated.
///
VTKM_CONT_EXPORT vtkm::Id GetNumberOfValues() const
{
return this->ArrayManager.GetNumberOfValues();
}
/// Allocates a large enough array in the execution environment and copies
/// the given data to that array. The allocated array can later be accessed
/// via the GetPortalConstExecution method. If control and execution share
/// arrays, then this method may save the iterators to be returned in the \c
/// GetPortalConst methods.
///
VTKM_CONT_EXPORT void LoadDataForInput(PortalConstControl portal)
{
this->ArrayManager.LoadDataForInput(portal);
}
/// Allocates a large enough array in the execution environment and copies
/// the given data to that array. The allocated array can later be accessed
/// via the GetPortalConstExecution method. If control and execution share
/// arrays, then this method may save the iterators to be returned in the \c
/// GetPortalConst methods.
///
VTKM_CONT_EXPORT void LoadDataForInput(const ContainerType &controlArray)
{
this->ArrayManager.LoadDataForInput(controlArray.GetPortalConst());
}
/// Allocates a large enough array in the execution environment and copies
/// the given data to that array. The allocated array can later be accessed
/// via the GetPortalExection method. If control and execution share arrays,
/// then this method may save the iterators of the container to be returned
/// in the \c GetPortal* methods.
///
VTKM_CONT_EXPORT void LoadDataForInPlace(ContainerType &controlArray)
{
this->ArrayManager.LoadDataForInPlace(controlArray.GetPortal());
}
/// Allocates an array in the execution environment of the specified size.
/// If control and execution share arrays, then this class can allocate
/// data using the given ArrayContainerExecution and remember its iterators
/// so that it can be used directly in the execution environment.
///
VTKM_CONT_EXPORT void AllocateArrayForOutput(ContainerType &controlArray,
vtkm::Id numberOfValues)
{
this->ArrayManager.AllocateArrayForOutput(controlArray, numberOfValues);
}
/// Allocates data in the given ArrayContainerControl and copies data held
/// in the execution environment (managed by this class) into the control
/// array. If control and execution share arrays, this can be no operation.
/// This method should only be called after AllocateArrayForOutput is
/// called.
///
VTKM_CONT_EXPORT void RetrieveOutputData(ContainerType &controlArray) const
{
this->ArrayManager.RetrieveOutputData(controlArray);
}
/// Similar to RetrieveOutputData except that instead of writing to the
/// controlArray itself, it writes to the given control environment
/// iterator. This allows the user to retrieve data without necessarily
/// allocating an array in the ArrayContainerControl (assuming that control
/// and exeuction have seperate memory spaces).
///
template <class IteratorTypeControl>
VTKM_CONT_EXPORT void CopyInto(IteratorTypeControl dest) const
{
this->ArrayManager.CopyInto(dest);
}
/// \brief Reduces the size of the array without changing its values.
///
/// This method allows you to resize the array without reallocating it. The
/// number of entries in the array is changed to \c numberOfValues. The data
/// in the array (from indices 0 to \c numberOfValues - 1) are the same, but
/// \c numberOfValues must be equal or less than the preexisting size
/// (returned from GetNumberOfValues). That is, this method can only be used
/// to shorten the array, not lengthen.
///
VTKM_CONT_EXPORT void Shrink(vtkm::Id numberOfValues)
{
this->ArrayManager.Shrink(numberOfValues);
}
/// Returns an array portal that can be used in the execution environment.
/// This portal was defined in either LoadDataForInput or
/// AllocateArrayForOutput. If control and environment share memory space,
/// this class may return the iterator from the \c controlArray.
///
VTKM_CONT_EXPORT PortalExecution GetPortalExecution()
{
return this->ArrayManager.GetPortal();
}
/// Const version of GetPortal.
///
VTKM_CONT_EXPORT PortalConstExecution GetPortalConstExecution() const
{
return this->ArrayManager.GetPortalConst();
}
/// Frees any resources (i.e. memory) allocated for the exeuction
/// environment, if any.
///
VTKM_CONT_EXPORT void ReleaseResources()
{
this->ArrayManager.ReleaseResources();
}
private:
ArrayManagerType ArrayManager;
};
}
}
} // namespace vtkm::cont::internal
#endif //vtkm_cont_internal_ArrayTransfer_h

@ -0,0 +1,38 @@
##============================================================================
## 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.
##============================================================================
set(headers
ArrayHandleExecutionManager.h
ArrayManagerExecution.h
ArrayManagerExecutionSerial.h
ArrayManagerExecutionShareWithControl.h
ArrayPortalFromIterators.h
ArrayPortalShrink.h
ArrayTransfer.h
)
vtkm_declare_headers(${headers})
# These source files are actually compiled in the parent directory.
# They are in a separate directory to highlight which objects are
# internal and which are part of the external interface.
#add_custom_target(vtkmContInternal ALL DEPENDS vtkmCont)
add_subdirectory(testing)

@ -0,0 +1,107 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// 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_DeviceAdapterTag_h
#define vtkm_cont_internal_DeviceAdapterTag_h
#include <vtkm/internal/Configure.h>
#include <vtkm/internal/ExportMacros.h>
#include <string>
#include <boost/static_assert.hpp>
#define VTKM_DEVICE_ADAPTER_ERROR -1
#define VTKM_DEVICE_ADAPTER_UNDEFINED 0
#define VTKM_DEVICE_ADAPTER_SERIAL 1
#ifndef VTKM_DEVICE_ADAPTER
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_SERIAL
#endif // VTKM_DEVICE_ADAPTER
namespace vtkm {
namespace cont {
namespace internal {
typedef std::string DeviceAdapterId;
template<typename DeviceAdapter>
struct DeviceAdapterTraits;
template<typename DeviceAdapter>
struct DeviceAdapterTagCheck
{
static const bool Valid = false;
};
}
}
}
/// Creates a tag named vtkm::cont::DeviceAdapterTagName and associated MPL
/// structures to use this tag. Always use this macro (in the base namespace)
/// when creating a device adapter.
#define VTKM_CREATE_DEVICE_ADAPTER(Name) \
namespace vtkm { \
namespace cont { \
struct DeviceAdapterTag##Name { }; \
namespace internal { \
template<> \
struct DeviceAdapterTraits<vtkm::cont::DeviceAdapterTag##Name> { \
static DeviceAdapterId GetId() { \
return DeviceAdapterId(#Name); \
} \
}; \
template<> \
struct DeviceAdapterTagCheck<vtkm::cont::DeviceAdapterTag##Name> { \
static const bool Valid = true; \
}; \
} \
} \
}
/// Checks that the argument is a proper device adapter tag. This is a handy
/// concept check for functions and classes to make sure that a template
/// argument is actually a device adapter tag. (You can get weird errors
/// elsewhere in the code when a mistake is made.)
#define VTKM_IS_DEVICE_ADAPTER_TAG(tag) \
BOOST_STATIC_ASSERT_MSG( \
::vtkm::cont::internal::DeviceAdapterTagCheck<tag>::Valid, \
"Provided type is not a valid VTKm device adapter tag.")
//-----------------------------------------------------------------------------
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_SERIAL
#include <vtkm/cont/internal/DeviceAdapterTagSerial.h>
#define VTKM_DEFAULT_DEVICE_ADAPTER_TAG ::vtkm::cont::DeviceAdapterTagSerial
#elif (VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_UNDEFINED) || !defined(VTKM_DEVICE_ADAPTER)
#ifndef VTKM_DEFAULT_DEVICE_ADAPTER_TAG
#warning If device adapter is undefined, VTKM_DEFAULT_DEVICE_ADAPTER_TAG must be defined.
#endif
#else
#warning Unrecognized device adapter given.
#endif
#endif //vtkm_cont_internal_DeviceAdapterTag_h

@ -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_internal_DeviceAdapterTagSerial_h
#define vtkm_cont_internal_DeviceAdapterTagSerial_h
#include <vtkm/cont/internal/DeviceAdapterTag.h>
VTKM_CREATE_DEVICE_ADAPTER(Serial);
#endif //vtkm_cont_internal_DeviceAdapterTagSerial_h

@ -0,0 +1,187 @@
//============================================================================
// 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_IteratorFromArrayPortal_h
#define vtkm_cont_internal_IteratorFromArrayPortal_h
#include <vtkm/cont/ArrayPortal.h>
#include <vtkm/cont/Assert.h>
#include <boost/iterator/iterator_facade.hpp>
namespace vtkm {
namespace cont {
namespace internal {
namespace detail {
template<class ArrayPortalType>
struct IteratorFromArrayPortalValue {
typedef typename ArrayPortalType::ValueType ValueType;
VTKM_CONT_EXPORT
IteratorFromArrayPortalValue(const ArrayPortalType &portal, vtkm::Id index)
: Portal(portal), Index(index) { }
VTKM_CONT_EXPORT
void Swap( IteratorFromArrayPortalValue<ArrayPortalType> &rhs ) throw()
{
//we need use the explicit type not a proxy temp object
//A proxy temp object would point to the same underlying data structure
//and would not hold the old value of *this once *this was set to rhs.
const ValueType aValue = *this;
*this = rhs;
rhs = aValue;
}
VTKM_CONT_EXPORT
IteratorFromArrayPortalValue<ArrayPortalType> &operator=(
const IteratorFromArrayPortalValue<ArrayPortalType> &rhs)
{
this->Portal.Set(this->Index, rhs.Portal.Get(rhs.Index));
return *this;
}
VTKM_CONT_EXPORT
ValueType operator=(ValueType value) {
this->Portal.Set(this->Index, value);
return value;
}
VTKM_CONT_EXPORT
operator ValueType(void) const {
return this->Portal.Get(this->Index);
}
const ArrayPortalType& Portal;
vtkm::Id Index;
};
} // namespace detail
template<class ArrayPortalType>
class IteratorFromArrayPortal : public
boost::iterator_facade<
IteratorFromArrayPortal<ArrayPortalType>,
typename ArrayPortalType::ValueType,
boost::random_access_traversal_tag,
detail::IteratorFromArrayPortalValue<ArrayPortalType>,
vtkm::Id>
{
public:
IteratorFromArrayPortal()
: Portal(), Index(0) { }
explicit IteratorFromArrayPortal(const ArrayPortalType &portal,
vtkm::Id index = 0)
: Portal(portal), Index(index) { }
VTKM_CONT_EXPORT
detail::IteratorFromArrayPortalValue<ArrayPortalType>
operator[](int idx) const
{
return detail::IteratorFromArrayPortalValue<ArrayPortalType>(this->Portal,
idx);
}
private:
ArrayPortalType Portal;
vtkm::Id Index;
// Implementation for boost iterator_facade
friend class boost::iterator_core_access;
VTKM_CONT_EXPORT
detail::IteratorFromArrayPortalValue<ArrayPortalType> dereference() const {
return detail::IteratorFromArrayPortalValue<ArrayPortalType>(this->Portal,
this->Index);
}
VTKM_CONT_EXPORT
bool equal(const IteratorFromArrayPortal<ArrayPortalType> &other) const {
// Technically, we should probably check that the portals are the same,
// but the portal interface does not specify an equal operator. It is
// by its nature undefined what happens when comparing iterators from
// different portals anyway.
return (this->Index == other.Index);
}
VTKM_CONT_EXPORT
void increment() {
this->Index++;
VTKM_ASSERT_CONT(this->Index >= 0);
VTKM_ASSERT_CONT(this->Index <= this->Portal.GetNumberOfValues());
}
VTKM_CONT_EXPORT
void decrement() {
this->Index--;
VTKM_ASSERT_CONT(this->Index >= 0);
VTKM_ASSERT_CONT(this->Index <= this->Portal.GetNumberOfValues());
}
VTKM_CONT_EXPORT
void advance(vtkm::Id delta) {
this->Index += delta;
VTKM_ASSERT_CONT(this->Index >= 0);
VTKM_ASSERT_CONT(this->Index <= this->Portal.GetNumberOfValues());
}
VTKM_CONT_EXPORT
vtkm::Id
distance_to(const IteratorFromArrayPortal<ArrayPortalType> &other) const {
// Technically, we should probably check that the portals are the same,
// but the portal interface does not specify an equal operator. It is
// by its nature undefined what happens when comparing iterators from
// different portals anyway.
return other.Index - this->Index;
}
};
template<class ArrayPortalType>
IteratorFromArrayPortal<ArrayPortalType> make_IteratorBegin(
const ArrayPortalType &portal)
{
return IteratorFromArrayPortal<ArrayPortalType>(portal, 0);
}
template<class ArrayPortalType>
IteratorFromArrayPortal<ArrayPortalType> make_IteratorEnd(
const ArrayPortalType &portal)
{
return IteratorFromArrayPortal<ArrayPortalType>(portal,
portal.GetNumberOfValues());
}
//implementat a custom swap function, since the std::swap won't work
//since we return RValues instead of Lvalues
template<typename T>
void swap( vtkm::cont::internal::detail::IteratorFromArrayPortalValue<T> a,
vtkm::cont::internal::detail::IteratorFromArrayPortalValue<T> b)
{
a.Swap(b);
}
}
}
} // namespace vtkm::cont::internal
#endif //vtkm_cont_internal_IteratorFromArrayPortal_h

@ -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.
##============================================================================
set(unit_tests
UnitTestArrayManagerExecutionShareWithControl.cxx
UnitTestArrayPortalFromIterators.cxx
# UnitTestIteratorFromArrayPortal.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests})

@ -0,0 +1,177 @@
//============================================================================
// 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/cont/internal/ArrayManagerExecutionShareWithControl.h>
#include <vtkm/cont/ArrayContainerControlBasic.h>
#include <vtkm/cont/testing/Testing.h>
#include <algorithm>
#include <vector>
namespace {
const vtkm::Id ARRAY_SIZE = 10;
template <typename T>
struct TemplatedTests
{
typedef vtkm::cont::internal::ArrayManagerExecutionShareWithControl
<T, vtkm::cont::ArrayContainerControlTagBasic>
ArrayManagerType;
typedef typename ArrayManagerType::ValueType ValueType;
typedef vtkm::cont::internal::ArrayContainerControl<
T, vtkm::cont::ArrayContainerControlTagBasic> ArrayContainerType;
void SetContainer(ArrayContainerType &array, ValueType value)
{
std::fill(array.GetPortal().GetIteratorBegin(),
array.GetPortal().GetIteratorEnd(),
value);
}
template <class IteratorType>
bool CheckArray(IteratorType begin, IteratorType end, ValueType value)
{
for (IteratorType iter = begin; iter != end; iter++)
{
if (!test_equal(*iter, value)) return false;
}
return true;
}
bool CheckContainer(ArrayContainerType &array, ValueType value)
{
return CheckArray(array.GetPortalConst().GetIteratorBegin(),
array.GetPortalConst().GetIteratorEnd(),
value);
}
void InputData()
{
const ValueType INPUT_VALUE(4145);
ArrayContainerType controlArray;
controlArray.Allocate(ARRAY_SIZE);
SetContainer(controlArray, INPUT_VALUE);
ArrayManagerType executionArray;
executionArray.LoadDataForInput(controlArray.GetPortalConst());
// Although the ArrayManagerExecutionShareWithControl class wraps the
// control array portal in a different array portal, it should still
// give the same iterator (to avoid any unnecessary indirection).
VTKM_TEST_ASSERT(
controlArray.GetPortalConst().GetIteratorBegin() ==
executionArray.GetPortalConst().GetIteratorBegin(),
"Execution array manager not holding control array iterators.");
std::vector<ValueType> copyBack(ARRAY_SIZE);
executionArray.CopyInto(copyBack.begin());
VTKM_TEST_ASSERT(CheckArray(copyBack.begin(), copyBack.end(), INPUT_VALUE),
"Did not get correct array back.");
}
void InPlaceData()
{
const ValueType INPUT_VALUE(2350);
ArrayContainerType controlArray;
controlArray.Allocate(ARRAY_SIZE);
SetContainer(controlArray, INPUT_VALUE);
ArrayManagerType executionArray;
executionArray.LoadDataForInPlace(controlArray.GetPortal());
// Although the ArrayManagerExecutionShareWithControl class wraps the
// control array portal in a different array portal, it should still
// give the same iterator (to avoid any unnecessary indirection).
VTKM_TEST_ASSERT(
controlArray.GetPortal().GetIteratorBegin() ==
executionArray.GetPortal().GetIteratorBegin(),
"Execution array manager not holding control array iterators.");
VTKM_TEST_ASSERT(
controlArray.GetPortalConst().GetIteratorBegin() ==
executionArray.GetPortalConst().GetIteratorBegin(),
"Execution array manager not holding control array iterators.");
std::vector<ValueType> copyBack(ARRAY_SIZE);
executionArray.CopyInto(copyBack.begin());
VTKM_TEST_ASSERT(CheckArray(copyBack.begin(), copyBack.end(), INPUT_VALUE),
"Did not get correct array back.");
}
void OutputData()
{
const ValueType OUTPUT_VALUE(6712);
ArrayContainerType controlArray;
ArrayManagerType executionArray;
executionArray.AllocateArrayForOutput(controlArray, ARRAY_SIZE);
std::fill(executionArray.GetPortal().GetIteratorBegin(),
executionArray.GetPortal().GetIteratorEnd(),
OUTPUT_VALUE);
std::vector<ValueType> copyBack(ARRAY_SIZE);
executionArray.CopyInto(copyBack.begin());
VTKM_TEST_ASSERT(CheckArray(copyBack.begin(), copyBack.end(), OUTPUT_VALUE),
"Did not get correct array back.");
executionArray.RetrieveOutputData(controlArray);
VTKM_TEST_ASSERT(CheckContainer(controlArray, OUTPUT_VALUE),
"Did not get the right value in the control container.");
}
void operator()() {
InputData();
InPlaceData();
OutputData();
}
};
struct TestFunctor
{
template <typename T>
void operator()(T)
{
TemplatedTests<T> tests;
tests();
}
};
void TestArrayManagerShare()
{
vtkm::testing::Testing::TryAllTypes(TestFunctor());
}
} // Anonymous namespace
int UnitTestArrayManagerExecutionShareWithControl(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestArrayManagerShare);
}

@ -0,0 +1,135 @@
//============================================================================
// 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/cont/internal/ArrayPortalFromIterators.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/VectorTraits.h>
namespace {
template<typename T>
struct TemplatedTests
{
static const vtkm::Id ARRAY_SIZE = 10;
typedef T ValueType;
typedef typename vtkm::VectorTraits<ValueType>::ComponentType ComponentType;
ValueType ExpectedValue(vtkm::Id index, ComponentType value) {
return ValueType(index + value);
}
template<class IteratorType>
void FillIterator(IteratorType begin, IteratorType end, ComponentType value) {
vtkm::Id index = 0;
for (IteratorType iter = begin; iter != end; iter++)
{
*iter = ExpectedValue(index, value);
index++;
}
}
template<class IteratorType>
bool CheckIterator(IteratorType begin,
IteratorType end,
ComponentType value) {
vtkm::Id index = 0;
for (IteratorType iter = begin; iter != end; iter++)
{
if (*iter != ExpectedValue(index, value)) return false;
index++;
}
return true;
}
void operator()()
{
ValueType array[ARRAY_SIZE];
static const ComponentType ORIGINAL_VALUE = 239;
FillIterator(array, array+ARRAY_SIZE, ORIGINAL_VALUE);
::vtkm::cont::internal::ArrayPortalFromIterators<ValueType *>
portal(array, array+ARRAY_SIZE);
::vtkm::cont::internal::ArrayPortalFromIterators<const ValueType *>
const_portal(array, array+ARRAY_SIZE);
VTKM_TEST_ASSERT(portal.GetNumberOfValues() == ARRAY_SIZE,
"Portal array size wrong.");
VTKM_TEST_ASSERT(const_portal.GetNumberOfValues() == ARRAY_SIZE,
"Const portal array size wrong.");
std::cout << " Check inital value." << std::endl;
VTKM_TEST_ASSERT(CheckIterator(portal.GetIteratorBegin(),
portal.GetIteratorEnd(),
ORIGINAL_VALUE),
"Portal iterator has bad value.");
VTKM_TEST_ASSERT(CheckIterator(const_portal.GetIteratorBegin(),
const_portal.GetIteratorEnd(),
ORIGINAL_VALUE),
"Const portal iterator has bad value.");
static const ComponentType SET_VALUE = 562;
std::cout << " Check get/set methods." << std::endl;
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
{
VTKM_TEST_ASSERT(portal.Get(index)
== ExpectedValue(index, ORIGINAL_VALUE),
"Bad portal value.");
VTKM_TEST_ASSERT(const_portal.Get(index)
== ExpectedValue(index, ORIGINAL_VALUE),
"Bad const portal value.");
portal.Set(index, ExpectedValue(index, SET_VALUE));
}
std::cout << " Make sure set has correct value." << std::endl;
VTKM_TEST_ASSERT(CheckIterator(portal.GetIteratorBegin(),
portal.GetIteratorEnd(),
SET_VALUE),
"Portal iterator has bad value.");
VTKM_TEST_ASSERT(CheckIterator(array, array+ARRAY_SIZE, SET_VALUE),
"Array has bad value.");
}
};
struct TestFunctor
{
template<typename T>
void operator()(T)
{
TemplatedTests<T> tests;
tests();
}
};
void TestArrayPortalFromIterators()
{
vtkm::testing::Testing::TryAllTypes(TestFunctor());
}
} // Anonymous namespace
int UnitTestArrayPortalFromIterators(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestArrayPortalFromIterators);
}

@ -0,0 +1,162 @@
//============================================================================
// 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/cont/internal/IteratorFromArrayPortal.h>
#include <vtkm/VectorTraits.h>
#include <vtkm/cont/internal/ArrayPortalFromIterators.h>
#include <vtkm/cont/testing/Testing.h>
namespace {
template<typename T>
struct TemplatedTests
{
static const vtkm::Id ARRAY_SIZE = 10;
typedef T ValueType;
typedef typename vtkm::VectorTraits<ValueType>::ComponentType ComponentType;
ValueType ExpectedValue(vtkm::Id index, ComponentType value) {
return ValueType(index + value);
}
template<class IteratorType>
void FillIterator(IteratorType begin, IteratorType end, ComponentType value) {
vtkm::Id index = 0;
for (IteratorType iter = begin; iter != end; iter++)
{
*iter = ExpectedValue(index, value);
index++;
}
}
template<class IteratorType>
bool CheckIterator(IteratorType begin,
IteratorType end,
ComponentType value) {
vtkm::Id index = 0;
for (IteratorType iter = begin; iter != end; iter++)
{
if (ValueType(*iter) != ExpectedValue(index, value)) return false;
index++;
}
return true;
}
ComponentType ORIGINAL_VALUE() { return 239; }
template<class ArrayPortalType>
void TestIteratorRead(ArrayPortalType portal)
{
typedef vtkm::cont::internal::IteratorFromArrayPortal<ArrayPortalType> IteratorType;
IteratorType begin = vtkm::cont::internal::make_IteratorBegin(portal);
IteratorType end = vtkm::cont::internal::make_IteratorEnd(portal);
VTKM_TEST_ASSERT(std::distance(begin, end) == ARRAY_SIZE,
"Distance between begin and end incorrect.");
std::cout << " Check forward iteration." << std::endl;
VTKM_TEST_ASSERT(CheckIterator(begin, end, ORIGINAL_VALUE()),
"Forward iteration wrong");
std::cout << " Check backward iteration." << std::endl;
IteratorType middle = end;
for (vtkm::Id index = portal.GetNumberOfValues()-1; index >= 0; index--)
{
middle--;
ValueType value = *middle;
VTKM_TEST_ASSERT(value == ExpectedValue(index, ORIGINAL_VALUE()),
"Backward iteration wrong");
}
std::cout << " Check advance" << std::endl;
middle = begin + ARRAY_SIZE/2;
VTKM_TEST_ASSERT(std::distance(begin, middle) == ARRAY_SIZE/2,
"Bad distance to middle.");
VTKM_TEST_ASSERT(
ValueType(*middle) == ExpectedValue(ARRAY_SIZE/2, ORIGINAL_VALUE()),
"Bad value at middle.");
}
template<class ArrayPortalType>
void TestIteratorWrite(ArrayPortalType portal)
{
typedef vtkm::cont::internal::IteratorFromArrayPortal<ArrayPortalType> IteratorType;
IteratorType begin = vtkm::cont::internal::make_IteratorBegin(portal);
IteratorType end = vtkm::cont::internal::make_IteratorEnd(portal);
static const ComponentType WRITE_VALUE = 873;
std::cout << " Write values to iterator." << std::endl;
FillIterator(begin, end, WRITE_VALUE);
std::cout << " Check values in portal." << std::endl;
VTKM_TEST_ASSERT(CheckIterator(portal.GetIteratorBegin(),
portal.GetIteratorEnd(),
WRITE_VALUE),
"Did not get correct values when writing to iterator.");
}
void operator()()
{
ValueType array[ARRAY_SIZE];
FillIterator(array, array+ARRAY_SIZE, ORIGINAL_VALUE());
::vtkm::cont::internal::ArrayPortalFromIterators<ValueType *>
portal(array, array+ARRAY_SIZE);
::vtkm::cont::internal::ArrayPortalFromIterators<const ValueType *>
const_portal(array, array+ARRAY_SIZE);
std::cout << " Test read from iterator." << std::endl;
TestIteratorRead(portal);
std::cout << " Test read from const iterator." << std::endl;
TestIteratorRead(const_portal);
std::cout << " Test write to iterator." << std::endl;
TestIteratorWrite(portal);
}
};
struct TestFunctor
{
template<typename T>
void operator()(T)
{
TemplatedTests<T> tests;
tests();
}
};
void TestArrayIteratorFromArrayPortal()
{
vtkm::testing::Testing::TryAllTypes(TestFunctor());
}
} // Anonymous namespace
int UnitTestIteratorFromArrayPortal(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestArrayIteratorFromArrayPortal);
}

@ -0,0 +1,35 @@
##============================================================================
## 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.
##============================================================================
set(headers
Testing.h
)
vtkm_declare_headers(${headers})
set(unit_tests
UnitTestArrayContainerControlBasic.cxx
UnitTestArrayContainerControlImplicit.cxx
UnitTestArrayHandle.cxx
UnitTestContTesting.cxx
)
vtkm_unit_tests(SOURCES ${unit_tests})

@ -0,0 +1,67 @@
//============================================================================
// 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_testing_Testing_h
#define vtkm_cont_testing_Testing_h
#include <vtkm/cont/Error.h>
#include <vtkm/testing/Testing.h>
namespace vtkm {
namespace cont {
namespace testing {
struct Testing
{
public:
template<class Func>
static VTKM_CONT_EXPORT int Run(Func function)
{
try
{
function();
}
catch (vtkm::testing::Testing::TestFailure error)
{
std::cout << "***** Test failed @ "
<< error.GetFile() << ":" << error.GetLine() << std::endl
<< error.GetMessage() << std::endl;
return 1;
}
catch (vtkm::cont::Error error)
{
std::cout << "***** Uncaught VTKm exception thrown." << std::endl
<< error.GetMessage() << std::endl;
return 1;
}
catch (...)
{
std::cout << "***** Unidentified exception thrown." << std::endl;
return 1;
}
return 0;
}
};
}
}
} // namespace vtkm::cont::testing
#endif //vtkm_cont_internal_Testing_h

@ -0,0 +1,168 @@
//============================================================================
// 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_ARRAY_CONTAINER_CONTROL VTKM_ARRAY_CONTAINER_CONTROL_ERROR
#include <vtkm/cont/ArrayContainerControlBasic.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/VectorTraits.h>
namespace
{
const vtkm::Id ARRAY_SIZE = 10;
template <typename T>
struct TemplatedTests
{
typedef vtkm::cont::internal::ArrayContainerControl<
T, vtkm::cont::ArrayContainerControlTagBasic> ArrayContainerType;
typedef typename ArrayContainerType::ValueType ValueType;
typedef typename ArrayContainerType::PortalType PortalType;
typedef typename PortalType::IteratorType IteratorType;
void SetContainer(ArrayContainerType &array, ValueType value)
{
for (IteratorType iter = array.GetPortal().GetIteratorBegin();
iter != array.GetPortal().GetIteratorEnd();
iter ++)
{
*iter = value;
}
}
bool CheckContainer(ArrayContainerType &array, ValueType value)
{
for (IteratorType iter = array.GetPortal().GetIteratorBegin();
iter != array.GetPortal().GetIteratorEnd();
iter ++)
{
if (!test_equal(*iter, value)) return false;
}
return true;
}
typename vtkm::VectorTraits<ValueType>::ComponentType STOLEN_ARRAY_VALUE() {
return 4529;
}
/// Returned value should later be passed to StealArray2. It is best to
/// put as much between the two test parts to maximize the chance of a
/// deallocated array being overridden (and thus detected).
ValueType *StealArray1()
{
ValueType *stolenArray;
ValueType stolenArrayValue = ValueType(STOLEN_ARRAY_VALUE());
ArrayContainerType stealMyArray;
stealMyArray.Allocate(ARRAY_SIZE);
SetContainer(stealMyArray, stolenArrayValue);
VTKM_TEST_ASSERT(stealMyArray.GetNumberOfValues() == ARRAY_SIZE,
"Array not properly allocated.");
// This call steals the array and prevents deallocation.
stolenArray = stealMyArray.StealArray();
VTKM_TEST_ASSERT(stealMyArray.GetNumberOfValues() == 0,
"StealArray did not let go of array.");
return stolenArray;
}
void StealArray2(ValueType *stolenArray)
{
ValueType stolenArrayValue = ValueType(STOLEN_ARRAY_VALUE());
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
{
VTKM_TEST_ASSERT(test_equal(stolenArray[index], stolenArrayValue),
"Stolen array did not retain values.");
}
delete[] stolenArray;
}
void BasicAllocation()
{
ArrayContainerType arrayContainer;
VTKM_TEST_ASSERT(arrayContainer.GetNumberOfValues() == 0,
"New array container not zero sized.");
arrayContainer.Allocate(ARRAY_SIZE);
VTKM_TEST_ASSERT(arrayContainer.GetNumberOfValues() == ARRAY_SIZE,
"Array not properly allocated.");
const ValueType BASIC_ALLOC_VALUE = ValueType(548);
SetContainer(arrayContainer, BASIC_ALLOC_VALUE);
VTKM_TEST_ASSERT(CheckContainer(arrayContainer, BASIC_ALLOC_VALUE),
"Array not holding value.");
arrayContainer.Allocate(ARRAY_SIZE * 2);
VTKM_TEST_ASSERT(arrayContainer.GetNumberOfValues() == ARRAY_SIZE * 2,
"Array not reallocated correctly.");
arrayContainer.Shrink(ARRAY_SIZE);
VTKM_TEST_ASSERT(arrayContainer.GetNumberOfValues() == ARRAY_SIZE,
"Array Shrnk failed to resize.");
arrayContainer.ReleaseResources();
VTKM_TEST_ASSERT(arrayContainer.GetNumberOfValues() == 0,
"Array not released correctly.");
try
{
arrayContainer.Shrink(ARRAY_SIZE);
VTKM_TEST_ASSERT(true==false,
"Array shrink do a larger size was possible. This can't be allowed.");
}
catch(vtkm::cont::ErrorControlBadValue){}
}
void operator()()
{
ValueType *stolenArray = StealArray1();
BasicAllocation();
StealArray2(stolenArray);
}
};
struct TestFunctor
{
template <typename T>
void operator()(T)
{
TemplatedTests<T> tests;
tests();
}
};
void TestArrayContainerControlBasic()
{
vtkm::testing::Testing::TryAllTypes(TestFunctor());
}
} // Anonymous namespace
int UnitTestArrayContainerControlBasic(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestArrayContainerControlBasic);
}

@ -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.
//============================================================================
#define VTKM_ARRAY_CONTAINER_CONTROL VTKM_ARRAY_CONTAINER_CONTROL_ERROR
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayContainerControlImplicit.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/internal/IteratorFromArrayPortal.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/VectorTraits.h>
namespace
{
template <typename T>
struct TestImplicitContainer
{
typedef T ValueType;
ValueType Temp;
typedef vtkm::cont::internal::IteratorFromArrayPortal<
TestImplicitContainer<T> > IteratorType;
VTKM_EXEC_CONT_EXPORT
TestImplicitContainer(): Temp(1) { }
VTKM_EXEC_CONT_EXPORT
vtkm::Id GetNumberOfValues() const
{
return 1;
}
VTKM_EXEC_CONT_EXPORT
ValueType Get(vtkm::Id vtkmNotUsed(index)) const
{
return Temp;
}
VTKM_CONT_EXPORT
IteratorType GetIteratorBegin() const {
return IteratorType(*this);
}
VTKM_CONT_EXPORT
IteratorType GetIteratorEnd() const {
return IteratorType(*this, this->GetNumberOfValues());
}
};
const vtkm::Id ARRAY_SIZE = 1;
template <typename T>
struct TemplatedTests
{
typedef vtkm::cont::ArrayContainerControlTagImplicit<
TestImplicitContainer<T> > ContainerTagType;
typedef vtkm::cont::internal::ArrayContainerControl<
T, ContainerTagType > ArrayContainerType;
typedef typename ArrayContainerType::ValueType ValueType;
typedef typename ArrayContainerType::PortalType PortalType;
typedef typename PortalType::IteratorType IteratorType;
void BasicAllocation()
{
ArrayContainerType arrayContainer;
try{ arrayContainer.GetNumberOfValues();
VTKM_TEST_ASSERT(false == true,
"Implicit Container GetNumberOfValues method didn't throw error.");
}
catch(vtkm::cont::ErrorControlBadValue e){}
try{ arrayContainer.Allocate(ARRAY_SIZE);
VTKM_TEST_ASSERT(false == true,
"Implicit Container Allocate method didn't throw error.");
}
catch(vtkm::cont::ErrorControlBadValue e){}
try
{
arrayContainer.Shrink(ARRAY_SIZE);
VTKM_TEST_ASSERT(true==false,
"Array shrink do a larger size was possible. This can't be allowed.");
}
catch(vtkm::cont::ErrorControlBadValue){}
try
{
arrayContainer.ReleaseResources();
VTKM_TEST_ASSERT(true==false,
"Can't Release an implicit array");
}
catch(vtkm::cont::ErrorControlBadValue){}
}
void BasicAccess()
{
TestImplicitContainer<T> portal;
vtkm::cont::ArrayHandle<T,ContainerTagType> implictHandle(portal);
VTKM_TEST_ASSERT(implictHandle.GetNumberOfValues() == 1,
"handle should have size 1");
VTKM_TEST_ASSERT(implictHandle.GetPortalConstControl().Get(0) == T(1),
"portals first values should be 1");
;
}
void operator()()
{
BasicAllocation();
BasicAccess();
}
};
struct TestFunctor
{
template <typename T>
void operator()(T)
{
TemplatedTests<T> tests;
tests();
}
};
void TestArrayContainerControlBasic()
{
vtkm::testing::Testing::TryAllTypes(TestFunctor());
}
} // Anonymous namespace
int UnitTestArrayContainerControlImplicit(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestArrayContainerControlBasic);
}

@ -0,0 +1,164 @@
//============================================================================
// 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 sets up the ArrayHandle semantics to allocate pointers and share memory
//between control and execution.
#define VTKM_ARRAY_CONTAINER_CONTROL VTKM_ARRAY_CONTAINER_CONTROL_BASIC
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_SERIAL
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/testing/Testing.h>
#include <algorithm>
namespace
{
const vtkm::Id ARRAY_SIZE = 10;
vtkm::Scalar TestValue(vtkm::Id index)
{
return static_cast<vtkm::Scalar>(10.0*index + 0.01*(index+1));
}
template<class IteratorType>
bool CheckValues(IteratorType begin, IteratorType end)
{
vtkm::Id index = 0;
for (IteratorType iter = begin; iter != end; iter++)
{
if (!test_equal(*iter, TestValue(index))) return false;
index++;
}
return true;
}
template<typename T>
bool CheckValues(const vtkm::cont::ArrayHandle<T> &handle)
{
return CheckValues(handle.GetPortalConstControl().GetIteratorBegin(),
handle.GetPortalConstControl().GetIteratorEnd());
}
void TestArrayHandle()
{
std::cout << "Create array handle." << std::endl;
vtkm::Scalar array[ARRAY_SIZE];
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
{
array[index] = TestValue(index);
}
vtkm::cont::ArrayHandle<vtkm::Scalar>::PortalControl arrayPortal(
&array[0], &array[ARRAY_SIZE]);
vtkm::cont::ArrayHandle<vtkm::Scalar>
arrayHandle(arrayPortal);
VTKM_TEST_ASSERT(arrayHandle.GetNumberOfValues() == ARRAY_SIZE,
"ArrayHandle has wrong number of entries.");
std::cout << "Check basic array." << std::endl;
VTKM_TEST_ASSERT(CheckValues(arrayHandle),
"Array values not set correctly.");
std::cout << "Check out execution array behavior." << std::endl;
{
vtkm::cont::ArrayHandle<vtkm::Scalar>::
ExecutionTypes<VTKM_DEFAULT_DEVICE_ADAPTER_TAG>::PortalConst
executionPortal;
executionPortal =
arrayHandle.PrepareForInput(VTKM_DEFAULT_DEVICE_ADAPTER_TAG());
VTKM_TEST_ASSERT(CheckValues(executionPortal.GetIteratorBegin(),
executionPortal.GetIteratorEnd()),
"Array not copied to execution correctly.");
}
{
bool gotException = false;
try
{
arrayHandle.PrepareForInPlace(VTKM_DEFAULT_DEVICE_ADAPTER_TAG());
}
catch (vtkm::cont::Error &error)
{
std::cout << "Got expected error: " << error.GetMessage() << std::endl;
gotException = true;
}
VTKM_TEST_ASSERT(gotException,
"PrepareForInPlace did not fail for const array.");
}
{
vtkm::cont::ArrayHandle<vtkm::Scalar>::
ExecutionTypes<VTKM_DEFAULT_DEVICE_ADAPTER_TAG>::Portal executionPortal;
executionPortal =
arrayHandle.PrepareForOutput(ARRAY_SIZE*2,
VTKM_DEFAULT_DEVICE_ADAPTER_TAG());
vtkm::Id index = 0;
for (vtkm::Scalar *iter = executionPortal.GetIteratorBegin();
iter != executionPortal.GetIteratorEnd();
iter++)
{
*iter = TestValue(index);
index++;
}
}
VTKM_TEST_ASSERT(arrayHandle.GetNumberOfValues() == ARRAY_SIZE*2,
"Array not allocated correctly.");
VTKM_TEST_ASSERT(CheckValues(arrayHandle),
"Array values not retrieved from execution.");
std::cout << "Try shrinking the array." << std::endl;
arrayHandle.Shrink(ARRAY_SIZE);
VTKM_TEST_ASSERT(arrayHandle.GetNumberOfValues() == ARRAY_SIZE,
"Array size did not shrink correctly.");
VTKM_TEST_ASSERT(CheckValues(arrayHandle),
"Array values not retrieved from execution.");
std::cout << "Try in place operation." << std::endl;
{
vtkm::cont::ArrayHandle<vtkm::Scalar>::
ExecutionTypes<VTKM_DEFAULT_DEVICE_ADAPTER_TAG>::Portal executionPortal;
executionPortal =
arrayHandle.PrepareForInPlace(VTKM_DEFAULT_DEVICE_ADAPTER_TAG());
for (vtkm::Scalar *iter = executionPortal.GetIteratorBegin();
iter != executionPortal.GetIteratorEnd();
iter++)
{
*iter += 1;
}
}
vtkm::cont::ArrayHandle<vtkm::Scalar>::PortalConstControl controlPortal =
arrayHandle.GetPortalConstControl();
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
{
VTKM_TEST_ASSERT(test_equal(controlPortal.Get(index), TestValue(index) + 1),
"Did not get result from in place operation.");
}
}
}
int UnitTestArrayHandle(int, char *[])
{
return vtkm::cont::testing::Testing::Run(TestArrayHandle);
}

@ -0,0 +1,85 @@
//============================================================================
// 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 meta-test makes sure that the testing environment is properly reporting
// errors.
#include <vtkm/cont/Assert.h>
#include <vtkm/cont/testing/Testing.h>
namespace {
void TestFail()
{
VTKM_TEST_FAIL("I expect this error.");
}
void BadTestAssert()
{
VTKM_TEST_ASSERT(0 == 1, "I expect this error.");
}
void BadAssert()
{
VTKM_ASSERT_CONT(0 == 1);
}
void GoodAssert()
{
VTKM_TEST_ASSERT(1 == 1, "Always true.");
VTKM_ASSERT_CONT(1 == 1);
}
} // anonymous namespace
int UnitTestContTesting(int, char *[])
{
std::cout << "-------\nThis call should fail." << std::endl;
if (vtkm::cont::testing::Testing::Run(TestFail) == 0)
{
std::cout << "Did not get expected fail!" << std::endl;
return 1;
}
std::cout << "-------\nThis call should fail." << std::endl;
if (vtkm::cont::testing::Testing::Run(BadTestAssert) == 0)
{
std::cout << "Did not get expected fail!" << std::endl;
return 1;
}
//VTKM_ASSERT_CONT only is a valid call when you are building with debug
#ifndef NDEBUG
int expectedResult=0;
#else
int expectedResult=1;
#endif
std::cout << "-------\nThis call should fail on debug builds." << std::endl;
if (vtkm::cont::testing::Testing::Run(BadAssert) == expectedResult)
{
std::cout << "Did not get expected fail!" << std::endl;
return 1;
}
std::cout << "-------\nThis call should pass." << std::endl;
// This is what your main function typically looks like.
return vtkm::cont::testing::Testing::Run(GoodAssert);
}