Commit 9ea10317 authored by Kenneth Moreland's avatar Kenneth Moreland
Browse files

Add passing input domain to transport operator

Previously, the operator for a Transport class took the object being
transported to the execution environment and the size of the output
domain. This change also passes in the control-side argument for the
input domain. This will help check input array sizes as well as make
other potential transformations based on the input domain.
parent d5c80802
......@@ -27,6 +27,7 @@ set(headers
TransportTagAtomicArray.h
TransportTagCellSetIn.h
TransportTagExecObject.h
TransportTagTopologyFieldIn.h
TransportTagWholeArrayIn.h
TransportTagWholeArrayInOut.h
TransportTagWholeArrayOut.h
......
......@@ -62,11 +62,17 @@ struct Transport
/// All \c Transport specializations are expected to have a constant
/// parenthesis operator that takes the data in the control environment and
/// returns an object that is accessible in the execution environment. The
/// operator also has a second argument that is the size of the dispatch that
/// can be used, for example, to allocate data for an output array.
/// second argument of the operator is a reference to the input domain
/// argument. This might be useful for checking the sizes of input data. The
/// third argument is the size of the output domain, which can be used, for
/// example, to allocate data for an output array. The transport might ignore
/// either or both of the second two arguments.
///
template<typename InputDomainType>
VTKM_CONT
ExecObjectType operator()(const ContObjectType contData, vtkm::Id size) const;
ExecObjectType operator()(const ContObjectType contData,
const InputDomainType &inputDomain
vtkm::Id outputSize) const;
};
#else // VTKM_DOXYGEN_ONLY
;
......
......@@ -40,18 +40,25 @@ struct TransportTagArrayIn { };
template<typename ContObjectType, typename Device>
struct Transport<vtkm::cont::arg::TransportTagArrayIn, ContObjectType, Device>
{
///\todo: something equivalent to VTKM_IS_ARRAY_HANDLE(ContObjectType);
VTKM_IS_ARRAY_HANDLE(ContObjectType);
typedef typename ContObjectType::template ExecutionTypes<Device>::PortalConst
ExecObjectType;
template<typename InputDomainType>
VTKM_CONT
ExecObjectType operator()(const ContObjectType &object, vtkm::Id) const
ExecObjectType operator()(const ContObjectType &object,
const InputDomainType &inputDomain,
vtkm::Id) const
{
// TODO: Throw an exception if object.GetNumberOfValues() does not equal
// the size passed into this operator. Currently, the size passed into
// this method is sometimes wrong (for example with point fields when
// mapping on cells).
// This transport expects the input domain to be an array handle.
VTKM_IS_ARRAY_HANDLE(InputDomainType);
if (object.GetNumberOfValues() != inputDomain.GetNumberOfValues())
{
throw vtkm::cont::ErrorControlBadValue(
"Input array to worklet invocation the wrong size.");
}
return object.PrepareForInput(Device());
}
......
......@@ -48,8 +48,11 @@ struct Transport<vtkm::cont::arg::TransportTagArrayInOut, ContObjectType, Device
typedef typename ContObjectType::template ExecutionTypes<Device>::Portal
ExecObjectType;
template<typename InputDomainType>
VTKM_CONT
ExecObjectType operator()(ContObjectType object, vtkm::Id size) const
ExecObjectType operator()(ContObjectType object,
const InputDomainType &,
vtkm::Id size) const
{
if (object.GetNumberOfValues() != size)
{
......
......@@ -47,8 +47,11 @@ struct Transport<vtkm::cont::arg::TransportTagArrayOut, ContObjectType, Device>
typedef typename ContObjectType::template ExecutionTypes<Device>::Portal
ExecObjectType;
template<typename InputDomainType>
VTKM_CONT
ExecObjectType operator()(ContObjectType object, vtkm::Id size) const
ExecObjectType operator()(ContObjectType object,
const InputDomainType &,
vtkm::Id size) const
{
return object.PrepareForOutput(size, Device());
}
......
......@@ -51,9 +51,11 @@ struct Transport<
{
typedef vtkm::exec::AtomicArray<T, Device> ExecObjectType;
template<typename InputDomainType>
VTKM_CONT
ExecObjectType operator()(
vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic> array,
const InputDomainType &,
vtkm::Id) const
{
// Note: we ignore the size of the domain because the randomly accessed
......
......@@ -40,7 +40,8 @@ struct TransportTagCellSetIn { };
template<typename FromTopology,
typename ToTopology,
typename ContObjectType, typename Device>
typename ContObjectType,
typename Device>
struct Transport<vtkm::cont::arg::TransportTagCellSetIn<FromTopology,ToTopology>, ContObjectType, Device>
{
VTKM_IS_CELL_SET(ContObjectType);
......@@ -50,10 +51,12 @@ struct Transport<vtkm::cont::arg::TransportTagCellSetIn<FromTopology,ToTopology>
Device,FromTopology,ToTopology>
::ExecObjectType ExecObjectType;
template<typename InputDomainType>
VTKM_CONT
ExecObjectType operator()(const ContObjectType &object, vtkm::Id) const
ExecObjectType operator()(const ContObjectType &object,
const InputDomainType &,
vtkm::Id) const
{
//create CUDA version of connectivity array.
return object.PrepareForInput(Device(),
FromTopology(),
ToTopology());
......
......@@ -44,14 +44,17 @@ struct Transport<vtkm::cont::arg::TransportTagExecObject,ContObjectType,Device>
// is not an execution object as an argument that is expected to be one. All
// execution objects are expected to inherit from
// vtkm::exec::ExecutionObjectBase.
static_assert(
std::is_base_of<vtkm::exec::ExecutionObjectBase, ContObjectType>::value,
VTKM_STATIC_ASSERT_MSG(
(std::is_base_of<vtkm::exec::ExecutionObjectBase, ContObjectType>::value),
"All execution objects are expected to inherit from vtkm::exec::ExecutionObjectBase");
typedef ContObjectType ExecObjectType;
template<typename InputDomainType>
VTKM_CONT
ExecObjectType operator()(const ContObjectType &object, vtkm::Id) const
ExecObjectType operator()(const ContObjectType &object,
const InputDomainType &,
vtkm::Id) const
{
return object;
}
......
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_arg_TransportTagTopologyFieldIn_h
#define vtk_m_cont_arg_TransportTagTopologyFieldIn_h
#include <vtkm/TopologyElementTag.h>
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/CellSet.h>
#include <vtkm/cont/arg/Transport.h>
namespace vtkm {
namespace cont {
namespace arg {
/// \brief \c Transport tag for input arrays in topology maps.
///
/// \c TransportTagTopologyFieldIn is a tag used with the \c Transport class to
/// transport \c ArrayHandle objects for input data. The transport is templated
/// on a topology element tag and expects a cell set input domain to check the
/// size of the input array.
///
template<typename TopologyElementTag>
struct TransportTagTopologyFieldIn { };
namespace detail {
VTKM_CONT
inline static vtkm::Id TopologyDomainSize(const vtkm::cont::CellSet &cellSet,
vtkm::TopologyElementTagPoint)
{
return cellSet.GetNumberOfPoints();
}
VTKM_CONT
inline static vtkm::Id TopologyDomainSize(const vtkm::cont::CellSet &cellSet,
vtkm::TopologyElementTagCell)
{
return cellSet.GetNumberOfCells();
}
VTKM_CONT
inline static vtkm::Id TopologyDomainSize(const vtkm::cont::CellSet &cellSet,
vtkm::TopologyElementTagFace)
{
return cellSet.GetNumberOfFaces();
}
VTKM_CONT
inline static vtkm::Id TopologyDomainSize(const vtkm::cont::CellSet &cellSet,
vtkm::TopologyElementTagEdge)
{
return cellSet.GetNumberOfEdges();
}
} // namespace detail
template<typename TopologyElementTag, typename ContObjectType, typename Device>
struct Transport<
vtkm::cont::arg::TransportTagTopologyFieldIn<TopologyElementTag>,
ContObjectType,
Device>
{
VTKM_IS_ARRAY_HANDLE(ContObjectType);
typedef typename ContObjectType::template ExecutionTypes<Device>::PortalConst
ExecObjectType;
VTKM_CONT
ExecObjectType operator()(const ContObjectType &object,
const vtkm::cont::CellSet &inputDomain,
vtkm::Id) const
{
if (object.GetNumberOfValues() !=
detail::TopologyDomainSize(inputDomain, TopologyElementTag()))
{
throw vtkm::cont::ErrorControlBadValue(
"Input array to worklet invocation the wrong size.");
}
return object.PrepareForInput(Device());
}
};
}
}
} // namespace vtkm::cont::arg
#endif //vtk_m_cont_arg_TransportTagTopologyFieldIn_h
......@@ -56,8 +56,11 @@ struct Transport<
typedef vtkm::exec::ExecutionWholeArrayConst<ValueType, StorageTag, Device>
ExecObjectType;
template<typename InputDomainType>
VTKM_CONT
ExecObjectType operator()(ContObjectType array, vtkm::Id) const
ExecObjectType operator()(ContObjectType array,
const InputDomainType &,
vtkm::Id) const
{
// Note: we ignore the size of the domain because the randomly accessed
// array might not have the same size depending on how the user is using
......
......@@ -58,8 +58,11 @@ struct Transport<
typedef vtkm::exec::ExecutionWholeArray<ValueType, StorageTag, Device>
ExecObjectType;
template<typename InputDomainType>
VTKM_CONT
ExecObjectType operator()(ContObjectType array, vtkm::Id) const
ExecObjectType operator()(ContObjectType array,
const InputDomainType &,
vtkm::Id) const
{
// Note: we ignore the size of the domain because the randomly accessed
// array might not have the same size depending on how the user is using
......
......@@ -58,8 +58,11 @@ struct Transport<
typedef vtkm::exec::ExecutionWholeArray<ValueType, StorageTag, Device>
ExecObjectType;
template<typename InputDomainType>
VTKM_CONT
ExecObjectType operator()(ContObjectType array, vtkm::Id) const
ExecObjectType operator()(ContObjectType array,
const InputDomainType &,
vtkm::Id) const
{
// Note: we ignore the size of the domain because the randomly accessed
// array might not have the same size depending on how the user is using
......
......@@ -70,7 +70,7 @@ struct TryArrayInType
transport;
TestKernel<PortalType> kernel;
kernel.Portal = transport(handle, ARRAY_SIZE);
kernel.Portal = transport(handle, handle, ARRAY_SIZE);
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(kernel, ARRAY_SIZE);
}
......
......@@ -68,7 +68,7 @@ struct TryArrayInOutType
transport;
TestKernel<PortalType> kernel;
kernel.Portal = transport(handle, ARRAY_SIZE);
kernel.Portal = transport(handle, handle, ARRAY_SIZE);
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(kernel, ARRAY_SIZE);
......
......@@ -23,6 +23,7 @@
#include <vtkm/exec/FunctorBase.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleIndex.h>
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
#include <vtkm/cont/testing/Testing.h>
......@@ -61,7 +62,9 @@ struct TryArrayOutType
transport;
TestKernel<PortalType> kernel;
kernel.Portal = transport(handle, ARRAY_SIZE);
kernel.Portal = transport(handle,
vtkm::cont::ArrayHandleIndex(ARRAY_SIZE),
ARRAY_SIZE);
VTKM_TEST_ASSERT(handle.GetNumberOfValues() == ARRAY_SIZE,
"ArrayOut transport did not allocate array correctly.");
......
......@@ -84,7 +84,7 @@ void TransportWholeCellSetIn(Device)
transport;
TestKernel<ExecObjectType> kernel;
kernel.CellSet = transport(contObject, 1);
kernel.CellSet = transport(contObject, nullptr, 1);
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(kernel, 1);
}
......
......@@ -61,7 +61,7 @@ void TryExecObjectTransport(Device)
transport;
TestKernel kernel;
kernel.Object = transport(contObject, 1);
kernel.Object = transport(contObject, nullptr, 1);
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(kernel, 1);
}
......
......@@ -131,7 +131,7 @@ struct TryWholeArrayType
std::cout << "Check Transport WholeArrayOut" << std::endl;
TestOutKernel<typename OutTransportType::ExecObjectType> outKernel;
outKernel.Portal = OutTransportType()(array, -1);
outKernel.Portal = OutTransportType()(array, nullptr, -1);
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(outKernel, ARRAY_SIZE);
......@@ -139,13 +139,13 @@ struct TryWholeArrayType
std::cout << "Check Transport WholeArrayIn" << std::endl;
TestInKernel<typename InTransportType::ExecObjectType> inKernel;
inKernel.Portal = InTransportType()(array, -1);
inKernel.Portal = InTransportType()(array, nullptr, -1);
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(inKernel, ARRAY_SIZE);
std::cout << "Check Transport WholeArrayInOut" << std::endl;
TestInOutKernel<typename InOutTransportType::ExecObjectType> inOutKernel;
inOutKernel.Portal = InOutTransportType()(array, -1);
inOutKernel.Portal = InOutTransportType()(array, nullptr, -1);
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(inOutKernel, ARRAY_SIZE);
......@@ -180,7 +180,7 @@ struct TryAtomicArrayType
std::cout << "Check Transport AtomicArray" << std::endl;
TestAtomicKernel<typename TransportType::ExecObjectType>
kernel(TransportType()(array, -1));
kernel(TransportType()(array, nullptr, -1));
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(kernel, ARRAY_SIZE);
......
......@@ -36,13 +36,13 @@ class DispatcherMapTopology :
public vtkm::worklet::internal::DispatcherBase<
DispatcherMapTopology<WorkletType,Device>,
WorkletType,
vtkm::worklet::WorkletMapTopologyBase
vtkm::worklet::detail::WorkletMapTopologyBase
>
{
typedef vtkm::worklet::internal::DispatcherBase<
DispatcherMapTopology<WorkletType,Device>,
WorkletType,
vtkm::worklet::WorkletMapTopologyBase
vtkm::worklet::detail::WorkletMapTopologyBase
> Superclass;
public:
......
......@@ -265,12 +265,16 @@ private:
const ParameterInterfaceType &parameters = invocation.Parameters;
typedef vtkm::worklet::internal::detail::DispatcherBaseTransportFunctor<
typename Invocation::ControlInterface, DeviceAdapter> TransportFunctorType;
typename Invocation::ControlInterface,
typename Invocation::InputDomainType,
DeviceAdapter> TransportFunctorType;
typedef typename ParameterInterfaceType::template StaticTransformType<
TransportFunctorType>::type ExecObjectParameters;
ExecObjectParameters execObjectParameters =
parameters.StaticTransformCont(TransportFunctorType(outputRange));
parameters.StaticTransformCont(TransportFunctorType(
invocation.GetInputDomain(),
outputRange));
// Get the arrays used for scattering input to output.
typename WorkletType::ScatterType::OutputToInputMapType outputToInputMap =
......
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