Commit 72b85559 authored by Kenneth Moreland's avatar Kenneth Moreland

Add ReducedValues[In][Out] tags to WorkletReduceByKey

parent ffa3b167
......@@ -31,6 +31,7 @@ set(headers
TransportTagKeyedValuesInOut.h
TransportTagKeyedValuesOut.h
TransportTagKeysIn.h
TransportTagReducedValuesIn.h
TransportTagTopologyFieldIn.h
TransportTagWholeArrayIn.h
TransportTagWholeArrayInOut.h
......
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2016 Sandia Corporation.
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_arg_TransportTagReducedValuesIn_h
#define vtk_m_cont_arg_TransportTagReducedValuesIn_h
#include <vtkm/cont/arg/Transport.h>
namespace vtkm {
namespace cont {
namespace arg {
/// \brief \c Transport tag for input values in a reduce by key.
///
/// \c TransportTagReducedValuesIn is a tag used with the \c Transport class to
/// transport \c ArrayHandle objects for input values that correspond to arrays
/// of reduced values. The values are passed 1-to-1 to the worklet invocations.
///
struct TransportTagReducedValuesIn { };
// Specialization of Transport class for TransportTagReducedValuesIn is
// implemented in vtkm/worklet/Keys.h. That class is not accessible from here
// due to VTK-m package dependencies.
}
}
}
#endif //vtk_m_cont_arg_TransportTagReducedValuesIn_h
......@@ -34,6 +34,7 @@
#include <vtkm/cont/arg/TransportTagKeyedValuesInOut.h>
#include <vtkm/cont/arg/TransportTagKeyedValuesOut.h>
#include <vtkm/cont/arg/TransportTagKeysIn.h>
#include <vtkm/cont/arg/TransportTagReducedValuesIn.h>
#include <vtkm/cont/arg/TypeCheckTagKeys.h>
#include <vtkm/BinaryOperators.h>
......@@ -348,6 +349,31 @@ struct Transport<
}
};
template<typename ContObjectType, typename Device>
struct Transport<
vtkm::cont::arg::TransportTagReducedValuesIn, ContObjectType, Device>
{
VTKM_IS_ARRAY_HANDLE(ContObjectType);
typedef typename ContObjectType::template ExecutionTypes<Device>::PortalConst
ExecObjectType;
template<typename KeyType>
VTKM_CONT
ExecObjectType operator()(const ContObjectType &object,
const vtkm::worklet::Keys<KeyType> &inputDomain,
vtkm::Id) const
{
if (object.GetNumberOfValues() != inputDomain.GetInputRange())
{
throw vtkm::cont::ErrorControlBadValue(
"Input array to worklet invocation the wrong size.");
}
return object.PrepareForInput(Device());
}
};
}
}
} // namespace vtkm::cont::arg
......
......@@ -22,10 +22,14 @@
#include <vtkm/worklet/internal/WorkletBase.h>
#include <vtkm/cont/arg/TransportTagArrayIn.h>
#include <vtkm/cont/arg/TransportTagArrayInOut.h>
#include <vtkm/cont/arg/TransportTagArrayOut.h>
#include <vtkm/cont/arg/TransportTagKeyedValuesIn.h>
#include <vtkm/cont/arg/TransportTagKeyedValuesInOut.h>
#include <vtkm/cont/arg/TransportTagKeyedValuesOut.h>
#include <vtkm/cont/arg/TransportTagKeysIn.h>
#include <vtkm/cont/arg/TransportTagReducedValuesIn.h>
#include <vtkm/cont/arg/TypeCheckTagArray.h>
#include <vtkm/cont/arg/TypeCheckTagKeys.h>
......@@ -109,6 +113,57 @@ public:
using FetchTag = vtkm::exec::arg::FetchTagArrayDirectIn;
};
/// \brief A control signature tag for reduced output values.
///
/// A \c WorkletReduceByKey operates by collecting all identical keys and
/// calling one instance of the worklet for those identical keys. The worklet
/// then produces a "reduced" value per key.
///
/// This tag specifies an \c ArrayHandle object that holds the values. It is
/// an input array with entries for each reduced value. This could be useful
/// to access values from a previous run of WorkletReduceByKey.
///
template<typename TypeList = AllTypes>
struct ReducedValuesIn : vtkm::cont::arg::ControlSignatureTagBase
{
using TypeCheckTag = vtkm::cont::arg::TypeCheckTagArray<TypeList>;
using TransportTag = vtkm::cont::arg::TransportTagReducedValuesIn;
using FetchTag = vtkm::exec::arg::FetchTagArrayDirectIn;
};
/// \brief A control signature tag for reduced output values.
///
/// A \c WorkletReduceByKey operates by collecting all identical keys and
/// calling one instance of the worklet for those identical keys. The worklet
/// then produces a "reduced" value per key.
///
/// This tag specifies an \c ArrayHandle object that holds the values. It is
/// an input/output array with entries for each reduced value. This could be
/// useful to access values from a previous run of WorkletReduceByKey.
///
template<typename TypeList = AllTypes>
struct ReducedValuesInOut : vtkm::cont::arg::ControlSignatureTagBase
{
using TypeCheckTag = vtkm::cont::arg::TypeCheckTagArray<TypeList>;
using TransportTag = vtkm::cont::arg::TransportTagArrayInOut;
using FetchTag = vtkm::exec::arg::FetchTagArrayDirectInOut;
};
/// \brief A control signature tag for reduced output values.
///
/// A \c WorkletReduceByKey operates by collecting all identical keys and
/// calling one instance of the worklet for those identical keys. The worklet
/// then produces a "reduced" value per key. This tag specifies an \c
/// ArrayHandle object that holds the values.
///
template<typename TypeList = AllTypes>
struct ReducedValuesOut : vtkm::cont::arg::ControlSignatureTagBase
{
using TypeCheckTag = vtkm::cont::arg::TypeCheckTagArray<TypeList>;
using TransportTag = vtkm::cont::arg::TransportTagArrayOut;
using FetchTag = vtkm::exec::arg::FetchTagArrayDirectOut;
};
/// \brief The \c ExecutionSignature tag to get the number of values.
///
/// A \c WorkletReduceByKey operates by collecting all values associated with
......
......@@ -49,7 +49,7 @@ static const vtkm::Id ARRAY_SIZE = 1033;
static const vtkm::IdComponent GROUP_SIZE = 10;
static const vtkm::Id NUM_UNIQUE = ARRAY_SIZE/GROUP_SIZE;
struct CheckReduceByKeyWorklet : vtkm::worklet::WorkletReduceByKey
struct CheckKeyValuesWorklet : vtkm::worklet::WorkletReduceByKey
{
typedef void ControlSignature(KeysIn keys,
ValuesIn<> keyMirror,
......@@ -98,6 +98,35 @@ struct CheckReduceByKeyWorklet : vtkm::worklet::WorkletReduceByKey
}
};
struct CheckReducedValuesWorklet : vtkm::worklet::WorkletReduceByKey
{
typedef void ControlSignature(KeysIn,
ReducedValuesOut<> extractKeys,
ReducedValuesIn<> indexReference,
ReducedValuesInOut<> copyKeyPair);
typedef void ExecutionSignature(_1, _2, _3, _4, WorkIndex);
template<typename T>
VTKM_EXEC
void operator()(const T &key,
T &reducedValueOut,
vtkm::Id indexReference,
vtkm::Pair<T,T> &copyKeyPair,
vtkm::Id workIndex) const
{
// This check only work if keys are in sorted order, which is how we group
// them.
TEST_ASSERT_WORKLET(key == TestValue(workIndex, T()));
reducedValueOut = key;
TEST_ASSERT_WORKLET(indexReference == workIndex);
TEST_ASSERT_WORKLET(copyKeyPair.first == key);
copyKeyPair.second = key;
}
};
template<typename KeyType>
void TryKeyType(KeyType)
{
......@@ -119,12 +148,13 @@ void TryKeyType(KeyType)
vtkm::cont::ArrayHandle<KeyType> writeKey;
vtkm::worklet::DispatcherReduceByKey<CheckReduceByKeyWorklet> dispatcher;
dispatcher.Invoke(keys,
keyArray,
vtkm::cont::ArrayHandleIndex(ARRAY_SIZE),
valuesToModify,
writeKey);
vtkm::worklet::DispatcherReduceByKey<CheckKeyValuesWorklet>
dispatcherCheckKeyValues;
dispatcherCheckKeyValues.Invoke(keys,
keyArray,
vtkm::cont::ArrayHandleIndex(ARRAY_SIZE),
valuesToModify,
writeKey);
VTKM_TEST_ASSERT(valuesToModify.GetNumberOfValues() == ARRAY_SIZE,
"Bad array size.");
......@@ -144,6 +174,27 @@ void TryKeyType(KeyType)
test_equal(key, writeKey.GetPortalConstControl().Get(index)),
"Bad out value.");
}
vtkm::cont::ArrayHandle<KeyType> keyPairIn;
keyPairIn.Allocate(NUM_UNIQUE);
SetPortal(keyPairIn.GetPortalControl());
vtkm::cont::ArrayHandle<KeyType> keyPairOut;
keyPairOut.Allocate(NUM_UNIQUE);
vtkm::worklet::DispatcherReduceByKey<CheckReducedValuesWorklet>
dispatcherCheckReducedValues;
dispatcherCheckReducedValues.Invoke(
keys,
writeKey,
vtkm::cont::ArrayHandleIndex(NUM_UNIQUE),
vtkm::cont::make_ArrayHandleZip(keyPairIn, keyPairOut));
VTKM_TEST_ASSERT(writeKey.GetNumberOfValues() == NUM_UNIQUE,
"Reduced values output not sized correctly.");
CheckPortal(writeKey.GetPortalConstControl());
CheckPortal(keyPairOut.GetPortalConstControl());
}
void TestReduceByKey()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment