vtk-m/vtkm/cont/CellLocatorPartitioned.cxx
Kenneth Moreland 54f0ef2a88 Support providing a Token to ReadPortal and WritePortal
When managing portals in the execution environment, `ArrayHandle` uses the
`Token` object to ensure that the memory associated with a portal exists
for the length of time that it is needed. This is done by creating the
portal with a `Token` object, and the associated portal objects are
guaranteed to be valid while that `Token` object exists. This is supported
by essentially locking the array from further changes.

`Token` objects are typically used when creating a control-side portal with
the `ReadPortal` or `WritePortal`. This is not to say that a `Token` would
not be useful; a control-side portal going out of scope is definitely a
problem. But the creation and distruction of portals in the control
environment is generally too much work for the possible benefits.

However, under certain circumstances it could be useful to use a `Token` to
get a control-side portal. For example, if the `PrepareForExecution` method
of an `ExecutionObjectBase` needs to fill a small `ArrayHandle` on the
control side to pass to the execution side, it would be better to use the
provided `Token` object when doing so. This change allows you to optionally
provide that `Token` when creating these control-side portals.
2022-11-01 09:29:17 -06:00

88 lines
2.8 KiB
C++

//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/CellLocatorPartitioned.h>
#include <vtkm/cont/PartitionedDataSet.h>
#include <vtkm/exec/CellLocatorPartitioned.h>
namespace vtkm
{
namespace cont
{
void CellLocatorPartitioned::Update()
{
if (this->Modified)
{
this->Build();
this->Modified = false;
}
}
void CellLocatorPartitioned::Build()
{
vtkm::Id numPartitions = this->Partitions.GetNumberOfPartitions();
this->LocatorsCont.resize(numPartitions);
this->GhostsCont.resize(numPartitions);
for (vtkm::Id index = 0; index < numPartitions; ++index)
{
const vtkm::cont::DataSet& dataset = this->Partitions.GetPartition(index);
// fill vector of cellLocators
vtkm::cont::CellLocatorGeneral cellLocator;
cellLocator.SetCellSet(dataset.GetCellSet());
cellLocator.SetCoordinates(dataset.GetCoordinateSystem());
cellLocator.Update();
this->LocatorsCont.at(index) = cellLocator;
// fill vector of ghostFields
vtkm::cont::ArrayHandle<vtkm::UInt8> ghostArrayHandle;
if (dataset.HasCellField("vtkGhostType"))
{
dataset.GetField("vtkGhostType").GetData().AsArrayHandle(ghostArrayHandle);
}
else
{
vtkm::cont::ArrayCopy(
vtkm::cont::ArrayHandleConstant<vtkm::UInt8>(0, dataset.GetNumberOfCells()),
ghostArrayHandle);
}
this->GhostsCont.at(index) = ghostArrayHandle;
}
}
const vtkm::exec::CellLocatorPartitioned CellLocatorPartitioned::PrepareForExecution(
vtkm::cont::DeviceAdapterId device,
vtkm::cont::Token& token)
{
this->Update();
vtkm::Id numPartitions = this->Partitions.GetNumberOfPartitions();
this->LocatorsExec.Allocate(numPartitions, vtkm::CopyFlag::Off, token);
auto portalLocators = this->LocatorsExec.WritePortal(token);
this->GhostsExec.Allocate(numPartitions, vtkm::CopyFlag::Off, token);
auto portalGhosts = this->GhostsExec.WritePortal(token);
for (vtkm::Id index = 0; index < numPartitions; ++index)
{
// fill arrayhandle of cellLocators
portalLocators.Set(index, this->LocatorsCont.at(index).PrepareForExecution(device, token));
// fill arrayhandle of ghostFields
portalGhosts.Set(index, this->GhostsCont.at(index).PrepareForInput(device, token));
}
return vtkm::exec::CellLocatorPartitioned(this->LocatorsExec.PrepareForInput(device, token),
this->GhostsExec.PrepareForInput(device, token));
}
} // namespace cont
} //namespace vtkm