2014-02-11 17:34:56 +00:00
|
|
|
//============================================================================
|
|
|
|
// Copyright (c) Kitware, Inc.
|
|
|
|
// All rights reserved.
|
|
|
|
// See LICENSE.txt for details.
|
2019-04-15 23:24:21 +00:00
|
|
|
//
|
2014-02-11 17:34:56 +00:00
|
|
|
// 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.
|
|
|
|
//============================================================================
|
2014-03-07 15:19:09 +00:00
|
|
|
#ifndef vtk_m_cont_testing_TestingDeviceAdapter_h
|
|
|
|
#define vtk_m_cont_testing_TestingDeviceAdapter_h
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2016-11-23 20:18:58 +00:00
|
|
|
#include <vtkm/BinaryOperators.h>
|
2017-05-18 14:51:24 +00:00
|
|
|
#include <vtkm/BinaryPredicates.h>
|
|
|
|
#include <vtkm/TypeTraits.h>
|
2016-11-23 20:18:58 +00:00
|
|
|
|
2019-09-03 15:53:14 +00:00
|
|
|
#include <vtkm/cont/ArrayGetValues.h>
|
2014-02-11 17:34:56 +00:00
|
|
|
#include <vtkm/cont/ArrayHandle.h>
|
2020-04-16 16:37:44 +00:00
|
|
|
#include <vtkm/cont/ArrayHandleCast.h>
|
2015-06-10 20:37:52 +00:00
|
|
|
#include <vtkm/cont/ArrayHandleConstant.h>
|
2015-09-15 04:11:09 +00:00
|
|
|
#include <vtkm/cont/ArrayHandleIndex.h>
|
2015-06-18 19:40:51 +00:00
|
|
|
#include <vtkm/cont/ArrayHandlePermutation.h>
|
2020-04-16 20:18:34 +00:00
|
|
|
#include <vtkm/cont/ArrayHandleView.h>
|
2015-06-10 20:37:52 +00:00
|
|
|
#include <vtkm/cont/ArrayHandleZip.h>
|
2014-09-08 20:59:11 +00:00
|
|
|
#include <vtkm/cont/ArrayPortalToIterators.h>
|
2017-05-18 14:51:24 +00:00
|
|
|
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
|
2017-01-09 21:15:32 +00:00
|
|
|
#include <vtkm/cont/ErrorBadAllocation.h>
|
2014-02-11 17:34:56 +00:00
|
|
|
#include <vtkm/cont/ErrorExecution.h>
|
2015-12-02 18:55:49 +00:00
|
|
|
#include <vtkm/cont/RuntimeDeviceInformation.h>
|
2014-06-10 18:53:34 +00:00
|
|
|
#include <vtkm/cont/Timer.h>
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2021-01-06 17:24:42 +00:00
|
|
|
#include <vtkm/cont/internal/ArrayPortalFromIterators.h>
|
2017-03-29 14:48:43 +00:00
|
|
|
#include <vtkm/cont/internal/VirtualObjectTransfer.h>
|
2014-02-11 17:34:56 +00:00
|
|
|
|
|
|
|
#include <vtkm/cont/testing/Testing.h>
|
|
|
|
|
2018-06-07 21:08:02 +00:00
|
|
|
#include <vtkm/cont/AtomicArray.h>
|
2016-02-10 15:51:31 +00:00
|
|
|
|
2014-06-11 22:15:46 +00:00
|
|
|
#include <algorithm>
|
2018-06-26 18:52:04 +00:00
|
|
|
#include <chrono>
|
2014-06-11 22:15:46 +00:00
|
|
|
#include <cmath>
|
2018-05-29 21:09:20 +00:00
|
|
|
#include <ctime>
|
|
|
|
#include <random>
|
2018-06-26 18:52:04 +00:00
|
|
|
#include <thread>
|
2014-02-11 17:34:56 +00:00
|
|
|
#include <utility>
|
|
|
|
#include <vector>
|
|
|
|
|
2016-11-23 21:14:56 +00:00
|
|
|
#include <vtkm/internal/Windows.h>
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
namespace cont
|
|
|
|
{
|
|
|
|
namespace testing
|
|
|
|
{
|
2014-02-11 17:34:56 +00:00
|
|
|
|
|
|
|
#define ERROR_MESSAGE "Got an error."
|
2021-04-10 12:27:31 +00:00
|
|
|
#define ARRAY_SIZE 100
|
|
|
|
#define OFFSET 10
|
|
|
|
#define DIM_SIZE 8
|
2014-02-11 17:34:56 +00:00
|
|
|
|
|
|
|
/// This class has a single static member, Run, that tests the templated
|
|
|
|
/// DeviceAdapter for conformance.
|
|
|
|
///
|
2017-05-18 14:29:41 +00:00
|
|
|
template <class DeviceAdapterTag>
|
2014-02-11 17:34:56 +00:00
|
|
|
struct TestingDeviceAdapter
|
|
|
|
{
|
|
|
|
private:
|
2017-06-23 18:50:34 +00:00
|
|
|
using StorageTag = vtkm::cont::StorageTagBasic;
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2017-08-16 15:34:21 +00:00
|
|
|
using IdArrayHandle = vtkm::cont::ArrayHandle<vtkm::Id, StorageTag>;
|
2017-10-24 22:12:30 +00:00
|
|
|
using IdComponentArrayHandle = vtkm::cont::ArrayHandle<vtkm::IdComponent, StorageTag>;
|
2017-08-16 15:34:21 +00:00
|
|
|
using ScalarArrayHandle = vtkm::cont::ArrayHandle<vtkm::FloatDefault, StorageTag>;
|
2020-04-16 20:18:34 +00:00
|
|
|
using FloatCastHandle = vtkm::cont::ArrayHandleCast<vtkm::FloatDefault, IdArrayHandle>;
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2021-02-01 15:03:11 +00:00
|
|
|
using IdPortalType = typename IdArrayHandle::WritePortalType;
|
|
|
|
using IdPortalConstType = typename IdArrayHandle::ReadPortalType;
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2017-06-23 18:50:34 +00:00
|
|
|
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapterTag>;
|
2014-02-11 17:34:56 +00:00
|
|
|
|
|
|
|
public:
|
|
|
|
// Cuda kernels have to be public (in Cuda 4.0).
|
|
|
|
|
|
|
|
|
2018-07-03 20:28:29 +00:00
|
|
|
template <typename PortalType>
|
|
|
|
struct GenericClearArrayKernel
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
2018-07-03 20:28:29 +00:00
|
|
|
using ValueType = typename PortalType::ValueType;
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2018-07-03 20:28:29 +00:00
|
|
|
GenericClearArrayKernel(const PortalType& array,
|
|
|
|
const ValueType& fillValue = static_cast<ValueType>(OFFSET))
|
2017-05-18 14:29:41 +00:00
|
|
|
: Array(array)
|
|
|
|
, Dims()
|
2018-07-03 20:28:29 +00:00
|
|
|
, FillValue(fillValue)
|
2017-05-18 14:29:41 +00:00
|
|
|
{
|
|
|
|
}
|
2015-10-15 13:26:26 +00:00
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2018-07-03 20:28:29 +00:00
|
|
|
GenericClearArrayKernel(const PortalType& array,
|
|
|
|
const vtkm::Id3& dims,
|
|
|
|
const ValueType& fillValue = static_cast<ValueType>(OFFSET))
|
2017-05-18 14:29:41 +00:00
|
|
|
: Array(array)
|
|
|
|
, Dims(dims)
|
2018-07-03 20:28:29 +00:00
|
|
|
, FillValue(fillValue)
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2018-07-03 20:28:29 +00:00
|
|
|
VTKM_EXEC void operator()(vtkm::Id index) const { this->Array.Set(index, this->FillValue); }
|
2017-05-18 14:29:41 +00:00
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_EXEC void operator()(vtkm::Id3 index) const
|
2015-10-15 13:26:26 +00:00
|
|
|
{
|
|
|
|
//convert from id3 to id
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Id flatIndex = index[0] + this->Dims[0] * (index[1] + this->Dims[1] * index[2]);
|
2015-10-15 13:26:26 +00:00
|
|
|
this->operator()(flatIndex);
|
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_CONT void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer&) {}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2018-07-03 20:28:29 +00:00
|
|
|
PortalType Array;
|
2015-10-15 13:26:26 +00:00
|
|
|
vtkm::Id3 Dims;
|
2018-07-03 20:28:29 +00:00
|
|
|
ValueType FillValue;
|
2014-02-11 17:34:56 +00:00
|
|
|
};
|
|
|
|
|
2018-07-03 20:28:29 +00:00
|
|
|
using ClearArrayKernel = GenericClearArrayKernel<IdPortalType>;
|
|
|
|
|
2020-03-26 23:34:18 +00:00
|
|
|
template <typename PortalType>
|
2014-02-11 17:34:56 +00:00
|
|
|
struct AddArrayKernel
|
|
|
|
{
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2020-03-26 23:34:18 +00:00
|
|
|
AddArrayKernel(const PortalType& array)
|
2017-05-18 14:29:41 +00:00
|
|
|
: Array(array)
|
|
|
|
, Dims()
|
|
|
|
{
|
|
|
|
}
|
2015-10-15 13:26:26 +00:00
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2020-03-26 23:34:18 +00:00
|
|
|
AddArrayKernel(const PortalType& array, const vtkm::Id3& dims)
|
2017-05-18 14:29:41 +00:00
|
|
|
: Array(array)
|
|
|
|
, Dims(dims)
|
|
|
|
{
|
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_EXEC void operator()(vtkm::Id index) const
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
|
|
|
this->Array.Set(index, this->Array.Get(index) + index);
|
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_EXEC void operator()(vtkm::Id3 index) const
|
2015-10-15 13:26:26 +00:00
|
|
|
{
|
|
|
|
//convert from id3 to id
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Id flatIndex = index[0] + this->Dims[0] * (index[1] + this->Dims[1] * index[2]);
|
2015-10-15 13:26:26 +00:00
|
|
|
this->operator()(flatIndex);
|
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_CONT void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer&) {}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2020-03-26 23:34:18 +00:00
|
|
|
PortalType Array;
|
2015-10-15 13:26:26 +00:00
|
|
|
vtkm::Id3 Dims;
|
2014-02-11 17:34:56 +00:00
|
|
|
};
|
|
|
|
|
2020-03-26 23:34:18 +00:00
|
|
|
template <typename PortalType>
|
|
|
|
static VTKM_CONT AddArrayKernel<PortalType> MakeAddArrayKernel(
|
|
|
|
PortalType portal,
|
|
|
|
const vtkm::Id3& dims = vtkm::Id3{})
|
|
|
|
{
|
|
|
|
return AddArrayKernel<PortalType>(portal, dims);
|
|
|
|
}
|
|
|
|
|
2018-07-03 20:28:29 +00:00
|
|
|
// Checks that each instance is only visited once:
|
|
|
|
struct OverlapKernel
|
|
|
|
{
|
|
|
|
using ArrayType = ArrayHandle<bool>;
|
2021-02-01 15:03:11 +00:00
|
|
|
using PortalType = typename ArrayType::WritePortalType;
|
2018-07-03 20:28:29 +00:00
|
|
|
|
|
|
|
PortalType TrackerPortal;
|
|
|
|
PortalType ValidPortal;
|
|
|
|
vtkm::Id3 Dims;
|
|
|
|
|
|
|
|
VTKM_CONT
|
|
|
|
OverlapKernel(const PortalType& trackerPortal,
|
|
|
|
const PortalType& validPortal,
|
|
|
|
const vtkm::Id3& dims)
|
|
|
|
: TrackerPortal(trackerPortal)
|
|
|
|
, ValidPortal(validPortal)
|
|
|
|
, Dims(dims)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT
|
|
|
|
OverlapKernel(const PortalType& trackerPortal, const PortalType& validPortal)
|
|
|
|
: TrackerPortal(trackerPortal)
|
|
|
|
, ValidPortal(validPortal)
|
|
|
|
, Dims()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_EXEC void operator()(vtkm::Id index) const
|
|
|
|
{
|
|
|
|
if (this->TrackerPortal.Get(index))
|
|
|
|
{ // this index has already been visited, that's an error
|
|
|
|
this->ValidPortal.Set(index, false);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
this->TrackerPortal.Set(index, true);
|
|
|
|
this->ValidPortal.Set(index, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_EXEC void operator()(vtkm::Id3 index) const
|
|
|
|
{
|
|
|
|
//convert from id3 to id
|
|
|
|
vtkm::Id flatIndex = index[0] + this->Dims[0] * (index[1] + this->Dims[1] * index[2]);
|
|
|
|
this->operator()(flatIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_CONT void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer&) {}
|
|
|
|
};
|
|
|
|
|
2014-02-11 17:34:56 +00:00
|
|
|
struct OneErrorKernel
|
|
|
|
{
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_EXEC void operator()(vtkm::Id index) const
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
if (index == ARRAY_SIZE / 2)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2014-02-11 17:34:56 +00:00
|
|
|
this->ErrorMessage.RaiseError(ERROR_MESSAGE);
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT void SetErrorMessageBuffer(
|
2017-05-18 14:29:41 +00:00
|
|
|
const vtkm::exec::internal::ErrorMessageBuffer& errorMessage)
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
|
|
|
this->ErrorMessage = errorMessage;
|
|
|
|
}
|
|
|
|
|
|
|
|
vtkm::exec::internal::ErrorMessageBuffer ErrorMessage;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct AllErrorKernel
|
|
|
|
{
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_EXEC void operator()(vtkm::Id vtkmNotUsed(index)) const
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
|
|
|
this->ErrorMessage.RaiseError(ERROR_MESSAGE);
|
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT void SetErrorMessageBuffer(
|
2017-05-18 14:29:41 +00:00
|
|
|
const vtkm::exec::internal::ErrorMessageBuffer& errorMessage)
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
|
|
|
this->ErrorMessage = errorMessage;
|
|
|
|
}
|
|
|
|
|
|
|
|
vtkm::exec::internal::ErrorMessageBuffer ErrorMessage;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct OffsetPlusIndexKernel
|
|
|
|
{
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2017-05-18 14:29:41 +00:00
|
|
|
OffsetPlusIndexKernel(const IdPortalType& array)
|
|
|
|
: Array(array)
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_EXEC void operator()(vtkm::Id index) const { this->Array.Set(index, OFFSET + index); }
|
|
|
|
|
|
|
|
VTKM_CONT void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer&) {}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
|
|
|
IdPortalType Array;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct MarkOddNumbersKernel
|
|
|
|
{
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2017-05-18 14:29:41 +00:00
|
|
|
MarkOddNumbersKernel(const IdPortalType& array)
|
|
|
|
: Array(array)
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_EXEC void operator()(vtkm::Id index) const { this->Array.Set(index, index % 2); }
|
|
|
|
|
|
|
|
VTKM_CONT void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer&) {}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
|
|
|
IdPortalType Array;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct FuseAll
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T>
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_EXEC bool operator()(const T&, const T&) const
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
|
|
|
//binary predicates for unique return true if they are the same
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T>
|
2016-03-14 13:51:17 +00:00
|
|
|
struct AtomicKernel
|
2016-02-10 15:51:31 +00:00
|
|
|
{
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2020-01-21 20:18:03 +00:00
|
|
|
AtomicKernel(const vtkm::cont::AtomicArray<T>& array, vtkm::cont::Token& token)
|
|
|
|
: AArray(array.PrepareForExecution(DeviceAdapterTag(), token))
|
2017-05-18 14:29:41 +00:00
|
|
|
{
|
|
|
|
}
|
2016-02-10 15:51:31 +00:00
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_EXEC void operator()(vtkm::Id index) const
|
2016-02-10 15:51:31 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
T value = (T)index;
|
2016-03-04 22:46:45 +00:00
|
|
|
this->AArray.Add(0, value);
|
2016-02-10 15:51:31 +00:00
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_CONT void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer&) {}
|
2016-02-10 15:51:31 +00:00
|
|
|
|
2021-02-02 23:43:51 +00:00
|
|
|
vtkm::exec::AtomicArrayExecutionObject<T> AArray;
|
2016-02-10 15:51:31 +00:00
|
|
|
};
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T>
|
2016-03-14 13:51:17 +00:00
|
|
|
struct AtomicCASKernel
|
2016-03-08 17:41:02 +00:00
|
|
|
{
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2020-01-21 20:18:03 +00:00
|
|
|
AtomicCASKernel(const vtkm::cont::AtomicArray<T>& array, vtkm::cont::Token& token)
|
|
|
|
: AArray(array.PrepareForExecution(DeviceAdapterTag(), token))
|
2017-05-18 14:29:41 +00:00
|
|
|
{
|
|
|
|
}
|
2016-03-08 17:41:02 +00:00
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_EXEC void operator()(vtkm::Id index) const
|
2016-03-08 17:41:02 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
T value = (T)index;
|
2019-08-22 19:52:58 +00:00
|
|
|
//Get the old value from the array
|
|
|
|
T oldValue = this->AArray.Get(0);
|
Change interface of atomic compare and swap
The old atomic compare and swap operations (`vtkm::AtomicCompareAndSwap`
and `vtkm::exec::AtomicArrayExecutionObject::CompareAndSwap`) had an
order of arguments that was confusing. The order of the arguments was
shared pointer (or index), desired value, expected value. Most people
probably assume expected value comes before desired value. And this
order conflicts with the order in the `std` methods, GCC atomics, and
Kokkos.
Change the interface of atomic operations to be patterned off the
`std::atomic_compare_exchange` and `std::atomic<T>::compare_exchange`
methods. First, these methods have a more intuitive order of parameters
(shared pointer, expected, desired). Second, rather than take a value
for the expected and return the actual old value, they take a pointer to
the expected value (or reference in `AtomicArrayExecutionObject`) and
modify this value in the case that it does not match the actual value.
This makes it harder to mix up the expected and desired parameters.
Also, because the methods return a bool indicating whether the value was
changed, there is an additional benefit that compare-exchange loops are
implemented easier.
For example, consider you want to apply the function `MyOp` on a
`sharedValue` atomically. With the old interface, you would have to do
something like this.
```cpp
T oldValue;
T newValue;
do
{
oldValue = *sharedValue;
newValue = MyOp(oldValue);
} while (vtkm::AtomicCompareAndSwap(sharedValue, newValue, oldValue) != oldValue);
```
With the new interface, this is simplfied to this.
```cpp
T oldValue = *sharedValue;
while (!vtkm::AtomicCompareExchange(sharedValue, &oldValue, MyOp(oldValue));
```
2020-09-25 00:02:59 +00:00
|
|
|
//Use atomic compare-exchange to atomically add value
|
|
|
|
while (!this->AArray.CompareExchange(0, &oldValue, oldValue + value))
|
|
|
|
;
|
2016-03-08 17:41:02 +00:00
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_CONT void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer&) {}
|
2016-03-08 17:41:02 +00:00
|
|
|
|
2021-02-02 23:43:51 +00:00
|
|
|
vtkm::exec::AtomicArrayExecutionObject<T> AArray;
|
2016-03-08 17:41:02 +00:00
|
|
|
};
|
|
|
|
|
2017-03-29 14:48:43 +00:00
|
|
|
class VirtualObjectTransferKernel
|
|
|
|
{
|
|
|
|
public:
|
2017-10-23 13:38:33 +00:00
|
|
|
struct Interface : public vtkm::VirtualObjectBase
|
2017-03-29 14:48:43 +00:00
|
|
|
{
|
2017-10-23 13:38:33 +00:00
|
|
|
VTKM_EXEC virtual vtkm::Id Foo() const = 0;
|
2017-03-29 14:48:43 +00:00
|
|
|
};
|
|
|
|
|
2017-10-23 13:38:33 +00:00
|
|
|
struct Concrete : public Interface
|
2017-03-29 14:48:43 +00:00
|
|
|
{
|
2017-10-23 13:38:33 +00:00
|
|
|
VTKM_EXEC vtkm::Id Foo() const override { return this->Value; }
|
2017-03-29 14:48:43 +00:00
|
|
|
|
|
|
|
vtkm::Id Value = 0;
|
|
|
|
};
|
|
|
|
|
2020-01-21 20:18:03 +00:00
|
|
|
VirtualObjectTransferKernel(const Interface* vo,
|
|
|
|
IdArrayHandle& result,
|
|
|
|
vtkm::cont::Token& token)
|
2017-05-18 14:29:41 +00:00
|
|
|
: Virtual(vo)
|
2020-01-21 20:18:03 +00:00
|
|
|
, Result(result.PrepareForInPlace(DeviceAdapterTag(), token))
|
2017-03-29 14:48:43 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_EXEC
|
2017-10-23 13:38:33 +00:00
|
|
|
void operator()(vtkm::Id) const { this->Result.Set(0, this->Virtual->Foo()); }
|
2017-05-18 14:29:41 +00:00
|
|
|
|
|
|
|
VTKM_CONT void SetErrorMessageBuffer(const vtkm::exec::internal::ErrorMessageBuffer&) {}
|
2017-03-29 14:48:43 +00:00
|
|
|
|
|
|
|
private:
|
2017-10-23 13:38:33 +00:00
|
|
|
const Interface* Virtual;
|
2017-03-29 14:48:43 +00:00
|
|
|
IdPortalType Result;
|
|
|
|
};
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2019-04-10 18:31:33 +00:00
|
|
|
struct CustomPairOp
|
|
|
|
{
|
|
|
|
using ValueType = vtkm::Pair<vtkm::Id, vtkm::Float32>;
|
|
|
|
|
|
|
|
VTKM_EXEC
|
|
|
|
ValueType operator()(const vtkm::Id& a) const { return ValueType(a, 0.0f); }
|
|
|
|
|
|
|
|
VTKM_EXEC
|
|
|
|
ValueType operator()(const vtkm::Id& a, const vtkm::Id& b) const
|
|
|
|
{
|
|
|
|
return ValueType(vtkm::Max(a, b), 0.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_EXEC
|
|
|
|
ValueType operator()(const ValueType& a, const ValueType& b) const
|
|
|
|
{
|
|
|
|
return ValueType(vtkm::Max(a.first, b.first), 0.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_EXEC
|
|
|
|
ValueType operator()(const vtkm::Id& a, const ValueType& b) const
|
|
|
|
{
|
|
|
|
return ValueType(vtkm::Max(a, b.first), 0.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_EXEC
|
|
|
|
ValueType operator()(const ValueType& a, const vtkm::Id& b) const
|
|
|
|
{
|
|
|
|
return ValueType(vtkm::Max(a.first, b), 0.0f);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-08-03 12:35:17 +00:00
|
|
|
struct CustomTForReduce
|
|
|
|
{
|
|
|
|
constexpr CustomTForReduce()
|
|
|
|
: Value(0.0f)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
constexpr CustomTForReduce(float f)
|
|
|
|
: Value(f)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT
|
|
|
|
constexpr float value() const { return this->Value; }
|
|
|
|
|
|
|
|
float Value;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
struct CustomMinAndMax
|
|
|
|
{
|
2019-04-10 18:31:33 +00:00
|
|
|
VTKM_EXEC_CONT
|
|
|
|
vtkm::Vec<float, 2> operator()(const T& a) const
|
|
|
|
{
|
|
|
|
return vtkm::make_Vec(a.value(), a.value());
|
|
|
|
}
|
|
|
|
|
2018-08-03 12:35:17 +00:00
|
|
|
VTKM_EXEC_CONT
|
|
|
|
vtkm::Vec<float, 2> operator()(const T& a, const T& b) const
|
|
|
|
{
|
|
|
|
return vtkm::make_Vec(vtkm::Min(a.value(), b.value()), vtkm::Max(a.value(), b.value()));
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT
|
|
|
|
vtkm::Vec<float, 2> operator()(const vtkm::Vec<float, 2>& a, const vtkm::Vec<float, 2>& b) const
|
|
|
|
{
|
|
|
|
return vtkm::make_Vec(vtkm::Min(a[0], b[0]), vtkm::Max(a[1], b[1]));
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT
|
|
|
|
vtkm::Vec<float, 2> operator()(const T& a, const vtkm::Vec<float, 2>& b) const
|
|
|
|
{
|
|
|
|
return vtkm::make_Vec(vtkm::Min(a.value(), b[0]), vtkm::Max(a.value(), b[1]));
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_EXEC_CONT
|
|
|
|
vtkm::Vec<float, 2> operator()(const vtkm::Vec<float, 2>& a, const T& b) const
|
|
|
|
{
|
|
|
|
return vtkm::make_Vec(vtkm::Min(a[0], b.value()), vtkm::Max(a[1], b.value()));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2014-02-11 17:34:56 +00:00
|
|
|
private:
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestDeviceAdapterTag()
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
2018-07-25 15:11:05 +00:00
|
|
|
constexpr DeviceAdapterTag deviceTag;
|
2019-04-18 19:09:57 +00:00
|
|
|
constexpr vtkm::cont::DeviceAdapterTagUndefined undefinedTag;
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2018-07-25 15:11:05 +00:00
|
|
|
VTKM_TEST_ASSERT(deviceTag.GetValue() == deviceTag.GetValue(),
|
2014-02-11 21:20:30 +00:00
|
|
|
"Device adapter Id does not equal itself.");
|
2019-04-18 19:09:57 +00:00
|
|
|
VTKM_TEST_ASSERT(deviceTag.GetValue() != undefinedTag.GetValue(),
|
2014-02-11 21:20:30 +00:00
|
|
|
"Device adapter Id not distinguishable from others.");
|
2015-12-16 16:18:52 +00:00
|
|
|
|
2018-07-25 15:11:05 +00:00
|
|
|
using Traits = vtkm::cont::DeviceAdapterTraits<DeviceAdapterTag>;
|
2015-12-16 16:18:52 +00:00
|
|
|
VTKM_TEST_ASSERT(Traits::GetName() == Traits::GetName(),
|
|
|
|
"Device adapter Name does not equal itself.");
|
2014-02-11 17:34:56 +00:00
|
|
|
}
|
|
|
|
|
2020-03-26 23:34:18 +00:00
|
|
|
static VTKM_CONT void TestMemoryTransfer()
|
|
|
|
{
|
|
|
|
using T = vtkm::Id;
|
|
|
|
using PortalType = vtkm::cont::internal::ArrayPortalFromIterators<T*>;
|
|
|
|
auto makePortal = [](const vtkm::cont::internal::BufferInfo& buffer) {
|
|
|
|
return PortalType(static_cast<T*>(buffer.GetPointer()),
|
|
|
|
static_cast<T*>(buffer.GetPointer()) +
|
|
|
|
static_cast<std::size_t>(buffer.GetSize()) / sizeof(T));
|
|
|
|
};
|
|
|
|
|
|
|
|
constexpr vtkm::BufferSizeType BUFFER_SIZE =
|
|
|
|
ARRAY_SIZE * static_cast<vtkm::BufferSizeType>(sizeof(T));
|
|
|
|
|
|
|
|
// Set up buffer on host.
|
2020-04-22 19:58:59 +00:00
|
|
|
vtkm::cont::internal::BufferInfo hostBufferSrc =
|
|
|
|
vtkm::cont::internal::AllocateOnHost(BUFFER_SIZE);
|
|
|
|
VTKM_TEST_ASSERT(hostBufferSrc.GetSize() == BUFFER_SIZE);
|
|
|
|
SetPortal(makePortal(hostBufferSrc));
|
2020-03-26 23:34:18 +00:00
|
|
|
|
|
|
|
vtkm::cont::internal::DeviceAdapterMemoryManager<DeviceAdapterTag> memoryManager;
|
|
|
|
|
2020-04-22 19:58:59 +00:00
|
|
|
vtkm::cont::internal::BufferInfo allocatedMemory = memoryManager.Allocate(BUFFER_SIZE);
|
|
|
|
VTKM_TEST_ASSERT(allocatedMemory.GetSize() == BUFFER_SIZE);
|
2020-03-26 23:34:18 +00:00
|
|
|
|
|
|
|
allocatedMemory = memoryManager.CopyHostToDevice(hostBufferSrc);
|
|
|
|
|
2020-04-22 19:58:59 +00:00
|
|
|
vtkm::cont::internal::BufferInfo workingMemory =
|
2020-03-26 23:34:18 +00:00
|
|
|
memoryManager.CopyDeviceToDevice(allocatedMemory);
|
2020-04-22 19:58:59 +00:00
|
|
|
VTKM_TEST_ASSERT(workingMemory.GetSize() == BUFFER_SIZE);
|
2020-03-26 23:34:18 +00:00
|
|
|
|
2020-04-22 19:58:59 +00:00
|
|
|
vtkm::cont::internal::BufferInfo hostBufferDest = memoryManager.CopyDeviceToHost(workingMemory);
|
|
|
|
VTKM_TEST_ASSERT(hostBufferDest.GetSize() == BUFFER_SIZE);
|
|
|
|
CheckPortal(makePortal(hostBufferDest));
|
2020-03-26 23:34:18 +00:00
|
|
|
|
|
|
|
memoryManager.Reallocate(workingMemory, BUFFER_SIZE / 2);
|
|
|
|
hostBufferDest = memoryManager.CopyDeviceToHost(workingMemory);
|
2020-04-22 19:58:59 +00:00
|
|
|
VTKM_TEST_ASSERT(hostBufferDest.GetSize() == BUFFER_SIZE / 2);
|
|
|
|
CheckPortal(makePortal(hostBufferDest));
|
2020-03-26 23:34:18 +00:00
|
|
|
|
|
|
|
memoryManager.Reallocate(workingMemory, BUFFER_SIZE * 2);
|
|
|
|
hostBufferDest = memoryManager.CopyDeviceToHost(workingMemory);
|
2020-04-22 19:58:59 +00:00
|
|
|
VTKM_TEST_ASSERT(hostBufferDest.GetSize() == BUFFER_SIZE * 2);
|
|
|
|
hostBufferDest.Reallocate(BUFFER_SIZE / 2);
|
|
|
|
CheckPortal(makePortal(hostBufferDest));
|
2020-03-26 23:34:18 +00:00
|
|
|
|
|
|
|
// This actually requires running schedule.
|
|
|
|
workingMemory = memoryManager.CopyDeviceToDevice(allocatedMemory);
|
2020-04-22 19:58:59 +00:00
|
|
|
Algorithm::Schedule(MakeAddArrayKernel(makePortal(workingMemory)), ARRAY_SIZE);
|
2020-03-26 23:34:18 +00:00
|
|
|
|
|
|
|
hostBufferDest = memoryManager.CopyDeviceToHost(workingMemory);
|
|
|
|
|
2020-04-22 19:58:59 +00:00
|
|
|
PortalType portal = makePortal(hostBufferDest);
|
2020-03-26 23:34:18 +00:00
|
|
|
VTKM_TEST_ASSERT(portal.GetNumberOfValues() == ARRAY_SIZE);
|
|
|
|
for (vtkm::Id index = 0; index < ARRAY_SIZE; ++index)
|
|
|
|
{
|
|
|
|
T expected = TestValue(index, T()) + T(index);
|
|
|
|
T computed = portal.Get(index);
|
|
|
|
VTKM_TEST_ASSERT(test_equal(expected, computed), expected, " != ", computed);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestOutOfMemory()
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
// Only test out of memory with 64 bit ids. If there are 32 bit ids on
|
|
|
|
// a 64 bit OS (common), it is simply too hard to get a reliable allocation
|
|
|
|
// that is too much memory.
|
2014-02-11 17:34:56 +00:00
|
|
|
#ifdef VTKM_USE_64BIT_IDS
|
2021-04-10 12:27:31 +00:00
|
|
|
bool caught_expected = false;
|
2014-02-11 17:34:56 +00:00
|
|
|
try
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2020-01-21 20:18:03 +00:00
|
|
|
vtkm::cont::Token token;
|
2019-07-31 16:20:38 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::Vec4f_32, StorageTagBasic> bigArray;
|
2020-06-16 12:54:01 +00:00
|
|
|
const vtkm::Id bigSize = 0x7FFFFFFFFFFFFFFELL;
|
2020-01-21 20:18:03 +00:00
|
|
|
bigArray.PrepareForOutput(bigSize, DeviceAdapterTag{}, token);
|
2014-02-11 17:34:56 +00:00
|
|
|
// It does not seem reasonable to get here. The previous call should fail.
|
|
|
|
VTKM_TEST_FAIL("A ridiculously sized allocation succeeded. Either there "
|
2014-02-11 21:20:30 +00:00
|
|
|
"was a failure that was not reported but should have been "
|
|
|
|
"or the width of vtkm::Id is not large enough to express all "
|
|
|
|
"array sizes.");
|
|
|
|
}
|
2021-04-10 13:11:27 +00:00
|
|
|
catch (vtkm::cont::ErrorBadAllocation&)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2021-04-10 12:27:31 +00:00
|
|
|
caught_expected = true;
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2021-04-10 12:27:31 +00:00
|
|
|
VTKM_TEST_ASSERT(caught_expected,
|
|
|
|
"Should have caught an exception from a monstrous allocation, but did not.");
|
2014-02-11 17:34:56 +00:00
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT
|
2014-06-10 18:53:34 +00:00
|
|
|
static void TestTimer()
|
|
|
|
{
|
2019-05-15 21:26:34 +00:00
|
|
|
auto& tracker = vtkm::cont::GetRuntimeDeviceTracker();
|
2019-01-09 16:11:49 +00:00
|
|
|
if (tracker.CanRunOn(DeviceAdapterTag()))
|
|
|
|
{
|
|
|
|
vtkm::cont::Timer timer{ DeviceAdapterTag() };
|
|
|
|
timer.Start();
|
2020-05-17 16:53:14 +00:00
|
|
|
Algorithm::Synchronize();
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2019-04-22 17:45:41 +00:00
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2019-01-09 16:11:49 +00:00
|
|
|
timer.Stop();
|
|
|
|
vtkm::Float64 elapsedTime = timer.GetElapsedTime();
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2019-04-22 17:45:41 +00:00
|
|
|
VTKM_TEST_ASSERT(elapsedTime > 0.499, "Timer did not capture full second wait.");
|
|
|
|
VTKM_TEST_ASSERT(elapsedTime < 1.0, "Timer counted too far or system really busy.");
|
2019-01-09 16:11:49 +00:00
|
|
|
}
|
2014-06-10 18:53:34 +00:00
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2017-03-29 14:48:43 +00:00
|
|
|
VTKM_CONT
|
|
|
|
static void TestVirtualObjectTransfer()
|
|
|
|
{
|
2017-10-23 13:38:33 +00:00
|
|
|
using BaseType = typename VirtualObjectTransferKernel::Interface;
|
2017-03-29 14:48:43 +00:00
|
|
|
using TargetType = typename VirtualObjectTransferKernel::Concrete;
|
2017-10-23 13:38:33 +00:00
|
|
|
using Transfer = vtkm::cont::internal::VirtualObjectTransfer<TargetType, DeviceAdapterTag>;
|
2017-03-29 14:48:43 +00:00
|
|
|
|
|
|
|
IdArrayHandle result;
|
|
|
|
result.Allocate(1);
|
2020-01-28 19:14:32 +00:00
|
|
|
result.WritePortal().Set(0, 0);
|
2017-03-29 14:48:43 +00:00
|
|
|
|
|
|
|
TargetType target;
|
|
|
|
target.Value = 5;
|
|
|
|
|
2017-10-23 13:38:33 +00:00
|
|
|
Transfer transfer(&target);
|
2020-01-23 19:12:29 +00:00
|
|
|
const BaseType* base = static_cast<const BaseType*>(transfer.PrepareForExecution(false));
|
2017-03-29 14:48:43 +00:00
|
|
|
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(VirtualObjectTransferKernel(base, result, token), 1);
|
|
|
|
}
|
2020-01-28 19:14:32 +00:00
|
|
|
VTKM_TEST_ASSERT(result.ReadPortal().Get(0) == 5, "Did not get expected result");
|
2017-03-29 14:48:43 +00:00
|
|
|
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
target.Value = 10;
|
2020-01-23 19:12:29 +00:00
|
|
|
base = static_cast<const BaseType*>(transfer.PrepareForExecution(true));
|
2020-01-21 20:18:03 +00:00
|
|
|
Algorithm::Schedule(VirtualObjectTransferKernel(base, result, token), 1);
|
|
|
|
}
|
2020-01-28 19:14:32 +00:00
|
|
|
VTKM_TEST_ASSERT(result.ReadPortal().Get(0) == 10, "Did not get expected result");
|
2017-03-29 14:48:43 +00:00
|
|
|
|
2017-10-23 13:38:33 +00:00
|
|
|
transfer.ReleaseResources();
|
2017-03-29 14:48:43 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestAlgorithmSchedule()
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
{
|
2019-04-22 17:45:41 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> handle;
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(ClearArrayKernel(handle.PrepareForOutput(1, DeviceAdapterTag{}, token)),
|
|
|
|
1);
|
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
2020-03-26 23:34:18 +00:00
|
|
|
Algorithm::Schedule(MakeAddArrayKernel(handle.PrepareForInPlace(DeviceAdapterTag{}, token)),
|
|
|
|
1);
|
2020-01-21 20:18:03 +00:00
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2020-05-08 15:30:59 +00:00
|
|
|
auto portal = handle.ReadPortal();
|
2014-02-11 21:20:30 +00:00
|
|
|
for (vtkm::Id index = 0; index < 1; index++)
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
vtkm::Id value = portal.Get(index);
|
2014-02-11 21:20:30 +00:00
|
|
|
VTKM_TEST_ASSERT(value == index + OFFSET,
|
|
|
|
"Got bad value for single value scheduled kernel.");
|
2014-02-11 17:34:56 +00:00
|
|
|
}
|
|
|
|
} //release memory
|
|
|
|
|
|
|
|
|
|
|
|
{
|
2019-04-22 17:45:41 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> handle;
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(
|
|
|
|
ClearArrayKernel(handle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag{}, token)),
|
|
|
|
ARRAY_SIZE);
|
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
2020-03-26 23:34:18 +00:00
|
|
|
Algorithm::Schedule(MakeAddArrayKernel(handle.PrepareForInPlace(DeviceAdapterTag{}, token)),
|
2020-01-21 20:18:03 +00:00
|
|
|
ARRAY_SIZE);
|
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2020-05-08 15:30:59 +00:00
|
|
|
auto portal = handle.ReadPortal();
|
2014-02-11 21:20:30 +00:00
|
|
|
for (vtkm::Id index = 0; index < ARRAY_SIZE; index++)
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
vtkm::Id value = portal.Get(index);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(value == index + OFFSET, "Got bad value for scheduled kernels.");
|
2014-02-11 17:34:56 +00:00
|
|
|
}
|
|
|
|
} //release memory
|
|
|
|
|
2015-07-22 14:03:48 +00:00
|
|
|
{
|
2019-04-22 17:45:41 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> handle;
|
2015-07-22 14:03:48 +00:00
|
|
|
|
|
|
|
//size is selected to be larger than the CUDA backend can launch in a
|
|
|
|
//single invocation when compiled for SM_2 support
|
|
|
|
const vtkm::Id size = 8400000;
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(
|
|
|
|
ClearArrayKernel(handle.PrepareForOutput(size, DeviceAdapterTag{}, token)), size);
|
|
|
|
}
|
2015-07-22 14:03:48 +00:00
|
|
|
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
2020-03-26 23:34:18 +00:00
|
|
|
Algorithm::Schedule(MakeAddArrayKernel(handle.PrepareForInPlace(DeviceAdapterTag{}, token)),
|
2020-01-21 20:18:03 +00:00
|
|
|
size);
|
|
|
|
}
|
2015-07-22 14:03:48 +00:00
|
|
|
|
2018-05-29 21:09:20 +00:00
|
|
|
//Rather than testing for correctness every value of a large array,
|
|
|
|
// we randomly test a subset of that array.
|
|
|
|
std::default_random_engine generator(static_cast<unsigned int>(std::time(nullptr)));
|
|
|
|
std::uniform_int_distribution<vtkm::Id> distribution(0, size - 1);
|
|
|
|
vtkm::Id numberOfSamples = size / 100;
|
2020-05-08 15:30:59 +00:00
|
|
|
auto portal = handle.ReadPortal();
|
2018-05-29 21:09:20 +00:00
|
|
|
for (vtkm::Id i = 0; i < numberOfSamples; ++i)
|
2015-07-22 14:03:48 +00:00
|
|
|
{
|
2018-05-29 21:09:20 +00:00
|
|
|
vtkm::Id randomIndex = distribution(generator);
|
2020-05-08 15:30:59 +00:00
|
|
|
vtkm::Id value = portal.Get(randomIndex);
|
2018-05-29 21:09:20 +00:00
|
|
|
VTKM_TEST_ASSERT(value == randomIndex + OFFSET, "Got bad value for scheduled kernels.");
|
2015-07-22 14:03:48 +00:00
|
|
|
}
|
|
|
|
} //release memory
|
|
|
|
|
2014-02-11 17:34:56 +00:00
|
|
|
//verify that the schedule call works with id3
|
|
|
|
{
|
2019-04-22 17:45:41 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> handle;
|
2014-02-11 21:20:30 +00:00
|
|
|
vtkm::Id3 maxRange(DIM_SIZE);
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(
|
|
|
|
ClearArrayKernel(
|
|
|
|
handle.PrepareForOutput(DIM_SIZE * DIM_SIZE * DIM_SIZE, DeviceAdapterTag{}, token),
|
|
|
|
maxRange),
|
|
|
|
maxRange);
|
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(
|
2020-03-26 23:34:18 +00:00
|
|
|
MakeAddArrayKernel(handle.PrepareForInPlace(DeviceAdapterTag{}, token), maxRange),
|
|
|
|
maxRange);
|
2020-01-21 20:18:03 +00:00
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2014-02-11 21:20:30 +00:00
|
|
|
const vtkm::Id maxId = DIM_SIZE * DIM_SIZE * DIM_SIZE;
|
2020-05-08 15:30:59 +00:00
|
|
|
auto portal = handle.ReadPortal();
|
2014-02-11 21:20:30 +00:00
|
|
|
for (vtkm::Id index = 0; index < maxId; index++)
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
vtkm::Id value = portal.Get(index);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(value == index + OFFSET, "Got bad value for scheduled vtkm::Id3 kernels.");
|
2014-02-11 17:34:56 +00:00
|
|
|
}
|
|
|
|
} //release memory
|
2018-07-03 20:28:29 +00:00
|
|
|
|
|
|
|
// Ensure that each element is only visited once:
|
|
|
|
{
|
|
|
|
using BoolArray = ArrayHandle<bool>;
|
2021-02-01 15:03:11 +00:00
|
|
|
using BoolPortal = typename BoolArray::WritePortalType;
|
2018-07-03 20:28:29 +00:00
|
|
|
BoolArray tracker;
|
|
|
|
BoolArray valid;
|
|
|
|
|
|
|
|
// Initialize tracker with 'false' values
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(
|
|
|
|
GenericClearArrayKernel<BoolPortal>(
|
|
|
|
tracker.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag(), token), false),
|
|
|
|
ARRAY_SIZE);
|
|
|
|
Algorithm::Schedule(GenericClearArrayKernel<BoolPortal>(
|
|
|
|
valid.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag(), token), false),
|
|
|
|
ARRAY_SIZE);
|
|
|
|
}
|
2018-07-03 20:28:29 +00:00
|
|
|
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(OverlapKernel(tracker.PrepareForInPlace(DeviceAdapterTag(), token),
|
|
|
|
valid.PrepareForInPlace(DeviceAdapterTag(), token)),
|
|
|
|
ARRAY_SIZE);
|
|
|
|
}
|
2018-07-03 20:28:29 +00:00
|
|
|
|
2020-01-28 19:14:32 +00:00
|
|
|
auto vPortal = valid.ReadPortal();
|
2018-07-03 20:28:29 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; i++)
|
|
|
|
{
|
|
|
|
bool isValid = vPortal.Get(i);
|
|
|
|
VTKM_TEST_ASSERT(isValid, "Schedule executed some elements more than once.");
|
|
|
|
}
|
|
|
|
} // release memory
|
|
|
|
|
|
|
|
// Ensure that each element is only visited once:
|
|
|
|
|
|
|
|
{
|
|
|
|
static constexpr vtkm::Id numElems{ DIM_SIZE * DIM_SIZE * DIM_SIZE };
|
|
|
|
static const vtkm::Id3 dims{ DIM_SIZE, DIM_SIZE, DIM_SIZE };
|
|
|
|
|
|
|
|
using BoolArray = ArrayHandle<bool>;
|
2021-02-01 15:03:11 +00:00
|
|
|
using BoolPortal = typename BoolArray::WritePortalType;
|
2018-07-03 20:28:29 +00:00
|
|
|
BoolArray tracker;
|
|
|
|
BoolArray valid;
|
|
|
|
|
|
|
|
// Initialize tracker with 'false' values
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(
|
|
|
|
GenericClearArrayKernel<BoolPortal>(
|
|
|
|
tracker.PrepareForOutput(numElems, DeviceAdapterTag(), token), dims, false),
|
|
|
|
numElems);
|
|
|
|
Algorithm::Schedule(
|
|
|
|
GenericClearArrayKernel<BoolPortal>(
|
|
|
|
valid.PrepareForOutput(numElems, DeviceAdapterTag(), token), dims, false),
|
|
|
|
numElems);
|
|
|
|
}
|
2018-07-03 20:28:29 +00:00
|
|
|
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(OverlapKernel(tracker.PrepareForInPlace(DeviceAdapterTag(), token),
|
|
|
|
valid.PrepareForInPlace(DeviceAdapterTag(), token),
|
|
|
|
dims),
|
|
|
|
dims);
|
|
|
|
}
|
2018-07-03 20:28:29 +00:00
|
|
|
|
2020-01-28 19:14:32 +00:00
|
|
|
auto vPortal = valid.ReadPortal();
|
2018-07-03 20:28:29 +00:00
|
|
|
for (vtkm::Id i = 0; i < numElems; i++)
|
|
|
|
{
|
|
|
|
bool isValid = vPortal.Get(i);
|
|
|
|
VTKM_TEST_ASSERT(isValid, "Id3 Schedule executed some elements more than once.");
|
|
|
|
}
|
|
|
|
} // release memory
|
2014-02-11 17:34:56 +00:00
|
|
|
}
|
|
|
|
|
2017-03-03 22:17:43 +00:00
|
|
|
static VTKM_CONT void TestCopyIf()
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
|
|
|
IdArrayHandle array;
|
|
|
|
IdArrayHandle stencil;
|
|
|
|
IdArrayHandle result;
|
|
|
|
|
|
|
|
//construct the index array
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(
|
|
|
|
OffsetPlusIndexKernel(array.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag(), token)),
|
|
|
|
ARRAY_SIZE);
|
|
|
|
Algorithm::Schedule(
|
|
|
|
MarkOddNumbersKernel(stencil.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag(), token)),
|
|
|
|
ARRAY_SIZE);
|
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
Algorithm::CopyIf(array, stencil, result);
|
|
|
|
VTKM_TEST_ASSERT(result.GetNumberOfValues() == array.GetNumberOfValues() / 2,
|
2017-03-03 22:17:43 +00:00
|
|
|
"result of CopyIf has an incorrect size");
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2020-05-08 15:30:59 +00:00
|
|
|
auto portal = result.ReadPortal();
|
2014-02-11 17:34:56 +00:00
|
|
|
for (vtkm::Id index = 0; index < result.GetNumberOfValues(); index++)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
const vtkm::Id value = portal.Get(index);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(value == (OFFSET + (index * 2) + 1), "Incorrect value in CopyIf result.");
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2017-03-09 00:05:28 +00:00
|
|
|
|
2020-04-16 20:18:34 +00:00
|
|
|
result.Allocate(0);
|
|
|
|
FloatCastHandle arrayCast(array);
|
|
|
|
FloatCastHandle resultCast(result);
|
|
|
|
|
|
|
|
Algorithm::CopyIf(arrayCast, stencil, resultCast);
|
|
|
|
VTKM_TEST_ASSERT(result.GetNumberOfValues() == array.GetNumberOfValues() / 2,
|
|
|
|
"result of CopyIf has an incorrect size");
|
|
|
|
|
2020-05-08 15:30:59 +00:00
|
|
|
portal = result.ReadPortal();
|
2020-04-16 20:18:34 +00:00
|
|
|
for (vtkm::Id index = 0; index < result.GetNumberOfValues(); index++)
|
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
const vtkm::Id value = portal.Get(index);
|
2020-04-16 20:18:34 +00:00
|
|
|
VTKM_TEST_ASSERT(value == (OFFSET + (index * 2) + 1), "Incorrect value in CopyIf result.");
|
|
|
|
}
|
|
|
|
|
2021-01-28 21:59:40 +00:00
|
|
|
array.ReleaseResources();
|
|
|
|
stencil.ReleaseResources();
|
2017-03-09 00:05:28 +00:00
|
|
|
Algorithm::CopyIf(array, stencil, result);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(result.GetNumberOfValues() == 0, "result of CopyIf has an incorrect size");
|
2014-02-11 17:34:56 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestOrderedUniqueValues()
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
2017-01-03 20:37:41 +00:00
|
|
|
std::vector<vtkm::Id> testData(ARRAY_SIZE);
|
2017-05-18 14:29:41 +00:00
|
|
|
for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
testData[i] = static_cast<vtkm::Id>(OFFSET + (i % 50));
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2015-06-05 14:32:48 +00:00
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
IdArrayHandle input = vtkm::cont::make_ArrayHandle(testData, vtkm::CopyFlag::Off);
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2015-06-05 14:32:48 +00:00
|
|
|
//make a deep copy of input and place it into temp
|
2014-02-11 17:34:56 +00:00
|
|
|
IdArrayHandle temp;
|
2017-05-18 14:29:41 +00:00
|
|
|
Algorithm::Copy(input, temp);
|
2015-06-05 14:32:48 +00:00
|
|
|
|
2014-02-11 17:34:56 +00:00
|
|
|
Algorithm::Sort(temp);
|
|
|
|
Algorithm::Unique(temp);
|
|
|
|
|
2015-06-05 14:32:48 +00:00
|
|
|
IdArrayHandle handle;
|
|
|
|
IdArrayHandle handle1;
|
|
|
|
|
2014-02-11 17:34:56 +00:00
|
|
|
//verify lower and upper bounds work
|
2017-05-18 14:29:41 +00:00
|
|
|
Algorithm::LowerBounds(temp, input, handle);
|
|
|
|
Algorithm::UpperBounds(temp, input, handle1);
|
2014-02-11 17:34:56 +00:00
|
|
|
|
|
|
|
// Check to make sure that temp was resized correctly during Unique.
|
|
|
|
// (This was a discovered bug at one point.)
|
2020-01-28 19:14:32 +00:00
|
|
|
temp.ReadPortal(); // Forces copy back to control.
|
2014-02-11 17:34:56 +00:00
|
|
|
temp.ReleaseResourcesExecution(); // Make sure not counting on execution.
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(temp.GetNumberOfValues() == 50,
|
|
|
|
"Unique did not resize array (or size did not copy to control).");
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2020-05-08 15:30:59 +00:00
|
|
|
auto portal = handle.ReadPortal();
|
|
|
|
auto portal1 = handle1.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
vtkm::Id value = portal.Get(i);
|
|
|
|
vtkm::Id value1 = portal1.Get(i);
|
2014-02-11 17:34:56 +00:00
|
|
|
VTKM_TEST_ASSERT(value == i % 50, "Got bad value (LowerBounds)");
|
|
|
|
VTKM_TEST_ASSERT(value1 >= i % 50, "Got bad value (UpperBounds)");
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
|
|
|
//now test it works when the id are not incrementing
|
|
|
|
const vtkm::Id RANDOMDATA_SIZE = 6;
|
|
|
|
vtkm::Id randomData[RANDOMDATA_SIZE];
|
2017-05-18 14:29:41 +00:00
|
|
|
randomData[0] = 500; // 2 (lower), 3 (upper)
|
|
|
|
randomData[1] = 955; // 3 (lower), 4 (upper)
|
|
|
|
randomData[2] = 955; // 3 (lower), 4 (upper)
|
|
|
|
randomData[3] = 120; // 0 (lower), 1 (upper)
|
|
|
|
randomData[4] = 320; // 1 (lower), 2 (upper)
|
|
|
|
randomData[5] = 955; // 3 (lower), 4 (upper)
|
2014-02-11 17:34:56 +00:00
|
|
|
|
|
|
|
//change the control structure under the handle
|
2020-07-16 16:32:32 +00:00
|
|
|
input = vtkm::cont::make_ArrayHandle(randomData, RANDOMDATA_SIZE, vtkm::CopyFlag::Off);
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2020-04-16 20:18:34 +00:00
|
|
|
FloatCastHandle tempCast(temp);
|
|
|
|
Algorithm::Copy(input, tempCast);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(temp.GetNumberOfValues() == RANDOMDATA_SIZE, "Copy failed");
|
2020-04-16 20:18:34 +00:00
|
|
|
Algorithm::Sort(tempCast);
|
|
|
|
Algorithm::Unique(tempCast);
|
|
|
|
Algorithm::LowerBounds(tempCast, FloatCastHandle(input), handle);
|
|
|
|
Algorithm::UpperBounds(tempCast, FloatCastHandle(input), handle1);
|
2014-02-11 17:34:56 +00:00
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(handle.GetNumberOfValues() == RANDOMDATA_SIZE,
|
2014-02-11 21:20:30 +00:00
|
|
|
"LowerBounds returned incorrect size");
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2020-01-28 19:14:32 +00:00
|
|
|
std::copy(vtkm::cont::ArrayPortalToIteratorBegin(handle.ReadPortal()),
|
|
|
|
vtkm::cont::ArrayPortalToIteratorEnd(handle.ReadPortal()),
|
2017-05-26 17:53:28 +00:00
|
|
|
randomData);
|
2014-02-11 17:34:56 +00:00
|
|
|
VTKM_TEST_ASSERT(randomData[0] == 2, "Got bad value - LowerBounds");
|
|
|
|
VTKM_TEST_ASSERT(randomData[1] == 3, "Got bad value - LowerBounds");
|
|
|
|
VTKM_TEST_ASSERT(randomData[2] == 3, "Got bad value - LowerBounds");
|
|
|
|
VTKM_TEST_ASSERT(randomData[3] == 0, "Got bad value - LowerBounds");
|
|
|
|
VTKM_TEST_ASSERT(randomData[4] == 1, "Got bad value - LowerBounds");
|
|
|
|
VTKM_TEST_ASSERT(randomData[5] == 3, "Got bad value - LowerBounds");
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(handle1.GetNumberOfValues() == RANDOMDATA_SIZE,
|
2014-02-11 21:20:30 +00:00
|
|
|
"UppererBounds returned incorrect size");
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2020-01-28 19:14:32 +00:00
|
|
|
std::copy(vtkm::cont::ArrayPortalToIteratorBegin(handle1.ReadPortal()),
|
|
|
|
vtkm::cont::ArrayPortalToIteratorEnd(handle1.ReadPortal()),
|
2017-05-26 17:53:28 +00:00
|
|
|
randomData);
|
2014-02-11 17:34:56 +00:00
|
|
|
VTKM_TEST_ASSERT(randomData[0] == 3, "Got bad value - UpperBound");
|
|
|
|
VTKM_TEST_ASSERT(randomData[1] == 4, "Got bad value - UpperBound");
|
|
|
|
VTKM_TEST_ASSERT(randomData[2] == 4, "Got bad value - UpperBound");
|
|
|
|
VTKM_TEST_ASSERT(randomData[3] == 1, "Got bad value - UpperBound");
|
|
|
|
VTKM_TEST_ASSERT(randomData[4] == 2, "Got bad value - UpperBound");
|
|
|
|
VTKM_TEST_ASSERT(randomData[5] == 4, "Got bad value - UpperBound");
|
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestSort()
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
2017-01-03 20:37:41 +00:00
|
|
|
std::vector<vtkm::Id> testData(ARRAY_SIZE);
|
2017-05-18 14:29:41 +00:00
|
|
|
for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
testData[i] = static_cast<vtkm::Id>(OFFSET + ((ARRAY_SIZE - i) % 50));
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2015-06-10 13:08:08 +00:00
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
IdArrayHandle unsorted = vtkm::cont::make_ArrayHandle(testData, vtkm::CopyFlag::Off);
|
2015-06-10 13:08:08 +00:00
|
|
|
IdArrayHandle sorted;
|
|
|
|
Algorithm::Copy(unsorted, sorted);
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2015-06-05 14:32:48 +00:00
|
|
|
//Validate the standard inplace sort is correct
|
2014-02-11 17:34:56 +00:00
|
|
|
Algorithm::Sort(sorted);
|
|
|
|
|
2020-05-08 15:30:59 +00:00
|
|
|
auto portal = sorted.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE - 1; ++i)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
vtkm::Id sorted1 = portal.Get(i);
|
|
|
|
vtkm::Id sorted2 = portal.Get(i + 1);
|
2014-02-11 17:34:56 +00:00
|
|
|
VTKM_TEST_ASSERT(sorted1 <= sorted2, "Values not properly sorted.");
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2017-03-09 00:05:28 +00:00
|
|
|
|
|
|
|
//Try zero sized array
|
2021-01-28 21:59:40 +00:00
|
|
|
sorted.Allocate(0);
|
2017-03-09 00:05:28 +00:00
|
|
|
Algorithm::Sort(sorted);
|
2015-04-16 14:25:44 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestSortWithComparisonObject()
|
2015-06-18 19:40:51 +00:00
|
|
|
{
|
2017-01-03 20:37:41 +00:00
|
|
|
std::vector<vtkm::Id> testData(ARRAY_SIZE);
|
2017-05-18 14:29:41 +00:00
|
|
|
for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
|
2015-04-16 14:25:44 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
testData[i] = static_cast<vtkm::Id>(OFFSET + ((ARRAY_SIZE - i) % 50));
|
2015-04-16 14:25:44 +00:00
|
|
|
}
|
|
|
|
|
2015-06-05 14:32:48 +00:00
|
|
|
//sort the users memory in-place
|
2020-07-16 16:32:32 +00:00
|
|
|
IdArrayHandle sorted = vtkm::cont::make_ArrayHandle(testData, vtkm::CopyFlag::Off);
|
2015-04-16 14:25:44 +00:00
|
|
|
Algorithm::Sort(sorted);
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2015-06-05 14:32:48 +00:00
|
|
|
//copy the sorted array into our own memory, if use the same user ptr
|
|
|
|
//we would also sort the 'sorted' handle
|
|
|
|
IdArrayHandle comp_sorted;
|
|
|
|
Algorithm::Copy(sorted, comp_sorted);
|
2017-05-18 14:29:41 +00:00
|
|
|
Algorithm::Sort(comp_sorted, vtkm::SortGreater());
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2015-06-05 14:32:48 +00:00
|
|
|
//Validate that sorted and comp_sorted are sorted in the opposite directions
|
2020-05-08 15:30:59 +00:00
|
|
|
auto sorted_portal = sorted.ReadPortal();
|
|
|
|
auto comp_sorted_portal = comp_sorted.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
vtkm::Id sorted1 = sorted_portal.Get(i);
|
|
|
|
vtkm::Id sorted2 = comp_sorted_portal.Get(ARRAY_SIZE - (i + 1));
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(sorted1 == sorted2, "Got bad sort values when using SortGreater");
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2015-06-05 14:32:48 +00:00
|
|
|
//validate that sorted and comp_sorted are now equal
|
2017-05-18 14:29:41 +00:00
|
|
|
Algorithm::Sort(comp_sorted, vtkm::SortLess());
|
2020-05-08 15:30:59 +00:00
|
|
|
comp_sorted_portal = comp_sorted.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
vtkm::Id sorted1 = sorted_portal.Get(i);
|
|
|
|
vtkm::Id sorted2 = comp_sorted_portal.Get(i);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(sorted1 == sorted2, "Got bad sort values when using SortLess");
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestSortWithFancyArrays()
|
2015-06-18 19:40:51 +00:00
|
|
|
{
|
2017-01-03 20:37:41 +00:00
|
|
|
std::vector<vtkm::Id> testData(ARRAY_SIZE);
|
2017-05-18 14:29:41 +00:00
|
|
|
for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
|
2015-06-18 19:40:51 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
testData[i] = static_cast<vtkm::Id>(OFFSET + ((ARRAY_SIZE - i) % 50));
|
2015-06-18 19:40:51 +00:00
|
|
|
}
|
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
IdArrayHandle unsorted = vtkm::cont::make_ArrayHandle(testData, vtkm::CopyFlag::Off);
|
2015-06-18 19:40:51 +00:00
|
|
|
IdArrayHandle sorted;
|
|
|
|
Algorithm::Copy(unsorted, sorted);
|
|
|
|
|
|
|
|
//verify that we can use ArrayHandleZip inplace
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::ArrayHandleZip<IdArrayHandle, IdArrayHandle> zipped(unsorted, sorted);
|
2015-06-18 19:40:51 +00:00
|
|
|
|
|
|
|
//verify we can use sort with zip handle
|
2015-07-20 21:01:13 +00:00
|
|
|
Algorithm::Sort(zipped, vtkm::SortGreater());
|
2015-06-18 19:40:51 +00:00
|
|
|
Algorithm::Sort(zipped);
|
|
|
|
|
2020-05-08 15:30:59 +00:00
|
|
|
auto portal = zipped.ReadPortal();
|
2015-06-18 19:40:51 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
|
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
vtkm::Pair<vtkm::Id, vtkm::Id> kv_sorted = portal.Get(i);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT((OFFSET + (i / (ARRAY_SIZE / 50))) == kv_sorted.first,
|
2015-06-18 19:40:51 +00:00
|
|
|
"ArrayZipHandle improperly sorted");
|
|
|
|
}
|
|
|
|
|
|
|
|
//verify that we can use ArrayHandlePermutation inplace
|
2015-09-15 04:11:09 +00:00
|
|
|
vtkm::cont::ArrayHandleIndex index(ARRAY_SIZE);
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::ArrayHandlePermutation<vtkm::cont::ArrayHandleIndex, IdArrayHandle> perm(index,
|
|
|
|
sorted);
|
2015-06-18 19:40:51 +00:00
|
|
|
|
|
|
|
//verify we can use a custom operator sort with permutation handle
|
2015-07-20 21:01:13 +00:00
|
|
|
Algorithm::Sort(perm, vtkm::SortGreater());
|
2020-05-08 15:30:59 +00:00
|
|
|
auto perm_portal = perm.ReadPortal();
|
2015-06-18 19:40:51 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
|
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
vtkm::Id sorted_value = perm_portal.Get(i);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT((OFFSET + ((ARRAY_SIZE - (i + 1)) / (ARRAY_SIZE / 50))) == sorted_value,
|
2015-06-18 19:40:51 +00:00
|
|
|
"ArrayZipPermutation improperly sorted");
|
|
|
|
}
|
|
|
|
|
|
|
|
//verify we can use the default sort with permutation handle
|
|
|
|
Algorithm::Sort(perm);
|
2020-05-08 15:30:59 +00:00
|
|
|
perm_portal = perm.ReadPortal();
|
2015-06-18 19:40:51 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
|
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
vtkm::Id sorted_value = perm_portal.Get(i);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT((OFFSET + (i / (ARRAY_SIZE / 50))) == sorted_value,
|
2015-06-18 19:40:51 +00:00
|
|
|
"ArrayZipPermutation improperly sorted");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestSortByKey()
|
2015-04-23 17:25:37 +00:00
|
|
|
{
|
2017-08-16 15:34:21 +00:00
|
|
|
using Vec3 = vtkm::Vec<FloatDefault, 3>;
|
2019-07-31 16:20:38 +00:00
|
|
|
using Vec3ArrayHandle = vtkm::cont::ArrayHandle<vtkm::Vec3f, StorageTag>;
|
2015-05-18 00:29:35 +00:00
|
|
|
|
2017-01-03 20:37:41 +00:00
|
|
|
std::vector<vtkm::Id> testKeys(ARRAY_SIZE);
|
|
|
|
std::vector<Vec3> testValues(testKeys.size());
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
|
|
|
|
{
|
2017-01-03 20:37:41 +00:00
|
|
|
std::size_t index = static_cast<size_t>(i);
|
|
|
|
testKeys[index] = ARRAY_SIZE - i;
|
|
|
|
testValues[index] = TestValue(i, Vec3());
|
2017-05-18 14:29:41 +00:00
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
IdArrayHandle keys = vtkm::cont::make_ArrayHandle(testKeys, vtkm::CopyFlag::Off);
|
|
|
|
Vec3ArrayHandle values = vtkm::cont::make_ArrayHandle(testValues, vtkm::CopyFlag::Off);
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
Algorithm::SortByKey(keys, values);
|
2015-06-10 13:08:08 +00:00
|
|
|
|
2020-05-08 15:30:59 +00:00
|
|
|
auto values_portal = values.ReadPortal();
|
|
|
|
auto keys_portal = keys.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
|
|
|
|
{
|
2015-04-23 17:25:37 +00:00
|
|
|
//keys should be sorted from 1 to ARRAY_SIZE
|
|
|
|
//values should be sorted from (ARRAY_SIZE-1) to 0
|
2020-05-08 15:30:59 +00:00
|
|
|
Vec3 sorted_value = values_portal.Get(i);
|
|
|
|
vtkm::Id sorted_key = keys_portal.Get(i);
|
2015-04-23 17:25:37 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT((sorted_key == (i + 1)), "Got bad SortByKeys key");
|
|
|
|
VTKM_TEST_ASSERT(test_equal(sorted_value, TestValue(ARRAY_SIZE - 1 - i, Vec3())),
|
|
|
|
"Got bad SortByKeys value");
|
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2015-04-23 17:25:37 +00:00
|
|
|
// this will return everything back to what it was before sorting
|
2017-05-18 14:29:41 +00:00
|
|
|
Algorithm::SortByKey(keys, values, vtkm::SortGreater());
|
2020-05-08 15:30:59 +00:00
|
|
|
values_portal = values.ReadPortal();
|
|
|
|
keys_portal = keys.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
|
|
|
|
{
|
2015-04-23 17:25:37 +00:00
|
|
|
//keys should be sorted from ARRAY_SIZE to 1
|
|
|
|
//values should be sorted from 0 to (ARRAY_SIZE-1)
|
2020-05-08 15:30:59 +00:00
|
|
|
Vec3 sorted_value = values_portal.Get(i);
|
|
|
|
vtkm::Id sorted_key = keys_portal.Get(i);
|
2015-04-23 17:25:37 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT((sorted_key == (ARRAY_SIZE - i)), "Got bad SortByKeys key");
|
|
|
|
VTKM_TEST_ASSERT(test_equal(sorted_value, TestValue(i, Vec3())), "Got bad SortByKeys value");
|
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2015-05-18 00:29:35 +00:00
|
|
|
//this is here to verify we can sort by vtkm::Vec
|
2017-05-18 14:29:41 +00:00
|
|
|
Algorithm::SortByKey(values, keys);
|
2020-05-08 15:30:59 +00:00
|
|
|
values_portal = values.ReadPortal();
|
|
|
|
keys_portal = keys.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
|
|
|
|
{
|
2015-04-23 17:25:37 +00:00
|
|
|
//keys should be sorted from ARRAY_SIZE to 1
|
|
|
|
//values should be sorted from 0 to (ARRAY_SIZE-1)
|
2020-05-08 15:30:59 +00:00
|
|
|
Vec3 sorted_value = values_portal.Get(i);
|
|
|
|
vtkm::Id sorted_key = keys_portal.Get(i);
|
2015-04-23 17:25:37 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT((sorted_key == (ARRAY_SIZE - i)), "Got bad SortByKeys key");
|
|
|
|
VTKM_TEST_ASSERT(test_equal(sorted_value, TestValue(i, Vec3())), "Got bad SortByKeys value");
|
|
|
|
}
|
2015-04-23 17:25:37 +00:00
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestLowerBoundsWithComparisonObject()
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
2017-01-03 20:37:41 +00:00
|
|
|
std::vector<vtkm::Id> testData(ARRAY_SIZE);
|
2017-05-18 14:29:41 +00:00
|
|
|
for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
testData[i] = static_cast<vtkm::Id>(OFFSET + (i % 50));
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2020-07-16 16:32:32 +00:00
|
|
|
IdArrayHandle input = vtkm::cont::make_ArrayHandle(testData, vtkm::CopyFlag::Off);
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2015-06-05 14:32:48 +00:00
|
|
|
//make a deep copy of input and place it into temp
|
2014-02-11 17:34:56 +00:00
|
|
|
IdArrayHandle temp;
|
2017-05-18 14:29:41 +00:00
|
|
|
Algorithm::Copy(input, temp);
|
2015-06-05 14:32:48 +00:00
|
|
|
|
2014-02-11 17:34:56 +00:00
|
|
|
Algorithm::Sort(temp);
|
|
|
|
Algorithm::Unique(temp);
|
|
|
|
|
|
|
|
IdArrayHandle handle;
|
|
|
|
//verify lower bounds work
|
2017-05-18 14:29:41 +00:00
|
|
|
Algorithm::LowerBounds(temp, input, handle, vtkm::SortLess());
|
2014-02-11 17:34:56 +00:00
|
|
|
|
|
|
|
// Check to make sure that temp was resized correctly during Unique.
|
|
|
|
// (This was a discovered bug at one point.)
|
2020-01-28 19:14:32 +00:00
|
|
|
temp.ReadPortal(); // Forces copy back to control.
|
2014-02-11 17:34:56 +00:00
|
|
|
temp.ReleaseResourcesExecution(); // Make sure not counting on execution.
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(temp.GetNumberOfValues() == 50,
|
|
|
|
"Unique did not resize array (or size did not copy to control).");
|
2020-05-08 15:30:59 +00:00
|
|
|
auto portal = handle.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
vtkm::Id value = portal.Get(i);
|
2014-02-11 17:34:56 +00:00
|
|
|
VTKM_TEST_ASSERT(value == i % 50, "Got bad LowerBounds value with SortLess");
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestUpperBoundsWithComparisonObject()
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
2017-01-03 20:37:41 +00:00
|
|
|
std::vector<vtkm::Id> testData(ARRAY_SIZE);
|
2017-05-18 14:29:41 +00:00
|
|
|
for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
testData[i] = static_cast<vtkm::Id>(OFFSET + (i % 50));
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2020-07-16 16:32:32 +00:00
|
|
|
IdArrayHandle input = vtkm::cont::make_ArrayHandle(testData, vtkm::CopyFlag::Off);
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2015-06-05 14:32:48 +00:00
|
|
|
//make a deep copy of input and place it into temp
|
2014-02-11 17:34:56 +00:00
|
|
|
IdArrayHandle temp;
|
2017-05-18 14:29:41 +00:00
|
|
|
Algorithm::Copy(input, temp);
|
2015-06-05 14:32:48 +00:00
|
|
|
|
2014-02-11 17:34:56 +00:00
|
|
|
Algorithm::Sort(temp);
|
|
|
|
Algorithm::Unique(temp);
|
|
|
|
|
|
|
|
IdArrayHandle handle;
|
|
|
|
//verify upper bounds work
|
2017-05-18 14:29:41 +00:00
|
|
|
Algorithm::UpperBounds(temp, input, handle, vtkm::SortLess());
|
2014-02-11 17:34:56 +00:00
|
|
|
|
|
|
|
// Check to make sure that temp was resized correctly during Unique.
|
|
|
|
// (This was a discovered bug at one point.)
|
2020-01-28 19:14:32 +00:00
|
|
|
temp.ReadPortal(); // Forces copy back to control.
|
2014-02-11 17:34:56 +00:00
|
|
|
temp.ReleaseResourcesExecution(); // Make sure not counting on execution.
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(temp.GetNumberOfValues() == 50,
|
|
|
|
"Unique did not resize array (or size did not copy to control).");
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2020-05-08 15:30:59 +00:00
|
|
|
auto portal = handle.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
vtkm::Id value = portal.Get(i);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(value == (i % 50) + 1, "Got bad UpperBounds value with SortLess");
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestUniqueWithComparisonObject()
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
2020-06-24 23:27:36 +00:00
|
|
|
IdArrayHandle input;
|
|
|
|
input.Allocate(ARRAY_SIZE);
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2020-06-24 23:27:36 +00:00
|
|
|
auto portal = input.WritePortal();
|
|
|
|
for (vtkm::Id index = 0; index < ARRAY_SIZE; ++index)
|
|
|
|
{
|
|
|
|
portal.Set(index, OFFSET + (index % 50));
|
|
|
|
}
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2020-06-24 23:27:36 +00:00
|
|
|
|
2015-06-05 14:32:48 +00:00
|
|
|
Algorithm::Sort(input);
|
|
|
|
Algorithm::Unique(input, FuseAll());
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2015-06-05 14:32:48 +00:00
|
|
|
// Check to make sure that input was resized correctly during Unique.
|
2014-02-11 17:34:56 +00:00
|
|
|
// (This was a discovered bug at one point.)
|
2020-06-24 23:27:36 +00:00
|
|
|
input.SyncControlArray(); // Forces copy back to control.
|
2015-06-05 14:32:48 +00:00
|
|
|
input.ReleaseResourcesExecution(); // Make sure not counting on execution.
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(input.GetNumberOfValues() == 1,
|
|
|
|
"Unique did not resize array (or size did not copy to control).");
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2020-01-28 19:14:32 +00:00
|
|
|
vtkm::Id value = input.ReadPortal().Get(0);
|
2014-02-11 17:34:56 +00:00
|
|
|
VTKM_TEST_ASSERT(value == OFFSET, "Got bad unique value");
|
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestReduce()
|
2015-04-28 13:31:50 +00:00
|
|
|
{
|
|
|
|
//construct the index array
|
|
|
|
IdArrayHandle array;
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(
|
|
|
|
ClearArrayKernel(array.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag(), token)),
|
|
|
|
ARRAY_SIZE);
|
|
|
|
}
|
2015-04-28 13:31:50 +00:00
|
|
|
|
|
|
|
//the output of reduce and scan inclusive should be the same
|
2021-03-02 20:08:51 +00:00
|
|
|
vtkm::Id reduce_sum = Algorithm::Reduce(array, 0);
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Id reduce_sum_with_intial_value = Algorithm::Reduce(array, vtkm::Id(ARRAY_SIZE));
|
2015-04-28 13:31:50 +00:00
|
|
|
vtkm::Id inclusive_sum = Algorithm::ScanInclusive(array, array);
|
2021-01-28 21:59:40 +00:00
|
|
|
array.Allocate(1, vtkm::CopyFlag::On);
|
2021-03-02 20:08:51 +00:00
|
|
|
vtkm::Id reduce_sum_one_value = Algorithm::Reduce(array, 0);
|
2021-01-28 21:59:40 +00:00
|
|
|
array.Allocate(0);
|
2021-03-02 20:08:51 +00:00
|
|
|
vtkm::Id reduce_sum_no_values = Algorithm::Reduce(array, 0);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(reduce_sum == OFFSET * ARRAY_SIZE, "Got bad sum from Reduce");
|
2015-04-28 13:31:50 +00:00
|
|
|
VTKM_TEST_ASSERT(reduce_sum_with_intial_value == reduce_sum + ARRAY_SIZE,
|
|
|
|
"Got bad sum from Reduce with initial value");
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(reduce_sum_one_value == OFFSET, "Got bad single sum from Reduce");
|
|
|
|
VTKM_TEST_ASSERT(reduce_sum_no_values == 0, "Got bad empty sum from Reduce");
|
2015-04-28 13:31:50 +00:00
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(reduce_sum == inclusive_sum,
|
|
|
|
"Got different sums from Reduce and ScanInclusive");
|
2015-06-18 19:40:51 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestReduceWithComparisonObject()
|
2015-06-18 19:40:51 +00:00
|
|
|
{
|
|
|
|
//construct the index array. Assign an abnormally large value
|
|
|
|
//to the middle of the array, that should be what we see as our sum.
|
2017-01-03 20:37:41 +00:00
|
|
|
std::vector<vtkm::Id> testData(ARRAY_SIZE);
|
2017-05-18 14:29:41 +00:00
|
|
|
const vtkm::Id maxValue = ARRAY_SIZE * 2;
|
|
|
|
for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
|
2015-06-18 19:40:51 +00:00
|
|
|
{
|
2017-01-03 20:37:41 +00:00
|
|
|
vtkm::Id index = static_cast<vtkm::Id>(i);
|
2017-05-18 14:29:41 +00:00
|
|
|
testData[i] = index;
|
2015-06-11 19:23:29 +00:00
|
|
|
}
|
2017-05-18 14:29:41 +00:00
|
|
|
testData[ARRAY_SIZE / 2] = maxValue;
|
2015-06-11 19:23:29 +00:00
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
IdArrayHandle input = vtkm::cont::make_ArrayHandle(testData, vtkm::CopyFlag::Off);
|
2019-07-31 16:20:38 +00:00
|
|
|
vtkm::Id2 range = Algorithm::Reduce(input, vtkm::Id2(0, 0), vtkm::MinAndMax<vtkm::Id>());
|
2016-11-22 23:03:27 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(maxValue == range[1], "Got bad value from Reduce with comparison object");
|
|
|
|
VTKM_TEST_ASSERT(0 == range[0], "Got bad value from Reduce with comparison object");
|
2018-08-03 12:35:17 +00:00
|
|
|
|
2019-04-10 18:31:33 +00:00
|
|
|
auto pairInit = vtkm::Pair<vtkm::Id, vtkm::Float32>(0, 0.0f);
|
|
|
|
vtkm::Pair<vtkm::Id, vtkm::Float32> pairRange =
|
|
|
|
Algorithm::Reduce(input, pairInit, CustomPairOp());
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(maxValue == pairRange.first,
|
|
|
|
"Got bad value from Reduce with pair comparison object");
|
|
|
|
VTKM_TEST_ASSERT(0.0f == pairRange.second,
|
|
|
|
"Got bad value from Reduce with pair comparison object");
|
|
|
|
|
2018-08-03 12:35:17 +00:00
|
|
|
//construct an array of bools and verify that they aren't all true
|
2020-07-16 16:32:32 +00:00
|
|
|
auto barray =
|
|
|
|
vtkm::cont::make_ArrayHandle({ true, true, true, true, true, true, false, true, true, true,
|
|
|
|
true, true, true, true, true, true, true, true, true, true,
|
|
|
|
true, true, true, true, true, true, true, true, true, true,
|
|
|
|
true, true, true, true, true, true, true, true, true, true,
|
|
|
|
true, true, true, true, true, true, true, true, true, true,
|
|
|
|
true, true, true, true, true, true, true, true, true, true });
|
2019-12-06 17:52:26 +00:00
|
|
|
bool all_true = Algorithm::Reduce(barray, true, vtkm::LogicalAnd());
|
|
|
|
VTKM_TEST_ASSERT(all_true == false, "reduction with vtkm::LogicalAnd should return false");
|
2018-08-03 12:35:17 +00:00
|
|
|
|
|
|
|
//test with a custom value type with the reduction value being a vtkm::Vec<float,2>
|
2020-07-16 16:32:32 +00:00
|
|
|
auto farray = vtkm::cont::make_ArrayHandle<CustomTForReduce>(
|
|
|
|
{ 13.1f, -2.1f, -1.0f, 13.1f, -2.1f, -1.0f, 413.1f, -2.1f, -1.0f, 13.1f, -2.1f, -1.0f,
|
|
|
|
13.1f, -2.1f, -1.0f, 13.1f, -2.1f, -1.0f, 13.1f, -2.1f, -1.0f, 13.1f, -2.1f, -1.0f,
|
|
|
|
13.1f, -2.1f, -11.0f, 13.1f, -2.1f, -1.0f, 13.1f, -2.1f, -1.0f, 13.1f, -2.1f, -1.0f,
|
|
|
|
13.1f, -2.1f, -1.0f, 13.1f, -2.1f, -1.0f, 13.1f, -2.1f, -1.0f, 13.1f, -211.1f, -1.0f,
|
|
|
|
13.1f, -2.1f, -1.0f, 13.1f, -2.1f, -1.0f, 13.1f, -2.1f, -1.0f, 113.1f, -2.1f, -1.0f });
|
2019-07-31 16:20:38 +00:00
|
|
|
vtkm::Vec2f_32 frange =
|
|
|
|
Algorithm::Reduce(farray, vtkm::Vec2f_32(0.0f, 0.0f), CustomMinAndMax<CustomTForReduce>());
|
2018-08-03 12:35:17 +00:00
|
|
|
VTKM_TEST_ASSERT(-211.1f == frange[0],
|
|
|
|
"Got bad float value from Reduce with comparison object");
|
|
|
|
VTKM_TEST_ASSERT(413.1f == frange[1], "Got bad float value from Reduce with comparison object");
|
2015-06-18 19:40:51 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestReduceWithFancyArrays()
|
2015-06-18 19:40:51 +00:00
|
|
|
{
|
2015-06-11 19:23:29 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
IdArrayHandle keys, values;
|
2015-06-11 19:23:29 +00:00
|
|
|
|
2020-01-22 23:54:00 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(
|
|
|
|
ClearArrayKernel(keys.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag(), token)),
|
|
|
|
ARRAY_SIZE);
|
|
|
|
|
|
|
|
Algorithm::Schedule(
|
|
|
|
ClearArrayKernel(values.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag(), token)),
|
|
|
|
ARRAY_SIZE);
|
|
|
|
}
|
2015-06-11 19:23:29 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::ArrayHandleZip<IdArrayHandle, IdArrayHandle> zipped(keys, values);
|
2015-06-11 19:23:29 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
//the output of reduce and scan inclusive should be the same
|
2017-08-16 15:34:21 +00:00
|
|
|
using ResultType = vtkm::Pair<vtkm::Id, vtkm::Id>;
|
2017-05-18 14:29:41 +00:00
|
|
|
ResultType reduce_sum_with_intial_value =
|
2020-04-16 20:18:34 +00:00
|
|
|
Algorithm::Reduce(vtkm::cont::make_ArrayHandleView(zipped, 0, ARRAY_SIZE),
|
|
|
|
ResultType(ARRAY_SIZE, ARRAY_SIZE));
|
2015-06-11 19:23:29 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
ResultType expectedResult(OFFSET * ARRAY_SIZE + ARRAY_SIZE, OFFSET * ARRAY_SIZE + ARRAY_SIZE);
|
|
|
|
VTKM_TEST_ASSERT((reduce_sum_with_intial_value == expectedResult),
|
|
|
|
"Got bad sum from Reduce with initial value");
|
2015-06-11 19:23:29 +00:00
|
|
|
}
|
|
|
|
|
2015-06-18 19:40:51 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
//lastly test with heterogeneous zip values ( vec3, and constant array handle),
|
|
|
|
//and a custom reduce binary functor
|
2017-06-23 18:50:34 +00:00
|
|
|
using ValueType = vtkm::Float32;
|
2015-06-18 19:40:51 +00:00
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
IdArrayHandle indexHandle =
|
|
|
|
vtkm::cont::make_ArrayHandle<vtkm::Id>({ 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4,
|
|
|
|
5, 5, 5, 1, 4, 9, 7, 7, 7, 8, 8, 8, 0, 1, 2 });
|
|
|
|
vtkm::cont::ArrayHandle<ValueType> valueHandle = vtkm::cont::make_ArrayHandle(
|
|
|
|
{ 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f, -2.0f });
|
2015-06-11 19:23:29 +00:00
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
const ValueType expectedSum = 125;
|
2015-04-28 13:31:50 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::ArrayHandlePermutation<IdArrayHandle, vtkm::cont::ArrayHandle<ValueType>> perm;
|
|
|
|
perm = vtkm::cont::make_ArrayHandlePermutation(indexHandle, valueHandle);
|
2015-04-30 13:01:52 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
const ValueType sum = Algorithm::Reduce(perm, ValueType(0.0f));
|
2015-04-30 13:01:52 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT((sum == expectedSum), "Got bad sum from Reduce with permutation handle");
|
2015-06-18 19:40:51 +00:00
|
|
|
}
|
2015-04-30 13:01:52 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestReduceByKey()
|
2015-05-04 19:53:35 +00:00
|
|
|
{
|
|
|
|
//first test with very basic integer key / values
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
const vtkm::Id expectedLength = 6;
|
2017-10-24 22:12:30 +00:00
|
|
|
vtkm::IdComponent expectedKeys[expectedLength] = { 0, 1, 4, 0, 2, -1 };
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Id expectedValues[expectedLength] = { 10, 2, 0, 3, 10, -42 };
|
2015-05-04 19:53:35 +00:00
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
IdComponentArrayHandle keys =
|
|
|
|
vtkm::cont::make_ArrayHandle<vtkm::IdComponent>({ 0, 0, 0, 1, 1, 4, 0, 2, 2, 2, 2, -1 });
|
|
|
|
IdArrayHandle values =
|
|
|
|
vtkm::cont::make_ArrayHandle<vtkm::Id>({ 13, -2, -1, 1, 1, 0, 3, 1, 2, 3, 4, -42 });
|
2015-05-04 19:53:35 +00:00
|
|
|
|
2017-10-24 22:12:30 +00:00
|
|
|
IdComponentArrayHandle keysOut;
|
|
|
|
IdArrayHandle valuesOut;
|
2017-05-18 14:29:41 +00:00
|
|
|
Algorithm::ReduceByKey(keys, values, keysOut, valuesOut, vtkm::Add());
|
2015-05-04 19:53:35 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(keysOut.GetNumberOfValues() == expectedLength,
|
|
|
|
"Got wrong number of output keys");
|
2015-05-04 19:53:35 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(valuesOut.GetNumberOfValues() == expectedLength,
|
|
|
|
"Got wrong number of output values");
|
2015-05-04 19:53:35 +00:00
|
|
|
|
2020-05-08 15:30:59 +00:00
|
|
|
auto keys_portal = keysOut.ReadPortal();
|
|
|
|
auto values_portal = valuesOut.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < expectedLength; ++i)
|
2015-05-04 19:53:35 +00:00
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
const vtkm::Id k = keys_portal.Get(i);
|
|
|
|
const vtkm::Id v = values_portal.Get(i);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(expectedKeys[i] == k, "Incorrect reduced key");
|
|
|
|
VTKM_TEST_ASSERT(expectedValues[i] == v, "Incorrect reduced value");
|
2015-05-04 19:53:35 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-12 20:11:28 +00:00
|
|
|
//next test with a single key across the entire set, using vec3 as the
|
|
|
|
//value, using a custom reduce binary functor
|
2015-06-01 16:19:17 +00:00
|
|
|
{
|
2020-07-16 16:32:32 +00:00
|
|
|
IdArrayHandle keys = vtkm::cont::make_ArrayHandle<vtkm::Id>({ 0, 0, 0 });
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Vec3f_64, StorageTag> values =
|
|
|
|
vtkm::cont::make_ArrayHandle({ vtkm::Vec3f_64(13.1, 13.3, 13.5),
|
|
|
|
vtkm::Vec3f_64(-2.1, -2.3, -2.5),
|
|
|
|
vtkm::Vec3f_64(-1.0, -1.0, 1.0) });
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
const vtkm::Id expectedLength = 1;
|
2020-07-16 16:32:32 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Id expectedKeys[expectedLength] = { 0 };
|
2015-06-01 18:50:35 +00:00
|
|
|
|
2019-07-31 16:20:38 +00:00
|
|
|
vtkm::Vec3f_64 expectedValues[expectedLength];
|
2017-05-18 14:29:41 +00:00
|
|
|
expectedValues[0] = vtkm::make_Vec(27.51, 30.59, -33.75);
|
2015-06-01 16:19:17 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
IdArrayHandle keysOut;
|
2019-07-31 16:20:38 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::Vec3f_64, StorageTag> valuesOut;
|
2017-05-18 14:29:41 +00:00
|
|
|
Algorithm::ReduceByKey(keys, values, keysOut, valuesOut, vtkm::Multiply());
|
2015-06-01 16:19:17 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(keysOut.GetNumberOfValues() == expectedLength,
|
|
|
|
"Got wrong number of output keys");
|
2015-06-01 16:19:17 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(valuesOut.GetNumberOfValues() == expectedLength,
|
|
|
|
"Got wrong number of output values");
|
2015-06-01 16:19:17 +00:00
|
|
|
|
2020-05-08 15:30:59 +00:00
|
|
|
auto keys_portal = keysOut.ReadPortal();
|
|
|
|
auto values_portal = valuesOut.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < expectedLength; ++i)
|
2015-06-01 16:19:17 +00:00
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
const vtkm::Id k = keys_portal.Get(i);
|
|
|
|
const vtkm::Vec3f_64 v = values_portal.Get(i);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(expectedKeys[i] == k, "Incorrect reduced key");
|
|
|
|
VTKM_TEST_ASSERT(expectedValues[i] == v, "Incorrect reduced vale");
|
2015-06-18 19:40:51 +00:00
|
|
|
}
|
2015-06-01 16:19:17 +00:00
|
|
|
}
|
2017-05-18 14:29:41 +00:00
|
|
|
}
|
2015-06-05 18:12:07 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
static VTKM_CONT void TestReduceByKeyWithFancyArrays()
|
|
|
|
{
|
2020-07-16 16:32:32 +00:00
|
|
|
IdComponentArrayHandle keys =
|
|
|
|
vtkm::cont::make_ArrayHandle<vtkm::IdComponent>({ 0, 0, 0, 1, 1, 4, 0, 2, 2, 2, 2, -1 });
|
|
|
|
IdArrayHandle values =
|
|
|
|
vtkm::cont::make_ArrayHandle<vtkm::Id>({ 13, -2, -1, 1, 1, 0, 3, 1, 2, 3, 4, -42 });
|
|
|
|
FloatCastHandle castValues(values);
|
|
|
|
|
2020-04-16 20:18:34 +00:00
|
|
|
const vtkm::Id expectedLength = 6;
|
|
|
|
vtkm::IdComponent expectedKeys[expectedLength] = { 0, 1, 4, 0, 2, -1 };
|
|
|
|
vtkm::Id expectedValues[expectedLength] = { 10, 2, 0, 3, 10, -42 };
|
2015-06-10 20:37:52 +00:00
|
|
|
|
2020-04-16 20:18:34 +00:00
|
|
|
IdComponentArrayHandle keysOut;
|
|
|
|
IdArrayHandle valuesOut;
|
|
|
|
FloatCastHandle castValuesOut(valuesOut);
|
|
|
|
Algorithm::ReduceByKey(keys, castValues, keysOut, castValuesOut, vtkm::Add());
|
2015-06-10 20:37:52 +00:00
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(keysOut.GetNumberOfValues() == expectedLength,
|
2017-05-18 14:29:41 +00:00
|
|
|
"Got wrong number of output keys");
|
2015-06-10 20:37:52 +00:00
|
|
|
|
2020-04-16 20:18:34 +00:00
|
|
|
VTKM_TEST_ASSERT(valuesOut.GetNumberOfValues() == expectedLength,
|
2017-05-18 14:29:41 +00:00
|
|
|
"Got wrong number of output values");
|
2020-05-08 15:30:59 +00:00
|
|
|
auto keys_portal = keysOut.ReadPortal();
|
|
|
|
auto values_portal = valuesOut.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < expectedLength; ++i)
|
2015-06-10 20:37:52 +00:00
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
const vtkm::Id k = keys_portal.Get(i);
|
|
|
|
const vtkm::Id v = values_portal.Get(i);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(expectedKeys[i] == k, "Incorrect reduced key");
|
2020-04-16 20:18:34 +00:00
|
|
|
VTKM_TEST_ASSERT(expectedValues[i] == v, "Incorrect reduced value");
|
2015-06-05 18:35:05 +00:00
|
|
|
}
|
2015-05-04 19:53:35 +00:00
|
|
|
}
|
|
|
|
|
2017-04-19 19:38:28 +00:00
|
|
|
static VTKM_CONT void TestScanInclusiveByKeyOne()
|
|
|
|
{
|
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
IdArrayHandle keys = vtkm::cont::make_ArrayHandle<vtkm::Id>({ 0 });
|
|
|
|
IdArrayHandle values = vtkm::cont::make_ArrayHandle<vtkm::Id>({ 5 });
|
2017-04-19 19:38:28 +00:00
|
|
|
|
|
|
|
IdArrayHandle valuesOut;
|
|
|
|
|
|
|
|
Algorithm::ScanInclusiveByKey(keys, values, valuesOut, vtkm::Add());
|
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
VTKM_TEST_ASSERT(valuesOut.GetNumberOfValues() == 1, "Got wrong number of output values");
|
2020-01-28 19:14:32 +00:00
|
|
|
const vtkm::Id v = valuesOut.ReadPortal().Get(0);
|
2017-04-19 19:38:28 +00:00
|
|
|
VTKM_TEST_ASSERT(5 == v, "Incorrect scanned value");
|
|
|
|
}
|
|
|
|
|
|
|
|
static VTKM_CONT void TestScanInclusiveByKeyTwo()
|
|
|
|
{
|
2020-07-16 16:32:32 +00:00
|
|
|
IdArrayHandle keys = vtkm::cont::make_ArrayHandle<vtkm::Id>({ 0, 1 });
|
|
|
|
IdArrayHandle values = vtkm::cont::make_ArrayHandle<vtkm::Id>({ 1, 1 });
|
2017-04-19 19:38:28 +00:00
|
|
|
|
|
|
|
const vtkm::Id expectedLength = 2;
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Id expectedValues[expectedLength] = { 1, 1 };
|
2017-04-19 19:38:28 +00:00
|
|
|
|
|
|
|
IdArrayHandle valuesOut;
|
|
|
|
|
|
|
|
Algorithm::ScanInclusiveByKey(keys, values, valuesOut, vtkm::Add());
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(valuesOut.GetNumberOfValues() == expectedLength,
|
|
|
|
"Got wrong number of output values");
|
2020-05-08 15:30:59 +00:00
|
|
|
auto values_portal = valuesOut.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < expectedLength; i++)
|
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
const vtkm::Id v = values_portal.Get(i);
|
2017-04-25 16:12:11 +00:00
|
|
|
VTKM_TEST_ASSERT(expectedValues[static_cast<std::size_t>(i)] == v, "Incorrect scanned value");
|
2017-04-19 19:38:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
static VTKM_CONT void TestScanInclusiveByKeyLarge()
|
|
|
|
{
|
2020-07-16 16:32:32 +00:00
|
|
|
std::vector<vtkm::Id> inputKeys(ARRAY_SIZE);
|
2017-04-20 21:13:05 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; i++)
|
|
|
|
{
|
2017-04-19 19:38:28 +00:00
|
|
|
if (i % 100 < 98)
|
2017-04-25 16:12:11 +00:00
|
|
|
inputKeys[static_cast<std::size_t>(i)] = static_cast<vtkm::Id>(i / 100);
|
2017-04-19 19:38:28 +00:00
|
|
|
else
|
2017-04-25 16:12:11 +00:00
|
|
|
inputKeys[static_cast<std::size_t>(i)] = static_cast<vtkm::Id>(i);
|
2017-04-19 19:38:28 +00:00
|
|
|
}
|
2020-07-16 16:32:32 +00:00
|
|
|
std::vector<vtkm::Id> inputValues(ARRAY_SIZE, 1);
|
2017-04-19 19:38:28 +00:00
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
std::vector<vtkm::Id> expectedValues(ARRAY_SIZE);
|
2017-05-18 14:29:41 +00:00
|
|
|
for (std::size_t i = 0; i < ARRAY_SIZE; i++)
|
|
|
|
{
|
2017-04-19 19:38:28 +00:00
|
|
|
if (i % 100 < 98)
|
2017-04-20 21:09:38 +00:00
|
|
|
expectedValues[i] = static_cast<vtkm::Id>(1 + i % 100);
|
2017-04-19 19:38:28 +00:00
|
|
|
else
|
2017-04-20 21:09:38 +00:00
|
|
|
expectedValues[i] = static_cast<vtkm::Id>(1);
|
2017-04-19 19:38:28 +00:00
|
|
|
}
|
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
IdArrayHandle keys = vtkm::cont::make_ArrayHandle(inputKeys, vtkm::CopyFlag::Off);
|
|
|
|
IdArrayHandle values = vtkm::cont::make_ArrayHandle(inputValues, vtkm::CopyFlag::Off);
|
2017-04-19 19:38:28 +00:00
|
|
|
|
|
|
|
IdArrayHandle valuesOut;
|
|
|
|
|
|
|
|
Algorithm::ScanInclusiveByKey(keys, values, valuesOut, vtkm::Add());
|
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
VTKM_TEST_ASSERT(valuesOut.GetNumberOfValues() == ARRAY_SIZE,
|
2017-04-19 19:38:28 +00:00
|
|
|
"Got wrong number of output values");
|
2020-05-08 15:30:59 +00:00
|
|
|
auto values_portal = valuesOut.ReadPortal();
|
2020-07-16 16:32:32 +00:00
|
|
|
for (auto i = 0; i < ARRAY_SIZE; i++)
|
2017-05-18 14:29:41 +00:00
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
const vtkm::Id v = values_portal.Get(i);
|
2017-04-25 16:12:11 +00:00
|
|
|
VTKM_TEST_ASSERT(expectedValues[static_cast<std::size_t>(i)] == v, "Incorrect scanned value");
|
2017-04-19 19:38:28 +00:00
|
|
|
}
|
|
|
|
}
|
2017-03-29 15:29:11 +00:00
|
|
|
static VTKM_CONT void TestScanInclusiveByKey()
|
|
|
|
{
|
2020-07-16 16:32:32 +00:00
|
|
|
IdComponentArrayHandle keys =
|
|
|
|
vtkm::cont::make_ArrayHandle<vtkm::IdComponent>({ 0, 0, 0, 1, 1, 2, 3, 3, 3, 3 });
|
|
|
|
IdArrayHandle values = vtkm::cont::make_ArrayHandle<vtkm::Id>({ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 });
|
2017-03-29 15:29:11 +00:00
|
|
|
|
|
|
|
const vtkm::Id expectedLength = 10;
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Id expectedValues[expectedLength] = { 1, 2, 3, 1, 2, 1, 1, 2, 3, 4 };
|
2017-03-29 15:29:11 +00:00
|
|
|
|
|
|
|
IdArrayHandle valuesOut;
|
|
|
|
|
|
|
|
Algorithm::ScanInclusiveByKey(keys, values, valuesOut);
|
|
|
|
VTKM_TEST_ASSERT(valuesOut.GetNumberOfValues() == expectedLength,
|
|
|
|
"Got wrong number of output values");
|
2020-05-08 15:30:59 +00:00
|
|
|
auto valuesPortal = valuesOut.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (auto i = 0; i < expectedLength; i++)
|
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
const vtkm::Id v = valuesPortal.Get(i);
|
2017-04-25 16:12:11 +00:00
|
|
|
VTKM_TEST_ASSERT(expectedValues[static_cast<std::size_t>(i)] == v, "Incorrect scanned value");
|
2017-03-29 15:29:11 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-16 16:37:44 +00:00
|
|
|
static VTKM_CONT void TestScanInclusiveByKeyInPlace()
|
|
|
|
{
|
2020-07-16 16:32:32 +00:00
|
|
|
IdComponentArrayHandle keys =
|
|
|
|
vtkm::cont::make_ArrayHandle<vtkm::IdComponent>({ 0, 0, 0, 1, 1, 2, 3, 3, 3, 3 });
|
|
|
|
IdArrayHandle values = vtkm::cont::make_ArrayHandle<vtkm::Id>({ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 });
|
2020-04-16 16:37:44 +00:00
|
|
|
|
|
|
|
const vtkm::Id expectedLength = 10;
|
|
|
|
vtkm::Id expectedValues[expectedLength] = { 1, 2, 3, 1, 2, 1, 1, 2, 3, 4 };
|
|
|
|
|
|
|
|
Algorithm::ScanInclusiveByKey(keys, values, values);
|
|
|
|
VTKM_TEST_ASSERT(values.GetNumberOfValues() == expectedLength,
|
|
|
|
"Got wrong number of output values");
|
2020-05-08 15:30:59 +00:00
|
|
|
auto valuesPortal = values.ReadPortal();
|
2020-04-16 16:37:44 +00:00
|
|
|
for (auto i = 0; i < expectedLength; i++)
|
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
const vtkm::Id v = valuesPortal.Get(i);
|
2020-04-16 16:37:44 +00:00
|
|
|
VTKM_TEST_ASSERT(expectedValues[static_cast<std::size_t>(i)] == v, "Incorrect scanned value");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
static VTKM_CONT void TestScanInclusiveByKeyInPlaceWithFancyArray()
|
|
|
|
{
|
2020-07-16 16:32:32 +00:00
|
|
|
IdComponentArrayHandle keys =
|
|
|
|
vtkm::cont::make_ArrayHandle<vtkm::IdComponent>({ 0, 0, 0, 1, 1, 2, 3, 3, 3, 3 });
|
|
|
|
IdArrayHandle values = vtkm::cont::make_ArrayHandle<vtkm::Id>({ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 });
|
|
|
|
FloatCastHandle castValues(values);
|
2020-04-16 16:37:44 +00:00
|
|
|
|
|
|
|
const vtkm::Id expectedLength = 10;
|
|
|
|
vtkm::Id expectedValues[expectedLength] = { 1, 2, 3, 1, 2, 1, 1, 2, 3, 4 };
|
|
|
|
|
|
|
|
Algorithm::ScanInclusiveByKey(keys, castValues, castValues);
|
|
|
|
VTKM_TEST_ASSERT(values.GetNumberOfValues() == expectedLength,
|
|
|
|
"Got wrong number of output values");
|
2020-05-08 15:30:59 +00:00
|
|
|
auto valuesPortal = values.ReadPortal();
|
2020-04-16 16:37:44 +00:00
|
|
|
for (auto i = 0; i < expectedLength; i++)
|
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
const vtkm::Id v = valuesPortal.Get(i);
|
2020-04-16 16:37:44 +00:00
|
|
|
VTKM_TEST_ASSERT(expectedValues[static_cast<std::size_t>(i)] == v, "Incorrect scanned value");
|
|
|
|
}
|
|
|
|
}
|
2017-04-13 17:50:56 +00:00
|
|
|
|
2017-04-18 19:26:15 +00:00
|
|
|
static VTKM_CONT void TestScanExclusiveByKeyOne()
|
|
|
|
{
|
|
|
|
vtkm::Id init = 5;
|
|
|
|
|
|
|
|
const vtkm::Id expectedLength = 1;
|
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
IdArrayHandle keys = vtkm::cont::make_ArrayHandle<vtkm::Id>({ 0 });
|
|
|
|
IdArrayHandle values = vtkm::cont::make_ArrayHandle<vtkm::Id>({ 0 });
|
2017-04-18 19:26:15 +00:00
|
|
|
|
|
|
|
IdArrayHandle valuesOut;
|
|
|
|
|
|
|
|
Algorithm::ScanExclusiveByKey(keys, values, valuesOut, init, vtkm::Add());
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(valuesOut.GetNumberOfValues() == expectedLength,
|
|
|
|
"Got wrong number of output values");
|
2020-01-28 19:14:32 +00:00
|
|
|
const vtkm::Id v = valuesOut.ReadPortal().Get(0);
|
2017-04-18 19:26:15 +00:00
|
|
|
VTKM_TEST_ASSERT(init == v, "Incorrect scanned value");
|
|
|
|
}
|
|
|
|
|
2017-04-19 19:38:28 +00:00
|
|
|
static VTKM_CONT void TestScanExclusiveByKeyTwo()
|
|
|
|
{
|
|
|
|
vtkm::Id init = 5;
|
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
IdArrayHandle keys = vtkm::cont::make_ArrayHandle<vtkm::Id>({ 0, 1 });
|
|
|
|
IdArrayHandle values = vtkm::cont::make_ArrayHandle<vtkm::Id>({ 1, 1 });
|
|
|
|
|
2017-04-19 19:38:28 +00:00
|
|
|
const vtkm::Id expectedLength = 2;
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Id expectedValues[expectedLength] = { 5, 5 };
|
2017-04-19 19:38:28 +00:00
|
|
|
|
|
|
|
IdArrayHandle valuesOut;
|
|
|
|
|
|
|
|
Algorithm::ScanExclusiveByKey(keys, values, valuesOut, init, vtkm::Add());
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(valuesOut.GetNumberOfValues() == expectedLength,
|
|
|
|
"Got wrong number of output values");
|
2020-05-08 15:30:59 +00:00
|
|
|
auto valuesPortal = valuesOut.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (auto i = 0; i < expectedLength; i++)
|
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
const vtkm::Id v = valuesPortal.Get(i);
|
2017-04-19 19:38:28 +00:00
|
|
|
VTKM_TEST_ASSERT(expectedValues[i] == v, "Incorrect scanned value");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static VTKM_CONT void TestScanExclusiveByKeyLarge()
|
|
|
|
{
|
2020-07-16 16:32:32 +00:00
|
|
|
std::vector<vtkm::Id> inputKeys(ARRAY_SIZE);
|
2017-05-18 14:29:41 +00:00
|
|
|
for (std::size_t i = 0; i < ARRAY_SIZE; i++)
|
|
|
|
{
|
2017-04-19 19:38:28 +00:00
|
|
|
if (i % 100 < 98)
|
2017-04-20 21:09:38 +00:00
|
|
|
inputKeys[i] = static_cast<vtkm::Id>(i / 100);
|
2017-04-19 19:38:28 +00:00
|
|
|
else
|
2017-04-20 21:09:38 +00:00
|
|
|
inputKeys[i] = static_cast<vtkm::Id>(i);
|
2017-04-19 19:38:28 +00:00
|
|
|
}
|
2020-07-16 16:32:32 +00:00
|
|
|
std::vector<vtkm::Id> inputValues(ARRAY_SIZE, 1);
|
2017-04-19 19:38:28 +00:00
|
|
|
vtkm::Id init = 5;
|
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
std::vector<vtkm::Id> expectedValues(ARRAY_SIZE);
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; i++)
|
|
|
|
{
|
2017-04-19 19:38:28 +00:00
|
|
|
if (i % 100 < 98)
|
2017-04-25 16:12:11 +00:00
|
|
|
expectedValues[static_cast<std::size_t>(i)] = static_cast<vtkm::Id>(init + i % 100);
|
2017-04-19 19:38:28 +00:00
|
|
|
else
|
2017-04-25 16:12:11 +00:00
|
|
|
expectedValues[static_cast<std::size_t>(i)] = init;
|
2017-04-19 19:38:28 +00:00
|
|
|
}
|
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
IdArrayHandle keys = vtkm::cont::make_ArrayHandle(inputKeys, vtkm::CopyFlag::Off);
|
|
|
|
IdArrayHandle values = vtkm::cont::make_ArrayHandle(inputValues, vtkm::CopyFlag::Off);
|
2017-04-19 19:38:28 +00:00
|
|
|
|
|
|
|
IdArrayHandle valuesOut;
|
|
|
|
|
|
|
|
Algorithm::ScanExclusiveByKey(keys, values, valuesOut, init, vtkm::Add());
|
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
VTKM_TEST_ASSERT(valuesOut.GetNumberOfValues() == ARRAY_SIZE,
|
2017-04-19 19:38:28 +00:00
|
|
|
"Got wrong number of output values");
|
2020-05-08 15:30:59 +00:00
|
|
|
auto valuesPortal = valuesOut.ReadPortal();
|
2020-07-16 16:32:32 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; i++)
|
2017-05-18 14:29:41 +00:00
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
const vtkm::Id v = valuesPortal.Get(i);
|
2017-04-25 16:12:11 +00:00
|
|
|
VTKM_TEST_ASSERT(expectedValues[static_cast<std::size_t>(i)] == v, "Incorrect scanned value");
|
2017-04-19 19:38:28 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-17 21:03:49 +00:00
|
|
|
static VTKM_CONT void TestScanExclusiveByKey()
|
|
|
|
{
|
|
|
|
vtkm::Id init = 5;
|
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
IdComponentArrayHandle keys =
|
|
|
|
vtkm::cont::make_ArrayHandle<vtkm::IdComponent>({ 0, 0, 0, 1, 1, 2, 3, 3, 3, 3 });
|
|
|
|
IdArrayHandle values = vtkm::cont::make_ArrayHandle<vtkm::Id>({ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 });
|
|
|
|
|
2017-04-17 21:03:49 +00:00
|
|
|
const vtkm::Id expectedLength = 10;
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Id expectedValues[expectedLength] = { 5, 6, 7, 5, 6, 5, 5, 6, 7, 8 };
|
2017-04-17 21:03:49 +00:00
|
|
|
|
|
|
|
IdArrayHandle valuesOut;
|
|
|
|
|
2017-04-17 22:11:02 +00:00
|
|
|
Algorithm::ScanExclusiveByKey(keys, values, valuesOut, init, vtkm::Add());
|
|
|
|
|
2017-04-17 21:03:49 +00:00
|
|
|
VTKM_TEST_ASSERT(valuesOut.GetNumberOfValues() == expectedLength,
|
|
|
|
"Got wrong number of output values");
|
2020-05-08 15:30:59 +00:00
|
|
|
auto valuesPortal = valuesOut.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < expectedLength; i++)
|
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
const vtkm::Id v = valuesPortal.Get(i);
|
2017-04-25 16:12:11 +00:00
|
|
|
VTKM_TEST_ASSERT(expectedValues[static_cast<std::size_t>(i)] == v, "Incorrect scanned value");
|
2017-04-17 21:03:49 +00:00
|
|
|
}
|
|
|
|
}
|
2020-04-16 16:37:44 +00:00
|
|
|
static VTKM_CONT void TestScanExclusiveByKeyInPlace()
|
|
|
|
{
|
|
|
|
vtkm::Id init = 5;
|
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
IdComponentArrayHandle keys =
|
|
|
|
vtkm::cont::make_ArrayHandle<vtkm::IdComponent>({ 0, 0, 0, 1, 1, 2, 3, 3, 3, 3 });
|
|
|
|
IdArrayHandle values = vtkm::cont::make_ArrayHandle<vtkm::Id>({ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 });
|
|
|
|
|
2020-04-16 16:37:44 +00:00
|
|
|
const vtkm::Id expectedLength = 10;
|
|
|
|
vtkm::Id expectedValues[expectedLength] = { 5, 6, 7, 5, 6, 5, 5, 6, 7, 8 };
|
|
|
|
|
|
|
|
Algorithm::ScanExclusiveByKey(keys, values, values, init, vtkm::Add());
|
|
|
|
VTKM_TEST_ASSERT(values.GetNumberOfValues() == expectedLength,
|
|
|
|
"Got wrong number of output values");
|
2020-05-08 15:30:59 +00:00
|
|
|
auto valuesPortal = values.ReadPortal();
|
2020-04-16 16:37:44 +00:00
|
|
|
for (auto i = 0; i < expectedLength; i++)
|
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
const vtkm::Id v = valuesPortal.Get(i);
|
2020-04-16 16:37:44 +00:00
|
|
|
VTKM_TEST_ASSERT(expectedValues[static_cast<std::size_t>(i)] == v, "Incorrect scanned value");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
static VTKM_CONT void TestScanExclusiveByKeyInPlaceWithFancyArray()
|
|
|
|
{
|
|
|
|
vtkm::FloatDefault init = 5;
|
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
IdComponentArrayHandle keys =
|
|
|
|
vtkm::cont::make_ArrayHandle<vtkm::IdComponent>({ 0, 0, 0, 1, 1, 2, 3, 3, 3, 3 });
|
|
|
|
IdArrayHandle values = vtkm::cont::make_ArrayHandle<vtkm::Id>({ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 });
|
|
|
|
FloatCastHandle castValues(values);
|
|
|
|
|
2020-04-16 16:37:44 +00:00
|
|
|
const vtkm::Id expectedLength = 10;
|
|
|
|
vtkm::Id expectedValues[expectedLength] = { 5, 6, 7, 5, 6, 5, 5, 6, 7, 8 };
|
|
|
|
|
|
|
|
Algorithm::ScanExclusiveByKey(keys, castValues, castValues, init, vtkm::Add());
|
|
|
|
VTKM_TEST_ASSERT(values.GetNumberOfValues() == expectedLength,
|
|
|
|
"Got wrong number of output values");
|
2020-05-08 15:30:59 +00:00
|
|
|
auto valuesPortal = values.ReadPortal();
|
2020-04-16 16:37:44 +00:00
|
|
|
for (auto i = 0; i < expectedLength; i++)
|
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
const vtkm::Id v = valuesPortal.Get(i);
|
2020-04-16 16:37:44 +00:00
|
|
|
VTKM_TEST_ASSERT(expectedValues[static_cast<std::size_t>(i)] == v, "Incorrect scanned value");
|
|
|
|
}
|
|
|
|
}
|
2017-04-13 17:50:56 +00:00
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestScanInclusive()
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
2015-06-16 12:35:04 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
//construct the index array
|
|
|
|
IdArrayHandle array;
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(
|
|
|
|
ClearArrayKernel(array.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag(), token)),
|
|
|
|
ARRAY_SIZE);
|
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
//we know have an array whose sum is equal to OFFSET * ARRAY_SIZE,
|
|
|
|
//let's validate that
|
|
|
|
vtkm::Id sum = Algorithm::ScanInclusive(array, array);
|
|
|
|
VTKM_TEST_ASSERT(sum == OFFSET * ARRAY_SIZE, "Got bad sum from Inclusive Scan");
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2020-05-08 15:30:59 +00:00
|
|
|
auto portal = array.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
|
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
const vtkm::Id value = portal.Get(i);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(value == (i + 1) * OFFSET, "Incorrect partial sum");
|
|
|
|
}
|
2015-06-16 12:35:04 +00:00
|
|
|
|
2021-01-28 21:59:40 +00:00
|
|
|
array.Allocate(1, vtkm::CopyFlag::On);
|
2017-05-18 14:29:41 +00:00
|
|
|
sum = Algorithm::ScanInclusive(array, array);
|
|
|
|
VTKM_TEST_ASSERT(sum == OFFSET, "Incorrect partial sum");
|
2020-01-28 19:14:32 +00:00
|
|
|
const vtkm::Id value = array.ReadPortal().Get(0);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(value == OFFSET, "Incorrect partial sum");
|
2017-03-09 00:05:28 +00:00
|
|
|
|
2021-01-28 21:59:40 +00:00
|
|
|
array.Allocate(0);
|
2017-05-18 14:29:41 +00:00
|
|
|
sum = Algorithm::ScanInclusive(array, array);
|
|
|
|
VTKM_TEST_ASSERT(sum == 0, "Incorrect partial sum");
|
2015-06-16 12:35:04 +00:00
|
|
|
}
|
|
|
|
|
2015-06-23 21:57:43 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
std::vector<vtkm::Float64> inputValues(ARRAY_SIZE);
|
|
|
|
for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
|
|
|
|
{
|
|
|
|
inputValues[i] = 1.01;
|
|
|
|
}
|
2015-06-23 21:57:43 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
std::size_t mid = ARRAY_SIZE / 2;
|
|
|
|
inputValues[mid] = 0.0;
|
2015-06-23 21:57:43 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::Float64> array =
|
2020-07-16 16:32:32 +00:00
|
|
|
vtkm::cont::make_ArrayHandle(inputValues, vtkm::CopyFlag::Off);
|
2015-06-23 21:57:43 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Float64 product = Algorithm::ScanInclusive(array, array, vtkm::Multiply());
|
2015-06-23 21:57:43 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(product == 0.0f, "ScanInclusive product result not 0.0");
|
2020-05-08 15:30:59 +00:00
|
|
|
auto portal = array.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (std::size_t i = 0; i < mid; ++i)
|
|
|
|
{
|
|
|
|
vtkm::Id index = static_cast<vtkm::Id>(i);
|
|
|
|
vtkm::Float64 expected = pow(1.01, static_cast<vtkm::Float64>(i + 1));
|
2020-05-08 15:30:59 +00:00
|
|
|
vtkm::Float64 got = portal.Get(index);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(test_equal(got, expected), "Incorrect results for ScanInclusive");
|
|
|
|
}
|
|
|
|
for (std::size_t i = mid; i < ARRAY_SIZE; ++i)
|
|
|
|
{
|
|
|
|
vtkm::Id index = static_cast<vtkm::Id>(i);
|
2020-05-08 15:30:59 +00:00
|
|
|
VTKM_TEST_ASSERT(portal.Get(index) == 0.0f, "Incorrect results for ScanInclusive");
|
2017-05-18 14:29:41 +00:00
|
|
|
}
|
2015-06-23 21:57:43 +00:00
|
|
|
}
|
|
|
|
|
2015-06-16 12:35:04 +00:00
|
|
|
{
|
2017-08-16 15:34:21 +00:00
|
|
|
using Vec3 = vtkm::Vec<Float64, 3>;
|
2019-07-31 16:20:38 +00:00
|
|
|
using Vec3ArrayHandle = vtkm::cont::ArrayHandle<vtkm::Vec3f_64, StorageTag>;
|
2015-06-16 12:35:04 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
std::vector<Vec3> testValues(ARRAY_SIZE);
|
2015-06-16 12:35:04 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
|
|
|
|
{
|
|
|
|
testValues[i] = TestValue(1, Vec3());
|
|
|
|
}
|
2020-07-16 16:32:32 +00:00
|
|
|
Vec3ArrayHandle values = vtkm::cont::make_ArrayHandle(testValues, vtkm::CopyFlag::Off);
|
2015-06-16 12:35:04 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
Vec3 sum = Algorithm::ScanInclusive(values, values);
|
|
|
|
VTKM_TEST_ASSERT(test_equal(sum, TestValue(1, Vec3()) * ARRAY_SIZE),
|
|
|
|
"Got bad sum from Inclusive Scan");
|
2015-06-16 12:35:04 +00:00
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestScanInclusiveWithComparisonObject()
|
2015-04-29 19:48:25 +00:00
|
|
|
{
|
|
|
|
|
|
|
|
//construct the index array
|
|
|
|
IdArrayHandle array;
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(
|
|
|
|
ClearArrayKernel(array.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag(), token)),
|
|
|
|
ARRAY_SIZE);
|
|
|
|
Algorithm::Schedule(
|
2020-03-26 23:34:18 +00:00
|
|
|
MakeAddArrayKernel(array.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag(), token)),
|
|
|
|
ARRAY_SIZE);
|
2020-01-21 20:18:03 +00:00
|
|
|
}
|
2015-04-29 19:48:25 +00:00
|
|
|
|
|
|
|
//we know have an array whose sum is equal to OFFSET * ARRAY_SIZE,
|
|
|
|
//let's validate that
|
|
|
|
IdArrayHandle result;
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Id sum = Algorithm::ScanInclusive(array, result, vtkm::Maximum());
|
|
|
|
VTKM_TEST_ASSERT(sum == OFFSET + (ARRAY_SIZE - 1),
|
2015-04-29 19:48:25 +00:00
|
|
|
"Got bad sum from Inclusive Scan with comparison object");
|
|
|
|
|
2020-05-08 15:30:59 +00:00
|
|
|
auto array_portal = array.ReadPortal();
|
|
|
|
auto result_portal = result.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
|
2015-04-29 19:48:25 +00:00
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
const vtkm::Id input_value = array_portal.Get(i);
|
|
|
|
const vtkm::Id result_value = result_portal.Get(i);
|
2015-04-29 19:48:25 +00:00
|
|
|
VTKM_TEST_ASSERT(input_value == result_value, "Incorrect partial sum");
|
|
|
|
}
|
|
|
|
|
|
|
|
//now try it inline
|
2017-05-18 14:29:41 +00:00
|
|
|
sum = Algorithm::ScanInclusive(array, array, vtkm::Maximum());
|
|
|
|
VTKM_TEST_ASSERT(sum == OFFSET + (ARRAY_SIZE - 1),
|
2015-04-29 19:48:25 +00:00
|
|
|
"Got bad sum from Inclusive Scan with comparison object");
|
2020-05-08 15:30:59 +00:00
|
|
|
array_portal = array.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
|
2015-04-29 19:48:25 +00:00
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
const vtkm::Id input_value = array_portal.Get(i);
|
|
|
|
const vtkm::Id result_value = result_portal.Get(i);
|
2015-04-29 19:48:25 +00:00
|
|
|
VTKM_TEST_ASSERT(input_value == result_value, "Incorrect partial sum");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestScanExclusive()
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
2015-06-16 12:35:04 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
//construct the index array
|
|
|
|
IdArrayHandle array;
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(
|
|
|
|
ClearArrayKernel(array.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag(), token)),
|
|
|
|
ARRAY_SIZE);
|
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
// we know have an array whose sum = (OFFSET * ARRAY_SIZE),
|
|
|
|
// let's validate that
|
|
|
|
vtkm::Id sum = Algorithm::ScanExclusive(array, array);
|
|
|
|
VTKM_TEST_ASSERT(sum == (OFFSET * ARRAY_SIZE), "Got bad sum from Exclusive Scan");
|
2014-02-11 17:34:56 +00:00
|
|
|
|
2020-05-08 15:30:59 +00:00
|
|
|
auto portal = array.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
|
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
const vtkm::Id value = portal.Get(i);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(value == i * OFFSET, "Incorrect partial sum");
|
|
|
|
}
|
2017-03-09 00:05:28 +00:00
|
|
|
|
2021-01-28 21:59:40 +00:00
|
|
|
array.Allocate(1, vtkm::CopyFlag::On);
|
2020-01-28 19:14:32 +00:00
|
|
|
array.WritePortal().Set(0, OFFSET);
|
2017-05-18 14:29:41 +00:00
|
|
|
sum = Algorithm::ScanExclusive(array, array);
|
|
|
|
VTKM_TEST_ASSERT(sum == OFFSET, "Incorrect partial sum");
|
2020-01-28 19:14:32 +00:00
|
|
|
const vtkm::Id value = array.ReadPortal().Get(0);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(value == 0, "Incorrect partial sum");
|
2017-03-09 00:05:28 +00:00
|
|
|
|
2021-01-28 21:59:40 +00:00
|
|
|
array.Allocate(0);
|
2017-05-18 14:29:41 +00:00
|
|
|
sum = Algorithm::ScanExclusive(array, array);
|
|
|
|
VTKM_TEST_ASSERT(sum == 0, "Incorrect partial sum");
|
2015-06-16 12:35:04 +00:00
|
|
|
}
|
|
|
|
|
2017-01-03 20:37:41 +00:00
|
|
|
// Enable when Exclusive Scan with custom operator is implemented for all
|
|
|
|
// device adaptors
|
2015-06-23 21:57:43 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
std::vector<vtkm::Float64> inputValues(ARRAY_SIZE);
|
|
|
|
for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
|
|
|
|
{
|
|
|
|
inputValues[i] = 1.01;
|
|
|
|
}
|
2015-06-23 21:57:43 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
std::size_t mid = ARRAY_SIZE / 2;
|
|
|
|
inputValues[mid] = 0.0;
|
2015-06-23 21:57:43 +00:00
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::Float64> array =
|
|
|
|
vtkm::cont::make_ArrayHandle(inputValues, vtkm::CopyFlag::Off);
|
2015-06-23 21:57:43 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Float64 initialValue = 2.00;
|
|
|
|
vtkm::Float64 product =
|
|
|
|
Algorithm::ScanExclusive(array, array, vtkm::Multiply(), initialValue);
|
2015-06-23 21:57:43 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(product == 0.0f, "ScanExclusive product result not 0.0");
|
2020-01-28 19:14:32 +00:00
|
|
|
VTKM_TEST_ASSERT(array.ReadPortal().Get(0) == initialValue,
|
2017-05-18 14:29:41 +00:00
|
|
|
"ScanExclusive result's first value != initialValue");
|
2020-05-08 15:30:59 +00:00
|
|
|
auto portal = array.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (std::size_t i = 1; i <= mid; ++i)
|
|
|
|
{
|
|
|
|
vtkm::Id index = static_cast<vtkm::Id>(i);
|
|
|
|
vtkm::Float64 expected = pow(1.01, static_cast<vtkm::Float64>(i)) * initialValue;
|
2020-05-08 15:30:59 +00:00
|
|
|
vtkm::Float64 got = portal.Get(index);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(test_equal(got, expected), "Incorrect results for ScanExclusive");
|
|
|
|
}
|
|
|
|
for (std::size_t i = mid + 1; i < ARRAY_SIZE; ++i)
|
|
|
|
{
|
|
|
|
vtkm::Id index = static_cast<vtkm::Id>(i);
|
2020-05-08 15:30:59 +00:00
|
|
|
VTKM_TEST_ASSERT(portal.Get(index) == 0.0f, "Incorrect results for ScanExclusive");
|
2017-05-18 14:29:41 +00:00
|
|
|
}
|
2015-06-23 21:57:43 +00:00
|
|
|
}
|
|
|
|
|
2015-06-16 12:35:04 +00:00
|
|
|
{
|
2017-08-16 15:34:21 +00:00
|
|
|
using Vec3 = vtkm::Vec<Float64, 3>;
|
2019-07-31 16:20:38 +00:00
|
|
|
using Vec3ArrayHandle = vtkm::cont::ArrayHandle<vtkm::Vec3f_64, StorageTag>;
|
2015-06-16 12:35:04 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
std::vector<Vec3> testValues(ARRAY_SIZE);
|
2015-06-16 12:35:04 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
|
|
|
|
{
|
|
|
|
testValues[i] = TestValue(1, Vec3());
|
|
|
|
}
|
2020-07-16 16:32:32 +00:00
|
|
|
Vec3ArrayHandle values = vtkm::cont::make_ArrayHandle(testValues, vtkm::CopyFlag::Off);
|
2015-06-16 12:35:04 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
Vec3 sum = Algorithm::ScanExclusive(values, values);
|
|
|
|
VTKM_TEST_ASSERT(test_equal(sum, (TestValue(1, Vec3()) * ARRAY_SIZE)),
|
|
|
|
"Got bad sum from Exclusive Scan");
|
2015-06-16 12:35:04 +00:00
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
}
|
|
|
|
|
2019-09-03 15:53:14 +00:00
|
|
|
static VTKM_CONT void TestScanExtended()
|
|
|
|
{
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
//construct the index array
|
|
|
|
IdArrayHandle array;
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(
|
|
|
|
ClearArrayKernel(array.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag(), token)),
|
|
|
|
ARRAY_SIZE);
|
|
|
|
}
|
2019-09-03 15:53:14 +00:00
|
|
|
|
|
|
|
// we now have an array whose sum = (OFFSET * ARRAY_SIZE),
|
|
|
|
// let's validate that
|
|
|
|
Algorithm::ScanExtended(array, array);
|
|
|
|
VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE + 1, "Output size incorrect.");
|
|
|
|
{
|
2020-01-28 19:14:32 +00:00
|
|
|
auto portal = array.ReadPortal();
|
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE + 1; ++i)
|
|
|
|
{
|
|
|
|
const vtkm::Id value = portal.Get(i);
|
|
|
|
VTKM_TEST_ASSERT(value == i * OFFSET, "Incorrect partial sum");
|
|
|
|
}
|
2019-09-03 15:53:14 +00:00
|
|
|
}
|
|
|
|
|
2021-01-28 21:59:40 +00:00
|
|
|
array.Allocate(1, vtkm::CopyFlag::On);
|
2020-01-28 19:14:32 +00:00
|
|
|
array.WritePortal().Set(0, OFFSET);
|
2019-09-03 15:53:14 +00:00
|
|
|
Algorithm::ScanExtended(array, array);
|
|
|
|
VTKM_TEST_ASSERT(array.GetNumberOfValues() == 2);
|
2020-01-28 19:14:32 +00:00
|
|
|
{
|
|
|
|
auto portal = array.ReadPortal();
|
|
|
|
VTKM_TEST_ASSERT(portal.Get(0) == 0, "Incorrect initial value");
|
|
|
|
VTKM_TEST_ASSERT(portal.Get(1) == OFFSET, "Incorrect total sum");
|
|
|
|
}
|
2019-09-03 15:53:14 +00:00
|
|
|
|
2021-01-28 21:59:40 +00:00
|
|
|
array.Allocate(0);
|
2019-09-03 15:53:14 +00:00
|
|
|
Algorithm::ScanExtended(array, array);
|
|
|
|
VTKM_TEST_ASSERT(array.GetNumberOfValues() == 1);
|
2020-01-28 19:14:32 +00:00
|
|
|
{
|
|
|
|
auto portal = array.ReadPortal();
|
|
|
|
VTKM_TEST_ASSERT(portal.Get(0) == 0, "Incorrect initial value");
|
|
|
|
}
|
2019-09-03 15:53:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
std::vector<vtkm::Float64> inputValues(ARRAY_SIZE);
|
|
|
|
for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
|
|
|
|
{
|
|
|
|
inputValues[i] = 1.01;
|
|
|
|
}
|
|
|
|
|
|
|
|
std::size_t mid = ARRAY_SIZE / 2;
|
|
|
|
inputValues[mid] = 0.0;
|
|
|
|
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Float64> array =
|
|
|
|
vtkm::cont::make_ArrayHandle(inputValues, vtkm::CopyFlag::On);
|
|
|
|
|
|
|
|
vtkm::Float64 initialValue = 2.00;
|
|
|
|
Algorithm::ScanExtended(array, array, vtkm::Multiply(), initialValue);
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(array.GetNumberOfValues() == ARRAY_SIZE + 1,
|
|
|
|
"ScanExtended output size incorrect.");
|
|
|
|
|
2020-01-28 19:14:32 +00:00
|
|
|
auto portal = array.ReadPortal();
|
2019-09-03 15:53:14 +00:00
|
|
|
VTKM_TEST_ASSERT(portal.Get(0) == initialValue,
|
|
|
|
"ScanExtended result's first value != initialValue");
|
|
|
|
|
|
|
|
for (std::size_t i = 1; i <= mid; ++i)
|
|
|
|
{
|
|
|
|
vtkm::Id index = static_cast<vtkm::Id>(i);
|
|
|
|
vtkm::Float64 expected = pow(1.01, static_cast<vtkm::Float64>(i)) * initialValue;
|
|
|
|
vtkm::Float64 got = portal.Get(index);
|
|
|
|
VTKM_TEST_ASSERT(test_equal(got, expected), "Incorrect results for ScanExtended");
|
|
|
|
}
|
|
|
|
for (std::size_t i = mid + 1; i < ARRAY_SIZE + 1; ++i)
|
|
|
|
{
|
|
|
|
vtkm::Id index = static_cast<vtkm::Id>(i);
|
|
|
|
VTKM_TEST_ASSERT(portal.Get(index) == 0.0f, "Incorrect results for ScanExtended");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
using Vec3 = vtkm::Vec3f_64;
|
|
|
|
using Vec3ArrayHandle = vtkm::cont::ArrayHandle<Vec3, StorageTag>;
|
|
|
|
|
|
|
|
std::vector<Vec3> testValues(ARRAY_SIZE);
|
|
|
|
|
|
|
|
for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
|
|
|
|
{
|
|
|
|
testValues[i] = TestValue(1, Vec3());
|
|
|
|
}
|
|
|
|
Vec3ArrayHandle values = vtkm::cont::make_ArrayHandle(testValues, vtkm::CopyFlag::On);
|
|
|
|
|
|
|
|
Algorithm::ScanExtended(values, values);
|
|
|
|
VTKM_TEST_ASSERT(test_equal(vtkm::cont::ArrayGetValue(ARRAY_SIZE, values),
|
|
|
|
(TestValue(1, Vec3()) * ARRAY_SIZE)),
|
|
|
|
"Got bad sum from ScanExtended");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestErrorExecution()
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
|
|
|
std::string message;
|
|
|
|
try
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2014-02-11 17:34:56 +00:00
|
|
|
Algorithm::Schedule(OneErrorKernel(), ARRAY_SIZE);
|
2018-06-26 18:52:04 +00:00
|
|
|
Algorithm::Synchronize();
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2017-05-18 14:29:41 +00:00
|
|
|
catch (vtkm::cont::ErrorExecution& error)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2014-02-11 17:34:56 +00:00
|
|
|
message = error.GetMessage();
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(message == ERROR_MESSAGE, "Did not get expected error message.");
|
2014-02-11 17:34:56 +00:00
|
|
|
|
|
|
|
message = "";
|
|
|
|
try
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2014-02-11 17:34:56 +00:00
|
|
|
Algorithm::Schedule(AllErrorKernel(), ARRAY_SIZE);
|
2018-06-26 18:52:04 +00:00
|
|
|
Algorithm::Synchronize();
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2017-05-18 14:29:41 +00:00
|
|
|
catch (vtkm::cont::ErrorExecution& error)
|
2014-02-11 21:20:30 +00:00
|
|
|
{
|
2014-02-11 17:34:56 +00:00
|
|
|
message = error.GetMessage();
|
2014-02-11 21:20:30 +00:00
|
|
|
}
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(message == ERROR_MESSAGE, "Did not get expected error message.");
|
2018-06-26 18:52:04 +00:00
|
|
|
|
2021-04-10 12:27:31 +00:00
|
|
|
// This is specifically to test the cuda-backend but should pass for all backends
|
2018-06-26 18:52:04 +00:00
|
|
|
message = "";
|
|
|
|
int nkernels = 0;
|
|
|
|
try
|
|
|
|
{
|
2020-01-21 20:18:03 +00:00
|
|
|
vtkm::cont::Token token;
|
|
|
|
|
2018-06-26 18:52:04 +00:00
|
|
|
IdArrayHandle idArray;
|
2020-01-21 20:18:03 +00:00
|
|
|
auto portal = idArray.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag{}, token);
|
2018-06-26 18:52:04 +00:00
|
|
|
|
|
|
|
Algorithm::Schedule(OneErrorKernel(), ARRAY_SIZE);
|
|
|
|
for (; nkernels < 100; ++nkernels)
|
|
|
|
{
|
2020-03-26 23:34:18 +00:00
|
|
|
Algorithm::Schedule(MakeAddArrayKernel(portal), ARRAY_SIZE);
|
2018-06-26 18:52:04 +00:00
|
|
|
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
|
|
|
}
|
|
|
|
Algorithm::Synchronize();
|
|
|
|
}
|
|
|
|
catch (vtkm::cont::ErrorExecution& error)
|
|
|
|
{
|
|
|
|
message = error.GetMessage();
|
|
|
|
}
|
|
|
|
VTKM_TEST_ASSERT(message == ERROR_MESSAGE, "Did not get expected error message.");
|
2014-02-11 17:34:56 +00:00
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename T, int N = 0>
|
|
|
|
struct TestCopy
|
|
|
|
{
|
|
|
|
};
|
2016-05-12 09:59:54 +00:00
|
|
|
|
|
|
|
template <typename T>
|
2017-05-18 14:29:41 +00:00
|
|
|
struct TestCopy<T>
|
|
|
|
{
|
|
|
|
static T get(vtkm::Id i) { return static_cast<T>(i); }
|
2016-05-12 09:59:54 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T, int N>
|
2017-05-18 14:29:41 +00:00
|
|
|
struct TestCopy<vtkm::Vec<T, N>>
|
|
|
|
{
|
|
|
|
static vtkm::Vec<T, N> get(vtkm::Id i)
|
|
|
|
{
|
|
|
|
vtkm::Vec<T, N> temp;
|
|
|
|
for (int j = 0; j < N; ++j)
|
|
|
|
{
|
|
|
|
temp[j] = static_cast<T>(OFFSET + (i % 50));
|
2016-05-12 09:59:54 +00:00
|
|
|
}
|
2017-05-18 14:29:41 +00:00
|
|
|
return temp;
|
|
|
|
}
|
2016-05-12 09:59:54 +00:00
|
|
|
};
|
|
|
|
|
2017-10-31 17:35:13 +00:00
|
|
|
template <typename T, typename U>
|
|
|
|
struct TestCopy<vtkm::Pair<T, U>>
|
|
|
|
{
|
|
|
|
static vtkm::Pair<T, U> get(vtkm::Id i)
|
|
|
|
{
|
|
|
|
return vtkm::make_Pair(TestCopy<T>::get(i), TestCopy<U>::get(i));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2016-05-12 09:59:54 +00:00
|
|
|
template <typename T>
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestCopyArrays()
|
2016-05-12 09:59:54 +00:00
|
|
|
{
|
2017-01-03 20:37:41 +00:00
|
|
|
#define COPY_ARRAY_SIZE 10000
|
|
|
|
|
|
|
|
std::vector<T> testData(COPY_ARRAY_SIZE);
|
2018-05-29 21:09:20 +00:00
|
|
|
std::default_random_engine generator(static_cast<unsigned int>(std::time(nullptr)));
|
2017-01-03 20:37:41 +00:00
|
|
|
|
|
|
|
vtkm::Id index = 0;
|
2017-05-18 14:29:41 +00:00
|
|
|
for (std::size_t i = 0; i < COPY_ARRAY_SIZE; ++i, ++index)
|
2016-05-12 09:59:54 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
testData[i] = TestCopy<T>::get(index);
|
2016-05-12 09:59:54 +00:00
|
|
|
}
|
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
vtkm::cont::ArrayHandle<T> input = vtkm::cont::make_ArrayHandle(testData, vtkm::CopyFlag::Off);
|
2016-05-12 09:59:54 +00:00
|
|
|
|
|
|
|
//make a deep copy of input and place it into temp
|
2016-08-12 16:39:42 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::ArrayHandle<T> temp;
|
|
|
|
temp.Allocate(COPY_ARRAY_SIZE * 2);
|
|
|
|
Algorithm::Copy(input, temp);
|
|
|
|
VTKM_TEST_ASSERT(temp.GetNumberOfValues() == COPY_ARRAY_SIZE, "Copy Needs to Resize Array");
|
2016-05-12 09:59:54 +00:00
|
|
|
|
2020-01-28 19:14:32 +00:00
|
|
|
const auto& portal = temp.ReadPortal();
|
2018-05-29 21:09:20 +00:00
|
|
|
|
|
|
|
std::uniform_int_distribution<vtkm::Id> distribution(0, COPY_ARRAY_SIZE - 1);
|
|
|
|
vtkm::Id numberOfSamples = COPY_ARRAY_SIZE / 50;
|
|
|
|
for (vtkm::Id i = 0; i < numberOfSamples; ++i)
|
2017-05-18 14:29:41 +00:00
|
|
|
{
|
2018-05-29 21:09:20 +00:00
|
|
|
vtkm::Id randomIndex = distribution(generator);
|
|
|
|
T value = portal.Get(randomIndex);
|
|
|
|
VTKM_TEST_ASSERT(value == testData[static_cast<size_t>(randomIndex)],
|
|
|
|
"Got bad value (Copy)");
|
2017-05-18 14:29:41 +00:00
|
|
|
}
|
2016-08-12 16:39:42 +00:00
|
|
|
}
|
|
|
|
|
2017-03-09 00:05:28 +00:00
|
|
|
//Verify copy of empty array works
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::ArrayHandle<T> tempIn;
|
|
|
|
vtkm::cont::ArrayHandle<T> tempOut;
|
2017-03-09 00:05:28 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
tempOut.Allocate(COPY_ARRAY_SIZE);
|
|
|
|
Algorithm::Copy(tempIn, tempOut);
|
|
|
|
VTKM_TEST_ASSERT(tempIn.GetNumberOfValues() == tempOut.GetNumberOfValues(),
|
|
|
|
"Copy sized wrong");
|
2017-03-09 00:05:28 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
// Actually allocate input array to 0 in case that makes a difference.
|
|
|
|
tempIn.Allocate(0);
|
|
|
|
tempOut.Allocate(COPY_ARRAY_SIZE);
|
|
|
|
Algorithm::Copy(tempIn, tempOut);
|
|
|
|
VTKM_TEST_ASSERT(tempIn.GetNumberOfValues() == tempOut.GetNumberOfValues(),
|
|
|
|
"Copy sized wrong");
|
2017-03-09 00:05:28 +00:00
|
|
|
}
|
|
|
|
|
2016-08-12 16:39:42 +00:00
|
|
|
//CopySubRange tests:
|
|
|
|
|
|
|
|
//1. Verify invalid input start position fails
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::ArrayHandle<T> output;
|
|
|
|
bool result = Algorithm::CopySubRange(input, COPY_ARRAY_SIZE * 4, 1, output);
|
|
|
|
VTKM_TEST_ASSERT(result == false, "CopySubRange when given bad input offset");
|
2016-08-12 16:39:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//2. Verify unallocated output gets allocated
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::ArrayHandle<T> output;
|
|
|
|
bool result = Algorithm::CopySubRange(input, 0, COPY_ARRAY_SIZE, output);
|
|
|
|
VTKM_TEST_ASSERT(result == true, "CopySubRange should succeed");
|
|
|
|
VTKM_TEST_ASSERT(output.GetNumberOfValues() == COPY_ARRAY_SIZE,
|
|
|
|
"CopySubRange needs to allocate output");
|
2016-08-12 16:39:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//3. Verify under allocated output gets resized properly
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::ArrayHandle<T> output;
|
|
|
|
output.Allocate(2);
|
|
|
|
bool result = Algorithm::CopySubRange(input, 0, COPY_ARRAY_SIZE, output);
|
|
|
|
VTKM_TEST_ASSERT(result == true, "CopySubRange should succeed");
|
|
|
|
VTKM_TEST_ASSERT(output.GetNumberOfValues() == COPY_ARRAY_SIZE,
|
|
|
|
"CopySubRange needs to re-allocate output");
|
2016-08-12 16:39:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//4. Verify invalid input length gets shortened
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::ArrayHandle<T> output;
|
|
|
|
bool result = Algorithm::CopySubRange(input, 100, COPY_ARRAY_SIZE, output);
|
|
|
|
VTKM_TEST_ASSERT(result == true, "CopySubRange needs to shorten input range");
|
|
|
|
VTKM_TEST_ASSERT(output.GetNumberOfValues() == (COPY_ARRAY_SIZE - 100),
|
|
|
|
"CopySubRange needs to shorten input range");
|
2016-08-12 16:39:42 +00:00
|
|
|
|
2018-05-29 21:09:20 +00:00
|
|
|
std::uniform_int_distribution<vtkm::Id> distribution(0, COPY_ARRAY_SIZE - 100 - 1);
|
|
|
|
vtkm::Id numberOfSamples = (COPY_ARRAY_SIZE - 100) / 100;
|
2020-05-08 15:30:59 +00:00
|
|
|
auto outputPortal = output.ReadPortal();
|
2018-05-29 21:09:20 +00:00
|
|
|
for (vtkm::Id i = 0; i < numberOfSamples; ++i)
|
2017-05-18 14:29:41 +00:00
|
|
|
{
|
2018-05-29 21:09:20 +00:00
|
|
|
vtkm::Id randomIndex = distribution(generator);
|
2020-05-08 15:30:59 +00:00
|
|
|
T value = outputPortal.Get(randomIndex);
|
2018-05-29 21:09:20 +00:00
|
|
|
VTKM_TEST_ASSERT(value == testData[static_cast<size_t>(randomIndex) + 100],
|
|
|
|
"Got bad value (CopySubRange 2)");
|
2017-05-18 14:29:41 +00:00
|
|
|
}
|
2016-08-12 16:39:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//5. Verify sub range copy works when copying into a larger output
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::ArrayHandle<T> output;
|
|
|
|
output.Allocate(COPY_ARRAY_SIZE * 2);
|
|
|
|
Algorithm::CopySubRange(input, 0, COPY_ARRAY_SIZE, output);
|
|
|
|
Algorithm::CopySubRange(input, 0, COPY_ARRAY_SIZE, output, COPY_ARRAY_SIZE);
|
|
|
|
VTKM_TEST_ASSERT(output.GetNumberOfValues() == (COPY_ARRAY_SIZE * 2),
|
|
|
|
"CopySubRange needs to not resize array");
|
2017-01-03 20:37:41 +00:00
|
|
|
|
2018-05-29 21:09:20 +00:00
|
|
|
std::uniform_int_distribution<vtkm::Id> distribution(0, COPY_ARRAY_SIZE - 1);
|
|
|
|
vtkm::Id numberOfSamples = COPY_ARRAY_SIZE / 50;
|
2020-05-08 15:30:59 +00:00
|
|
|
auto portal = output.ReadPortal();
|
2018-05-29 21:09:20 +00:00
|
|
|
for (vtkm::Id i = 0; i < numberOfSamples; ++i)
|
2017-05-18 14:29:41 +00:00
|
|
|
{
|
2018-05-29 21:09:20 +00:00
|
|
|
vtkm::Id randomIndex = distribution(generator);
|
2020-05-08 15:30:59 +00:00
|
|
|
T value = portal.Get(randomIndex);
|
2018-05-29 21:09:20 +00:00
|
|
|
VTKM_TEST_ASSERT(value == testData[static_cast<size_t>(randomIndex)],
|
|
|
|
"Got bad value (CopySubRange 5)");
|
2020-05-08 15:30:59 +00:00
|
|
|
value = portal.Get(COPY_ARRAY_SIZE + randomIndex);
|
2018-05-29 21:09:20 +00:00
|
|
|
VTKM_TEST_ASSERT(value == testData[static_cast<size_t>(randomIndex)],
|
|
|
|
"Got bad value (CopySubRange 5)");
|
2017-05-18 14:29:41 +00:00
|
|
|
}
|
2016-08-12 16:39:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//6. Verify that whey sub range needs to reallocate the output it
|
|
|
|
// properly copies the original data instead of clearing it
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::ArrayHandle<T> output;
|
|
|
|
output.Allocate(COPY_ARRAY_SIZE);
|
|
|
|
Algorithm::CopySubRange(input, 0, COPY_ARRAY_SIZE, output);
|
|
|
|
Algorithm::CopySubRange(input, 0, COPY_ARRAY_SIZE, output, COPY_ARRAY_SIZE);
|
|
|
|
VTKM_TEST_ASSERT(output.GetNumberOfValues() == (COPY_ARRAY_SIZE * 2),
|
|
|
|
"CopySubRange needs too resize Array");
|
2018-05-29 21:09:20 +00:00
|
|
|
std::uniform_int_distribution<vtkm::Id> distribution(0, COPY_ARRAY_SIZE - 1);
|
|
|
|
vtkm::Id numberOfSamples = COPY_ARRAY_SIZE / 50;
|
2020-05-08 15:30:59 +00:00
|
|
|
auto portal = output.ReadPortal();
|
2018-05-29 21:09:20 +00:00
|
|
|
for (vtkm::Id i = 0; i < numberOfSamples; ++i)
|
2017-05-18 14:29:41 +00:00
|
|
|
{
|
2018-05-29 21:09:20 +00:00
|
|
|
vtkm::Id randomIndex = distribution(generator);
|
2020-05-08 15:30:59 +00:00
|
|
|
T value = portal.Get(randomIndex);
|
2018-05-29 21:09:20 +00:00
|
|
|
VTKM_TEST_ASSERT(value == testData[static_cast<size_t>(randomIndex)],
|
|
|
|
"Got bad value (CopySubRange 6)");
|
2020-05-08 15:30:59 +00:00
|
|
|
value = portal.Get(COPY_ARRAY_SIZE + randomIndex);
|
2018-05-29 21:09:20 +00:00
|
|
|
VTKM_TEST_ASSERT(value == testData[static_cast<size_t>(randomIndex)],
|
|
|
|
"Got bad value (CopySubRange 6)");
|
2017-05-18 14:29:41 +00:00
|
|
|
}
|
2016-08-12 16:39:42 +00:00
|
|
|
}
|
|
|
|
|
2017-10-10 19:30:49 +00:00
|
|
|
// 7. Test that overlapping ranges trigger a failure:
|
|
|
|
// 7.1 output starts inside input range:
|
|
|
|
{
|
|
|
|
const vtkm::Id inBegin = 100;
|
|
|
|
const vtkm::Id inEnd = 200;
|
|
|
|
const vtkm::Id outBegin = 150;
|
|
|
|
|
|
|
|
const vtkm::Id numVals = inEnd - inBegin;
|
|
|
|
bool result = Algorithm::CopySubRange(input, inBegin, numVals, input, outBegin);
|
|
|
|
VTKM_TEST_ASSERT(result == false, "Overlapping subrange did not fail.");
|
|
|
|
}
|
|
|
|
|
|
|
|
// 7.2 input starts inside output range
|
|
|
|
{
|
|
|
|
const vtkm::Id inBegin = 100;
|
|
|
|
const vtkm::Id inEnd = 200;
|
|
|
|
const vtkm::Id outBegin = 50;
|
|
|
|
|
|
|
|
const vtkm::Id numVals = inEnd - inBegin;
|
|
|
|
bool result = Algorithm::CopySubRange(input, inBegin, numVals, input, outBegin);
|
|
|
|
VTKM_TEST_ASSERT(result == false, "Overlapping subrange did not fail.");
|
|
|
|
}
|
|
|
|
|
2016-08-12 16:39:42 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::ArrayHandle<T> output;
|
2016-08-12 16:39:42 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
//7. Verify negative input index returns false
|
|
|
|
bool result = Algorithm::CopySubRange(input, -1, COPY_ARRAY_SIZE, output);
|
|
|
|
VTKM_TEST_ASSERT(result == false, "CopySubRange negative index should fail");
|
2016-08-12 16:39:42 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
//8. Verify negative input numberOfElementsToCopy returns false
|
|
|
|
result = Algorithm::CopySubRange(input, 0, -COPY_ARRAY_SIZE, output);
|
|
|
|
VTKM_TEST_ASSERT(result == false, "CopySubRange negative number elements should fail");
|
2016-08-12 16:39:42 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
//9. Verify negative output index return false
|
|
|
|
result = Algorithm::CopySubRange(input, 0, COPY_ARRAY_SIZE, output, -2);
|
|
|
|
VTKM_TEST_ASSERT(result == false, "CopySubRange negative output index should fail");
|
2016-08-12 16:39:42 +00:00
|
|
|
}
|
|
|
|
|
2017-01-03 20:37:41 +00:00
|
|
|
#undef COPY_ARRAY_SIZE
|
2016-05-12 09:59:54 +00:00
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestCopyArraysMany()
|
2016-05-12 09:59:54 +00:00
|
|
|
{
|
2019-07-31 16:20:38 +00:00
|
|
|
TestCopyArrays<vtkm::Vec3f_32>();
|
|
|
|
TestCopyArrays<vtkm::Vec4ui_8>();
|
2017-05-18 14:29:41 +00:00
|
|
|
//
|
2017-10-31 17:35:13 +00:00
|
|
|
TestCopyArrays<vtkm::Pair<vtkm::Id, vtkm::Float32>>();
|
2019-07-31 16:20:38 +00:00
|
|
|
TestCopyArrays<vtkm::Pair<vtkm::Id, vtkm::Vec3f_32>>();
|
2017-05-18 14:29:41 +00:00
|
|
|
//
|
|
|
|
TestCopyArrays<vtkm::Float32>();
|
|
|
|
TestCopyArrays<vtkm::Float64>();
|
|
|
|
//
|
|
|
|
TestCopyArrays<vtkm::Int32>();
|
|
|
|
TestCopyArrays<vtkm::Int64>();
|
|
|
|
//
|
|
|
|
TestCopyArrays<vtkm::UInt8>();
|
|
|
|
TestCopyArrays<vtkm::UInt16>();
|
|
|
|
TestCopyArrays<vtkm::UInt32>();
|
|
|
|
TestCopyArrays<vtkm::UInt64>();
|
2016-05-12 09:59:54 +00:00
|
|
|
}
|
2015-06-12 15:46:36 +00:00
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestCopyArraysInDiffTypes()
|
2015-06-12 15:46:36 +00:00
|
|
|
{
|
2017-01-03 20:37:41 +00:00
|
|
|
std::vector<vtkm::Id> testData(ARRAY_SIZE);
|
2017-05-18 14:29:41 +00:00
|
|
|
for (std::size_t i = 0; i < ARRAY_SIZE; ++i)
|
2015-06-12 15:46:36 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
testData[i] = static_cast<vtkm::Id>(OFFSET + (i % 50));
|
2015-06-12 15:46:36 +00:00
|
|
|
}
|
|
|
|
|
2020-07-16 16:32:32 +00:00
|
|
|
IdArrayHandle input = vtkm::cont::make_ArrayHandle<vtkm::Id>(testData, vtkm::CopyFlag::Off);
|
2015-06-12 15:46:36 +00:00
|
|
|
|
|
|
|
//make a deep copy of input and place it into temp
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Float64> temp;
|
2017-05-18 14:29:41 +00:00
|
|
|
Algorithm::Copy(input, temp);
|
2015-06-12 15:46:36 +00:00
|
|
|
|
2017-01-03 20:37:41 +00:00
|
|
|
std::vector<vtkm::Id>::const_iterator c = testData.begin();
|
2020-05-08 15:30:59 +00:00
|
|
|
auto portal = temp.ReadPortal();
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i, ++c)
|
2015-06-12 15:46:36 +00:00
|
|
|
{
|
2020-05-08 15:30:59 +00:00
|
|
|
vtkm::Float64 value = portal.Get(i);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(value == static_cast<vtkm::Float64>(*c), "Got bad value (Copy)");
|
2015-06-12 15:46:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-19 22:42:58 +00:00
|
|
|
static VTKM_CONT void TestAtomicArray()
|
2016-02-10 15:51:31 +00:00
|
|
|
{
|
2017-01-03 20:37:41 +00:00
|
|
|
//we can't use ARRAY_SIZE as that would cause a overflow
|
|
|
|
vtkm::Int32 SHORT_ARRAY_SIZE = 10000;
|
|
|
|
|
2016-03-04 22:46:45 +00:00
|
|
|
vtkm::Int32 atomicCount = 0;
|
2017-05-18 14:29:41 +00:00
|
|
|
for (vtkm::Int32 i = 0; i < SHORT_ARRAY_SIZE; i++)
|
2019-08-22 19:52:58 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
atomicCount += i;
|
2019-08-22 19:52:58 +00:00
|
|
|
}
|
2017-01-03 20:37:41 +00:00
|
|
|
// To test the atomics, SHORT_ARRAY_SIZE number of threads will all increment
|
2016-02-10 15:51:31 +00:00
|
|
|
// a single atomic value.
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::Int32> atomicElement =
|
2020-07-16 16:32:32 +00:00
|
|
|
vtkm::cont::make_ArrayHandle<vtkm::Int32>({ 0 });
|
2016-02-10 15:51:31 +00:00
|
|
|
|
2018-06-07 21:08:02 +00:00
|
|
|
vtkm::cont::AtomicArray<vtkm::Int32> atomic(atomicElement);
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(AtomicKernel<vtkm::Int32>(atomic, token), SHORT_ARRAY_SIZE);
|
|
|
|
}
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Int32 expected = vtkm::Int32(atomicCount);
|
2020-01-28 19:14:32 +00:00
|
|
|
vtkm::Int32 actual = atomicElement.WritePortal().Get(0);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(expected == actual, "Did not get expected value: Atomic add Int32");
|
2016-02-10 15:51:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::Int64> atomicElement =
|
2020-07-16 16:32:32 +00:00
|
|
|
vtkm::cont::make_ArrayHandle<vtkm::Int64>({ 0 });
|
2016-02-10 15:51:31 +00:00
|
|
|
|
2018-06-07 21:08:02 +00:00
|
|
|
vtkm::cont::AtomicArray<vtkm::Int64> atomic(atomicElement);
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(AtomicKernel<vtkm::Int64>(atomic, token), SHORT_ARRAY_SIZE);
|
|
|
|
}
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Int64 expected = vtkm::Int64(atomicCount);
|
2020-01-28 19:14:32 +00:00
|
|
|
vtkm::Int64 actual = atomicElement.WritePortal().Get(0);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(expected == actual, "Did not get expected value: Atomic add Int64");
|
2016-02-10 15:51:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::Int32> atomicElement =
|
2020-07-16 16:32:32 +00:00
|
|
|
vtkm::cont::make_ArrayHandle<vtkm::Int32>({ 0 });
|
2016-02-10 15:51:31 +00:00
|
|
|
|
2018-06-07 21:08:02 +00:00
|
|
|
vtkm::cont::AtomicArray<vtkm::Int32> atomic(atomicElement);
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(AtomicCASKernel<vtkm::Int32>(atomic, token), SHORT_ARRAY_SIZE);
|
|
|
|
}
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Int32 expected = vtkm::Int32(atomicCount);
|
2020-01-28 19:14:32 +00:00
|
|
|
vtkm::Int32 actual = atomicElement.WritePortal().Get(0);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(expected == actual, "Did not get expected value: Atomic CAS Int32");
|
2016-02-10 15:51:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::cont::ArrayHandle<vtkm::Int64> atomicElement =
|
2020-07-16 16:32:32 +00:00
|
|
|
vtkm::cont::make_ArrayHandle<vtkm::Int64>({ 0 });
|
2016-02-10 15:51:31 +00:00
|
|
|
|
2018-06-07 21:08:02 +00:00
|
|
|
vtkm::cont::AtomicArray<vtkm::Int64> atomic(atomicElement);
|
2020-01-21 20:18:03 +00:00
|
|
|
{
|
|
|
|
vtkm::cont::Token token;
|
|
|
|
Algorithm::Schedule(AtomicCASKernel<vtkm::Int64>(atomic, token), SHORT_ARRAY_SIZE);
|
|
|
|
}
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Int64 expected = vtkm::Int64(atomicCount);
|
2020-01-28 19:14:32 +00:00
|
|
|
vtkm::Int64 actual = atomicElement.WritePortal().Get(0);
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_TEST_ASSERT(expected == actual, "Did not get expected value: Atomic CAS Int64");
|
2016-02-10 15:51:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-05 21:47:09 +00:00
|
|
|
static VTKM_CONT void TestBitFieldToUnorderedSet()
|
|
|
|
{
|
|
|
|
using IndexArray = vtkm::cont::ArrayHandle<vtkm::Id>;
|
|
|
|
using WordType = WordTypeDefault;
|
|
|
|
|
|
|
|
// Test that everything works correctly with a partial word at the end.
|
|
|
|
static constexpr vtkm::Id BitsPerWord = static_cast<vtkm::Id>(sizeof(WordType) * CHAR_BIT);
|
|
|
|
// +5 to get a partial word:
|
|
|
|
static constexpr vtkm::Id NumBits = 1024 * BitsPerWord + 5;
|
|
|
|
static constexpr vtkm::Id NumWords = (NumBits + BitsPerWord - 1) / BitsPerWord;
|
|
|
|
|
|
|
|
auto testIndexArray = [](const BitField& bits) {
|
|
|
|
const vtkm::Id numBits = bits.GetNumberOfBits();
|
|
|
|
IndexArray indices;
|
|
|
|
Algorithm::BitFieldToUnorderedSet(bits, indices);
|
|
|
|
Algorithm::Sort(indices);
|
|
|
|
|
2020-01-28 19:14:32 +00:00
|
|
|
auto bitPortal = bits.ReadPortal();
|
|
|
|
auto indexPortal = indices.ReadPortal();
|
2019-03-05 21:47:09 +00:00
|
|
|
|
|
|
|
const vtkm::Id numIndices = indices.GetNumberOfValues();
|
|
|
|
vtkm::Id curIndex = 0;
|
|
|
|
for (vtkm::Id curBit = 0; curBit < numBits; ++curBit)
|
|
|
|
{
|
|
|
|
const bool markedSet = curIndex < numIndices ? indexPortal.Get(curIndex) == curBit : false;
|
|
|
|
const bool isSet = bitPortal.GetBit(curBit);
|
|
|
|
|
|
|
|
// std::cout << "curBit: " << curBit
|
|
|
|
// << " activeIndex: "
|
|
|
|
// << (curIndex < numIndices ? indexPortal.Get(curIndex) : -1)
|
|
|
|
// << " isSet: " << isSet << " markedSet: " << markedSet << "\n";
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(
|
|
|
|
markedSet == isSet, "Bit ", curBit, " is set? ", isSet, " Marked set? ", markedSet);
|
|
|
|
|
|
|
|
if (markedSet)
|
|
|
|
{
|
|
|
|
curIndex++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(curIndex == indices.GetNumberOfValues(), "Index array has extra values.");
|
|
|
|
};
|
|
|
|
|
|
|
|
auto testRepeatedMask = [&](WordType mask) {
|
|
|
|
BitField bits;
|
|
|
|
{
|
|
|
|
bits.Allocate(NumBits);
|
2020-01-28 19:14:32 +00:00
|
|
|
auto fillPortal = bits.WritePortal();
|
2019-03-05 21:47:09 +00:00
|
|
|
for (vtkm::Id i = 0; i < NumWords; ++i)
|
|
|
|
{
|
|
|
|
fillPortal.SetWord(i, mask);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
testIndexArray(bits);
|
|
|
|
};
|
|
|
|
|
|
|
|
auto testRandomMask = [&](WordType seed) {
|
|
|
|
std::mt19937 mt{ seed };
|
|
|
|
std::uniform_int_distribution<std::mt19937::result_type> rng;
|
|
|
|
|
|
|
|
BitField bits;
|
|
|
|
{
|
|
|
|
bits.Allocate(NumBits);
|
2020-01-28 19:14:32 +00:00
|
|
|
auto fillPortal = bits.WritePortal();
|
2019-03-05 21:47:09 +00:00
|
|
|
for (vtkm::Id i = 0; i < NumWords; ++i)
|
|
|
|
{
|
|
|
|
fillPortal.SetWord(i, static_cast<WordType>(rng(mt)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
testIndexArray(bits);
|
|
|
|
};
|
|
|
|
|
|
|
|
testRepeatedMask(0x00000000);
|
|
|
|
testRepeatedMask(0xeeeeeeee);
|
|
|
|
testRepeatedMask(0xffffffff);
|
|
|
|
testRepeatedMask(0x1c0fd395);
|
|
|
|
testRepeatedMask(0xdeadbeef);
|
|
|
|
|
|
|
|
testRandomMask(0x00000000);
|
|
|
|
testRandomMask(0xeeeeeeee);
|
|
|
|
testRandomMask(0xffffffff);
|
|
|
|
testRandomMask(0x1c0fd395);
|
|
|
|
testRandomMask(0xdeadbeef);
|
2019-07-11 16:41:43 +00:00
|
|
|
|
|
|
|
// This case was causing issues on CUDA:
|
|
|
|
{
|
|
|
|
BitField bits;
|
|
|
|
Algorithm::Fill(bits, false, 32 * 32);
|
2020-01-28 19:14:32 +00:00
|
|
|
auto portal = bits.WritePortal();
|
2019-07-11 16:41:43 +00:00
|
|
|
portal.SetWord(2, 0x00100000ul);
|
|
|
|
portal.SetWord(8, 0x00100010ul);
|
|
|
|
portal.SetWord(11, 0x10000000ul);
|
|
|
|
testIndexArray(bits);
|
|
|
|
}
|
2019-03-05 21:47:09 +00:00
|
|
|
}
|
|
|
|
|
2019-06-13 14:04:28 +00:00
|
|
|
static VTKM_CONT void TestCountSetBits()
|
|
|
|
{
|
|
|
|
using WordType = WordTypeDefault;
|
|
|
|
|
|
|
|
// Test that everything works correctly with a partial word at the end.
|
|
|
|
static constexpr vtkm::Id BitsPerWord = static_cast<vtkm::Id>(sizeof(WordType) * CHAR_BIT);
|
|
|
|
// +5 to get a partial word:
|
|
|
|
static constexpr vtkm::Id NumFullWords = 1024;
|
|
|
|
static constexpr vtkm::Id NumBits = NumFullWords * BitsPerWord + 5;
|
|
|
|
static constexpr vtkm::Id NumWords = (NumBits + BitsPerWord - 1) / BitsPerWord;
|
|
|
|
|
|
|
|
auto verifyPopCount = [](const BitField& bits) {
|
|
|
|
vtkm::Id refPopCount = 0;
|
|
|
|
const vtkm::Id numBits = bits.GetNumberOfBits();
|
2020-01-28 19:14:32 +00:00
|
|
|
auto portal = bits.ReadPortal();
|
2019-06-13 14:04:28 +00:00
|
|
|
for (vtkm::Id idx = 0; idx < numBits; ++idx)
|
|
|
|
{
|
|
|
|
if (portal.GetBit(idx))
|
|
|
|
{
|
|
|
|
++refPopCount;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const vtkm::Id popCount = Algorithm::CountSetBits(bits);
|
|
|
|
|
|
|
|
VTKM_TEST_ASSERT(
|
|
|
|
refPopCount == popCount, "CountSetBits returned ", popCount, ", expected ", refPopCount);
|
|
|
|
};
|
|
|
|
|
|
|
|
auto testRepeatedMask = [&](WordType mask) {
|
|
|
|
BitField bits;
|
|
|
|
{
|
|
|
|
bits.Allocate(NumBits);
|
2020-01-28 19:14:32 +00:00
|
|
|
auto fillPortal = bits.WritePortal();
|
2019-06-13 14:04:28 +00:00
|
|
|
for (vtkm::Id i = 0; i < NumWords; ++i)
|
|
|
|
{
|
|
|
|
fillPortal.SetWord(i, mask);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
verifyPopCount(bits);
|
|
|
|
};
|
|
|
|
|
|
|
|
auto testRandomMask = [&](WordType seed) {
|
|
|
|
std::mt19937 mt{ seed };
|
|
|
|
std::uniform_int_distribution<std::mt19937::result_type> rng;
|
|
|
|
|
|
|
|
BitField bits;
|
|
|
|
{
|
|
|
|
bits.Allocate(NumBits);
|
2020-01-28 19:14:32 +00:00
|
|
|
auto fillPortal = bits.WritePortal();
|
2019-06-13 14:04:28 +00:00
|
|
|
for (vtkm::Id i = 0; i < NumWords; ++i)
|
|
|
|
{
|
|
|
|
fillPortal.SetWord(i, static_cast<WordType>(rng(mt)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
verifyPopCount(bits);
|
|
|
|
};
|
|
|
|
|
|
|
|
testRepeatedMask(0x00000000);
|
|
|
|
testRepeatedMask(0xeeeeeeee);
|
|
|
|
testRepeatedMask(0xffffffff);
|
|
|
|
testRepeatedMask(0x1c0fd395);
|
|
|
|
testRepeatedMask(0xdeadbeef);
|
|
|
|
|
|
|
|
testRandomMask(0x00000000);
|
|
|
|
testRandomMask(0xeeeeeeee);
|
|
|
|
testRandomMask(0xffffffff);
|
|
|
|
testRandomMask(0x1c0fd395);
|
|
|
|
testRandomMask(0xdeadbeef);
|
2019-07-11 16:41:43 +00:00
|
|
|
|
|
|
|
// This case was causing issues on CUDA:
|
|
|
|
{
|
|
|
|
BitField bits;
|
|
|
|
Algorithm::Fill(bits, false, 32 * 32);
|
2020-01-28 19:14:32 +00:00
|
|
|
auto portal = bits.WritePortal();
|
2019-07-11 16:41:43 +00:00
|
|
|
portal.SetWord(2, 0x00100000ul);
|
|
|
|
portal.SetWord(8, 0x00100010ul);
|
|
|
|
portal.SetWord(11, 0x10000000ul);
|
|
|
|
verifyPopCount(bits);
|
|
|
|
}
|
2019-06-13 14:04:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename WordType>
|
|
|
|
static VTKM_CONT void TestFillBitFieldMask(WordType mask)
|
|
|
|
{
|
|
|
|
|
|
|
|
// Test that everything works correctly with a partial word at the end.
|
|
|
|
static constexpr vtkm::Id BitsPerWord = static_cast<vtkm::Id>(sizeof(WordType) * CHAR_BIT);
|
|
|
|
// +5 to get a partial word:
|
|
|
|
static constexpr vtkm::Id NumFullWords = 1024;
|
|
|
|
static constexpr vtkm::Id NumBits = NumFullWords * BitsPerWord + 5;
|
|
|
|
static constexpr vtkm::Id NumWords = (NumBits + BitsPerWord - 1) / BitsPerWord;
|
|
|
|
|
|
|
|
vtkm::cont::BitField bits;
|
|
|
|
{
|
|
|
|
Algorithm::Fill(bits, mask, NumBits);
|
|
|
|
|
|
|
|
vtkm::Id numBits = bits.GetNumberOfBits();
|
|
|
|
VTKM_TEST_ASSERT(numBits == NumBits, "Unexpected number of bits.");
|
|
|
|
vtkm::Id numWords = bits.GetNumberOfWords<WordType>();
|
|
|
|
VTKM_TEST_ASSERT(numWords == NumWords, "Unexpected number of words.");
|
|
|
|
|
2020-01-28 19:14:32 +00:00
|
|
|
auto portal = bits.ReadPortal();
|
2019-06-13 14:04:28 +00:00
|
|
|
for (vtkm::Id wordIdx = 0; wordIdx < NumWords; ++wordIdx)
|
|
|
|
{
|
|
|
|
VTKM_TEST_ASSERT(portal.GetWord<WordType>(wordIdx) == mask,
|
|
|
|
"Incorrect word in result BitField; expected 0x",
|
|
|
|
std::hex,
|
|
|
|
vtkm::UInt64{ mask },
|
|
|
|
", got 0x",
|
|
|
|
vtkm::UInt64{ portal.GetWord<WordType>(wordIdx) },
|
|
|
|
std::dec,
|
|
|
|
" for word ",
|
|
|
|
wordIdx,
|
|
|
|
"/",
|
|
|
|
NumWords);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now fill the BitField with the reversed mask to test the no-alloc
|
|
|
|
// overload:
|
|
|
|
{
|
|
|
|
WordType invWord = static_cast<WordType>(~mask);
|
|
|
|
Algorithm::Fill(bits, invWord);
|
|
|
|
|
|
|
|
vtkm::Id numBits = bits.GetNumberOfBits();
|
|
|
|
VTKM_TEST_ASSERT(numBits == NumBits, "Unexpected number of bits.");
|
|
|
|
vtkm::Id numWords = bits.GetNumberOfWords<WordType>();
|
|
|
|
VTKM_TEST_ASSERT(numWords == NumWords, "Unexpected number of words.");
|
|
|
|
|
2020-01-28 19:14:32 +00:00
|
|
|
auto portal = bits.ReadPortal();
|
2019-06-13 14:04:28 +00:00
|
|
|
for (vtkm::Id wordIdx = 0; wordIdx < NumWords; ++wordIdx)
|
|
|
|
{
|
|
|
|
VTKM_TEST_ASSERT(portal.GetWord<WordType>(wordIdx) == invWord,
|
|
|
|
"Incorrect word in result BitField; expected 0x",
|
|
|
|
std::hex,
|
|
|
|
vtkm::UInt64{ invWord },
|
|
|
|
", got 0x",
|
|
|
|
vtkm::UInt64{ portal.GetWord<WordType>(wordIdx) },
|
|
|
|
std::dec,
|
|
|
|
" for word ",
|
|
|
|
wordIdx,
|
|
|
|
"/",
|
|
|
|
NumWords);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static VTKM_CONT void TestFillBitFieldBool(bool value)
|
|
|
|
{
|
|
|
|
|
|
|
|
// Test that everything works correctly with a partial word at the end.
|
|
|
|
// +5 to get a partial word:
|
|
|
|
static constexpr vtkm::Id NumBits = 1024 * 32 + 5;
|
|
|
|
|
|
|
|
vtkm::cont::BitField bits;
|
|
|
|
{
|
|
|
|
Algorithm::Fill(bits, value, NumBits);
|
|
|
|
|
|
|
|
vtkm::Id numBits = bits.GetNumberOfBits();
|
|
|
|
VTKM_TEST_ASSERT(numBits == NumBits, "Unexpected number of bits.");
|
|
|
|
|
2020-01-28 19:14:32 +00:00
|
|
|
auto portal = bits.ReadPortal();
|
2019-06-13 14:04:28 +00:00
|
|
|
for (vtkm::Id bitIdx = 0; bitIdx < NumBits; ++bitIdx)
|
|
|
|
{
|
|
|
|
VTKM_TEST_ASSERT(portal.GetBit(bitIdx) == value, "Incorrect bit in result BitField.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Now fill the BitField with the reversed mask to test the no-alloc
|
|
|
|
// overload:
|
|
|
|
{
|
|
|
|
Algorithm::Fill(bits, !value);
|
|
|
|
|
|
|
|
vtkm::Id numBits = bits.GetNumberOfBits();
|
|
|
|
VTKM_TEST_ASSERT(numBits == NumBits, "Unexpected number of bits.");
|
|
|
|
|
2020-01-28 19:14:32 +00:00
|
|
|
auto portal = bits.ReadPortal();
|
2019-06-13 14:04:28 +00:00
|
|
|
for (vtkm::Id bitIdx = 0; bitIdx < NumBits; ++bitIdx)
|
|
|
|
{
|
|
|
|
VTKM_TEST_ASSERT(portal.GetBit(bitIdx) == !value, "Incorrect bit in result BitField.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static VTKM_CONT void TestFillBitField()
|
|
|
|
{
|
|
|
|
TestFillBitFieldBool(true);
|
|
|
|
TestFillBitFieldBool(false);
|
|
|
|
TestFillBitFieldMask<vtkm::UInt8>(vtkm::UInt8{ 0 });
|
|
|
|
TestFillBitFieldMask<vtkm::UInt8>(static_cast<vtkm::UInt8>(~vtkm::UInt8{ 0 }));
|
|
|
|
TestFillBitFieldMask<vtkm::UInt8>(vtkm::UInt8{ 0xab });
|
|
|
|
TestFillBitFieldMask<vtkm::UInt8>(vtkm::UInt8{ 0x4f });
|
|
|
|
TestFillBitFieldMask<vtkm::UInt16>(vtkm::UInt16{ 0 });
|
|
|
|
TestFillBitFieldMask<vtkm::UInt16>(static_cast<vtkm::UInt16>(~vtkm::UInt16{ 0 }));
|
|
|
|
TestFillBitFieldMask<vtkm::UInt16>(vtkm::UInt16{ 0xfade });
|
|
|
|
TestFillBitFieldMask<vtkm::UInt16>(vtkm::UInt16{ 0xbeef });
|
|
|
|
TestFillBitFieldMask<vtkm::UInt32>(vtkm::UInt32{ 0 });
|
|
|
|
TestFillBitFieldMask<vtkm::UInt32>(static_cast<vtkm::UInt32>(~vtkm::UInt32{ 0 }));
|
|
|
|
TestFillBitFieldMask<vtkm::UInt32>(vtkm::UInt32{ 0xfacecafe });
|
|
|
|
TestFillBitFieldMask<vtkm::UInt32>(vtkm::UInt32{ 0xbaddecaf });
|
|
|
|
TestFillBitFieldMask<vtkm::UInt64>(vtkm::UInt64{ 0 });
|
|
|
|
TestFillBitFieldMask<vtkm::UInt64>(static_cast<vtkm::UInt64>(~vtkm::UInt64{ 0 }));
|
|
|
|
TestFillBitFieldMask<vtkm::UInt64>(vtkm::UInt64{ 0xbaddefacedfacade });
|
|
|
|
TestFillBitFieldMask<vtkm::UInt64>(vtkm::UInt64{ 0xfeeddeadbeef2dad });
|
|
|
|
}
|
|
|
|
|
|
|
|
static VTKM_CONT void TestFillArrayHandle()
|
|
|
|
{
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Int32> handle;
|
|
|
|
Algorithm::Fill(handle, 867, ARRAY_SIZE);
|
|
|
|
|
|
|
|
{
|
2020-01-28 19:14:32 +00:00
|
|
|
auto portal = handle.ReadPortal();
|
2019-06-13 14:04:28 +00:00
|
|
|
VTKM_TEST_ASSERT(portal.GetNumberOfValues() == ARRAY_SIZE);
|
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
|
|
|
|
{
|
|
|
|
VTKM_TEST_ASSERT(portal.Get(i) == 867);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Algorithm::Fill(handle, 5309);
|
|
|
|
{
|
2020-01-28 19:14:32 +00:00
|
|
|
auto portal = handle.ReadPortal();
|
2019-06-13 14:04:28 +00:00
|
|
|
VTKM_TEST_ASSERT(portal.GetNumberOfValues() == ARRAY_SIZE);
|
|
|
|
for (vtkm::Id i = 0; i < ARRAY_SIZE; ++i)
|
|
|
|
{
|
|
|
|
VTKM_TEST_ASSERT(portal.Get(i) == 5309);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-02-11 17:34:56 +00:00
|
|
|
struct TestAll
|
|
|
|
{
|
2016-10-19 22:42:58 +00:00
|
|
|
VTKM_CONT void operator()() const
|
2014-02-11 17:34:56 +00:00
|
|
|
{
|
2020-03-26 23:34:18 +00:00
|
|
|
TestMemoryTransfer();
|
2015-04-16 14:25:44 +00:00
|
|
|
TestOutOfMemory();
|
|
|
|
TestTimer();
|
2017-03-29 14:48:43 +00:00
|
|
|
TestVirtualObjectTransfer();
|
2015-04-16 14:25:44 +00:00
|
|
|
|
|
|
|
TestAlgorithmSchedule();
|
|
|
|
TestErrorExecution();
|
2015-04-28 13:31:50 +00:00
|
|
|
|
|
|
|
TestReduce();
|
2015-04-30 13:01:52 +00:00
|
|
|
TestReduceWithComparisonObject();
|
2015-06-18 19:40:51 +00:00
|
|
|
TestReduceWithFancyArrays();
|
2015-04-28 13:31:50 +00:00
|
|
|
|
2015-05-04 19:53:35 +00:00
|
|
|
TestReduceByKey();
|
2015-06-18 19:40:51 +00:00
|
|
|
TestReduceByKeyWithFancyArrays();
|
2015-05-04 19:53:35 +00:00
|
|
|
|
2015-06-16 12:35:04 +00:00
|
|
|
TestScanExclusive();
|
2019-09-03 15:53:14 +00:00
|
|
|
TestScanExtended();
|
2015-06-16 12:35:04 +00:00
|
|
|
|
2015-04-16 14:25:44 +00:00
|
|
|
TestScanInclusive();
|
2015-04-29 19:48:25 +00:00
|
|
|
TestScanInclusiveWithComparisonObject();
|
|
|
|
|
2017-04-19 19:38:28 +00:00
|
|
|
TestScanInclusiveByKeyOne();
|
|
|
|
TestScanInclusiveByKeyTwo();
|
|
|
|
TestScanInclusiveByKeyLarge();
|
2017-03-29 15:29:11 +00:00
|
|
|
TestScanInclusiveByKey();
|
2020-04-16 16:37:44 +00:00
|
|
|
TestScanInclusiveByKeyInPlace();
|
|
|
|
TestScanInclusiveByKeyInPlaceWithFancyArray();
|
2017-03-29 15:29:11 +00:00
|
|
|
|
2017-04-19 19:38:28 +00:00
|
|
|
TestScanExclusiveByKeyOne();
|
|
|
|
TestScanExclusiveByKeyTwo();
|
|
|
|
TestScanExclusiveByKeyLarge();
|
2017-04-17 21:03:49 +00:00
|
|
|
TestScanExclusiveByKey();
|
2020-04-16 16:37:44 +00:00
|
|
|
TestScanExclusiveByKeyInPlace();
|
|
|
|
TestScanExclusiveByKeyInPlaceWithFancyArray();
|
2017-04-13 17:50:56 +00:00
|
|
|
|
2015-04-16 14:25:44 +00:00
|
|
|
TestSort();
|
|
|
|
TestSortWithComparisonObject();
|
2015-06-18 19:40:51 +00:00
|
|
|
TestSortWithFancyArrays();
|
2015-04-23 17:25:37 +00:00
|
|
|
TestSortByKey();
|
2015-04-28 13:31:50 +00:00
|
|
|
|
2015-04-16 14:25:44 +00:00
|
|
|
TestLowerBoundsWithComparisonObject();
|
2015-04-28 13:31:50 +00:00
|
|
|
|
2015-04-16 14:25:44 +00:00
|
|
|
TestUpperBoundsWithComparisonObject();
|
2015-04-28 13:31:50 +00:00
|
|
|
|
2015-04-16 14:25:44 +00:00
|
|
|
TestUniqueWithComparisonObject();
|
2015-04-28 13:31:50 +00:00
|
|
|
|
2015-04-16 14:25:44 +00:00
|
|
|
TestOrderedUniqueValues(); //tests Copy, LowerBounds, Sort, Unique
|
2017-03-03 22:17:43 +00:00
|
|
|
TestCopyIf();
|
2015-06-12 15:46:36 +00:00
|
|
|
|
2016-05-12 09:59:54 +00:00
|
|
|
TestCopyArraysMany();
|
2015-06-12 15:46:36 +00:00
|
|
|
TestCopyArraysInDiffTypes();
|
2016-02-10 15:51:31 +00:00
|
|
|
|
|
|
|
TestAtomicArray();
|
2019-03-05 21:47:09 +00:00
|
|
|
|
|
|
|
TestBitFieldToUnorderedSet();
|
2019-06-13 14:04:28 +00:00
|
|
|
TestCountSetBits();
|
|
|
|
TestFillBitField();
|
|
|
|
|
|
|
|
TestFillArrayHandle();
|
2014-02-11 17:34:56 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
public:
|
|
|
|
/// Run a suite of tests to check to see if a DeviceAdapter properly supports
|
2015-04-23 17:25:37 +00:00
|
|
|
/// all members and classes required for driving vtkm algorithms. Returns an
|
2014-02-11 17:34:56 +00:00
|
|
|
/// error code that can be returned from the main function of a test.
|
|
|
|
///
|
2019-01-01 22:19:02 +00:00
|
|
|
static VTKM_CONT int Run(int argc, char* argv[])
|
|
|
|
{
|
|
|
|
return vtkm::cont::testing::Testing::Run(TestAll(), argc, argv);
|
|
|
|
}
|
2014-02-11 17:34:56 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
#undef ERROR_MESSAGE
|
|
|
|
#undef ARRAY_SIZE
|
|
|
|
#undef OFFSET
|
|
|
|
#undef DIM
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // namespace vtkm::cont::testing
|
|
|
|
|
2018-06-07 19:34:30 +00:00
|
|
|
#endif //vtk_m_cont_testing_TestingDeviceAdapter_h
|