Commit 84311a24 authored by Robert Maynard's avatar Robert Maynard

Merge branch 'master' into cmake_refactor

parents 83b360f1 84a772c3
......@@ -215,7 +215,7 @@ function(vtkm_declare_headers)
#TODO: look at the testable and cuda options
set(options CUDA)
set(oneValueArgs TESTABLE)
set(multiValueArgs)
set(multiValueArgs EXCLUDE_FROM_TESTING)
cmake_parse_arguments(VTKm_DH "${options}"
"${oneValueArgs}" "${multiValueArgs}"
${ARGN}
......@@ -229,11 +229,15 @@ function(vtkm_declare_headers)
set(VTKm_DH_TESTABLE ON)
endif()
set(hfiles ${VTKm_DH_UNPARSED_ARGUMENTS})
set(hfiles ${VTKm_DH_UNPARSED_ARGUMENTS} ${VTKm_DH_EXCLUDE_FROM_TESTING})
vtkm_get_kit_name(name dir_prefix)
#only do header testing if enable testing is turned on
if (VTKm_ENABLE_TESTING AND VTKm_DH_TESTABLE)
set_source_files_properties(${VTKm_DH_EXCLUDE_FROM_TESTING}
PROPERTIES VTKm_CANT_BE_HEADER_TESTED TRUE
)
vtkm_add_header_build_test(
"${name}" "${dir_prefix}" "${VTKm_DH_CUDA}" ${hfiles})
endif()
......@@ -241,19 +245,6 @@ function(vtkm_declare_headers)
vtkm_install_headers("${dir_prefix}" ${hfiles})
endfunction(vtkm_declare_headers)
#-----------------------------------------------------------------------------
function(vtkm_install_template_sources)
set(hfiles ${ARGN})
vtkm_get_kit_name(name dir_prefix)
# CMake does not add installed files as project files, and template sources
# are not declared as source files anywhere, add a fake target here to let
# an IDE know that these sources exist.
add_custom_target(${name}_template_srcs SOURCES ${hfiles})
vtkm_install_headers("${dir_prefix}" ${hfiles})
endfunction(vtkm_install_template_sources)
#-----------------------------------------------------------------------------
# Add a VTK-m library. The name of the library will match the "kit" name
# (e.g. vtkm_rendering) unless the NAME argument is given.
......@@ -318,10 +309,9 @@ function(vtkm_library)
vtkm_generate_export_header(${lib_name})
#test and install the headers
vtkm_declare_headers(${VTKm_LIB_HEADERS})
#install the template sources
vtkm_install_template_sources(${VTKm_LIB_TEMPLATE_SOURCES})
vtkm_declare_headers(${VTKm_LIB_HEADERS}
EXCLUDE_FROM_TESTING ${VTKm_LIB_TEMPLATE_SOURCES}
)
#install the library itself
install(TARGETS ${lib_name}
......
......@@ -132,9 +132,7 @@ std::string fieldName = "pointvar";
// Create an isosurface filter
vtkm::filter::MarchingCubes filter;
filter.SetIsoValue(0, isovalue);
vtkm::filter::Result result = filter.Execute( inputData,
inputData.GetField(fieldName) );
filter.MapFieldOntoOutput(result, inputData.GetField(fieldName));
vtkm::cont::DataSet outputData = filter.Execute(inputData);
// compute the bounds and extends of the input data
vtkm::Bounds coordsBounds = inputData.GetCoordinateSystem().GetBounds();
......@@ -162,7 +160,6 @@ vtkm::rendering::CanvasRayTracer canvas(512, 512);
vtkm::rendering::Color bg(0.2f, 0.2f, 0.2f, 1.0f);
// Render an image of the output isosurface
vtkm::cont::DataSet& outputData = result.GetDataSet();
scene.AddActor(vtkm::rendering::Actor(outputData.GetCellSet(),
outputData.GetCoordinateSystem(),
outputData.GetField(fieldName),
......
......@@ -119,9 +119,8 @@ int main(int argc, char* argv[])
filter.SetGenerateNormals(false);
filter.SetMergeDuplicatePoints(false);
filter.SetIsoValue(0, isovalue);
vtkm::filter::Result result = filter.Execute(inputData, inputData.GetField(fieldName));
filter.MapFieldOntoOutput(result, inputData.GetField(fieldName));
vtkm::cont::DataSet& outputData = result.GetDataSet();
filter.SetActiveField(fieldName);
vtkm::cont::DataSet outputData = filter.Execute(inputData);
// Render a separate image with the output isosurface
std::cout << "about to render the results of the MarchingCubes filter" << std::endl;
vtkm::rendering::Scene scene2;
......
......@@ -126,9 +126,9 @@ class GameOfLife : public vtkm::filter::FilterDataSet<GameOfLife>
public:
template <typename Policy, typename Device>
VTKM_CONT vtkm::filter::Result DoExecute(const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<Policy> policy,
Device)
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
vtkm::filter::PolicyBase<Policy> policy,
Device)
{
if (!this->PrintedDeviceMsg)
......@@ -166,11 +166,11 @@ public:
vtkm::cont::Field stateField("state", vtkm::cont::Field::ASSOC_POINTS, state);
output.AddField(stateField);
return vtkm::filter::Result(output);
return output;
}
template <typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
VTKM_CONT bool DoMapField(vtkm::filter::Result&,
VTKM_CONT bool DoMapField(vtkm::cont::DataSet&,
const vtkm::cont::ArrayHandle<T, StorageType>&,
const vtkm::filter::FieldMetadata&,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
......
......@@ -201,14 +201,11 @@ int main(int argc, char* argv[])
vtkm::filter::MarchingCubes filter;
filter.SetGenerateNormals(true);
filter.SetMergeDuplicatePoints(false);
filter.SetActiveField("nodevar");
filter.SetIsoValue(0.5);
vtkm::filter::Result result = filter.Execute(dataSet, dataSet.GetField("nodevar"));
filter.MapFieldOntoOutput(result, dataSet.GetField("nodevar"));
auto outputData = filter.Execute(dataSet);
//need to extract vertices, normals, and scalars
vtkm::cont::DataSet& outputData = result.GetDataSet();
using VertType = vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>>;
vtkm::cont::CoordinateSystem coords = outputData.GetCoordinateSystem();
......
......@@ -239,6 +239,17 @@ struct SynchronizeFunctor
}
};
struct TransformFunctor
{
template <typename Device, typename... Args>
VTKM_CONT bool operator()(Device, Args&&... args) const
{
VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::cont::DeviceAdapterAlgorithm<Device>::Transform(std::forward<Args>(args)...);
return true;
}
};
struct UniqueFunctor
{
template <typename Device, typename... Args>
......@@ -494,6 +505,21 @@ struct Algorithm
VTKM_CONT static void Synchronize() { vtkm::cont::TryExecute(SynchronizeFunctor()); }
template <typename T,
typename U,
typename V,
typename StorageT,
typename StorageU,
typename StorageV,
typename BinaryFunctor>
VTKM_CONT static void Transform(const vtkm::cont::ArrayHandle<T, StorageT>& input1,
const vtkm::cont::ArrayHandle<U, StorageU>& input2,
vtkm::cont::ArrayHandle<V, StorageV>& output,
BinaryFunctor binaryFunctor)
{
vtkm::cont::TryExecute(TransformFunctor(), input1, input2, output, binaryFunctor);
}
template <typename T, class Storage>
VTKM_CONT static void Unique(vtkm::cont::ArrayHandle<T, Storage>& values)
{
......
......@@ -303,6 +303,13 @@ public:
///
ArrayHandle(const StorageType& storage);
/// Special constructor for subclass specializations that need to set the
/// initial state of the control array. When this constructor is used, it
/// is assumed that the control array is valid.
///
ArrayHandle(StorageType&& storage);
/// Destructs an empty ArrayHandle.
///
/// Implemented so that it is defined exclusively in the control environment.
......
......@@ -52,6 +52,15 @@ ArrayHandle<T, S>::ArrayHandle(const typename ArrayHandle<T, S>::StorageType& st
this->Internals->ExecutionArrayValid = false;
}
template <typename T, typename S>
ArrayHandle<T, S>::ArrayHandle(typename ArrayHandle<T, S>::StorageType&& storage)
: Internals(new InternalStruct)
{
this->Internals->ControlArray = std::move(storage);
this->Internals->ControlArrayValid = true;
this->Internals->ExecutionArrayValid = false;
}
template <typename T, typename S>
ArrayHandle<T, S>::~ArrayHandle()
{
......
......@@ -62,7 +62,6 @@ set(headers
DataSetBuilderRectilinear.h
DataSetBuilderUniform.h
DataSetFieldAdd.h
DecomposerMultiBlock.h
DeviceAdapter.h
DeviceAdapterAlgorithm.h
DeviceAdapterListTag.h
......@@ -74,6 +73,7 @@ set(headers
ErrorBadDevice.h
ErrorBadType.h
ErrorBadValue.h
ErrorFilterExecution.h
ErrorExecution.h
ErrorInternal.h
Field.h
......
......@@ -31,10 +31,26 @@ namespace cont
namespace detail
{
bool loadColorTablePreset(vtkm::cont::ColorTable::Preset preset, vtkm::cont::ColorTable& table);
std::set<std::string> GetPresetNames();
bool loadColorTablePreset(std::string name, vtkm::cont::ColorTable& table);
}
//----------------------------------------------------------------------------
ColorTable::ColorTable(vtkm::cont::ColorTable::Preset preset)
: Impl(std::make_shared<detail::ColorTableInternals>())
{
const bool loaded = this->LoadPreset(preset);
if (!loaded)
{ //if we failed to load the requested color table, call SetColorSpace
//so that the internal host side cache is constructed and we leave
//the constructor in a valid state. We use RGB as it is the default
//when the no parameter constructor is called
this->SetColorSpace(ColorSpace::LAB);
}
this->AddSegmentAlpha(this->Impl->TableRange.Min, 1.0f, this->Impl->TableRange.Max, 1.0f);
}
//----------------------------------------------------------------------------
ColorTable::ColorTable(const std::string& name)
: Impl(std::make_shared<detail::ColorTableInternals>())
......@@ -45,7 +61,7 @@ ColorTable::ColorTable(const std::string& name)
//so that the internal host side cache is constructed and we leave
//the constructor in a valid state. We use RGB as it is the default
//when the no parameter constructor is called
this->SetColorSpace(ColorSpace::RGB);
this->SetColorSpace(ColorSpace::LAB);
}
this->AddSegmentAlpha(this->Impl->TableRange.Min, 1.0f, this->Impl->TableRange.Max, 1.0f);
}
......@@ -88,6 +104,12 @@ ColorTable::~ColorTable()
{
}
//----------------------------------------------------------------------------
bool ColorTable::LoadPreset(vtkm::cont::ColorTable::Preset preset)
{
return detail::loadColorTablePreset(preset, *this);
}
//----------------------------------------------------------------------------
std::set<std::string> ColorTable::GetPresets() const
{
......@@ -852,6 +874,12 @@ vtkm::cont::VirtualObjectHandle<vtkm::exec::ColorTableBase>* ColorTable::GetHand
return this->Impl->ExecHandle;
}
//---------------------------------------------------------------------------
vtkm::Id ColorTable::GetModifiedCount() const
{
return this->Impl->HostSideCache->GetModifiedCount();
}
/*
#define ColorTableExportMapFunctions(T) \
......
......@@ -100,18 +100,44 @@ enum struct ColorSpace
/// mode where colors will pass through white when interpolating between two
/// saturated colors.
///
/// To map an vtkm::cont::ArrayHandle through the color and opacity transfer
/// functions and into a RGB or RGBA array you will need to use
/// vtkm::worklet::ColorTransferFunction. ColorTransferFunction has
/// controls if you want to modify which ColorSpace (RGB, HSV, LAB, Diverging) you want to
/// interpolate through.
/// To map a field from a vtkm::cont::DataSet through the color and opacity transfer
/// functions and into a RGB or RGBA array you should use vtkm::filter::FieldToColor.
///
class VTKM_CONT_EXPORT ColorTable
{
std::shared_ptr<detail::ColorTableInternals> Impl;
public:
/// Construct a color table from a preset color table
// Note: these are in flux and will change soon.
enum struct Preset
{
DEFAULT,
VIRIDIS,
COOL_TO_WARM,
COOL_TO_WARN_EXTENDED,
COLD_AND_HOT,
INFERNO,
BLACK_BODY_RADIATION,
SAMSEL_FIRE,
LINEAR_YGB,
BLACK_BLUE_AND_WHITE,
LINEAR_GREEN,
X_RAY,
JET,
RAINBOW_DESATURATED,
RAINBOW
};
/// \brief Construct a color table from a preset
///
/// Constructs a color table from a given preset, which might include a NaN color.
/// The alpha table will have 2 entries of alpha = 1.0 with linear interpolation
///
/// Note: these are a select set of the presets you can get by providing a string identifier.
///
ColorTable(vtkm::cont::ColorTable::Preset preset = vtkm::cont::ColorTable::Preset::DEFAULT);
/// \brief Construct a color table from a preset color table
///
/// Constructs a color table from a given preset, which might include a NaN color.
/// The alpha table will have 2 entries of alpha = 1.0 with linear interpolation
......@@ -134,20 +160,20 @@ public:
/// "Jet"
/// "Rainbow"
///
ColorTable(const std::string& name);
explicit ColorTable(const std::string& name);
/// Construct a color table with a zero positions, and an invalid range
///
/// Note: The color table will have 0 entries
/// Note: The alpha table will have 0 entries
ColorTable(ColorSpace space = ColorSpace::RGB);
explicit ColorTable(ColorSpace space);
/// Construct a color table with a 2 positions
///
/// Note: The color table will have 2 entries of rgb = {1.0,1.0,1.0}
/// Note: The alpha table will have 2 entries of alpha = 1.0 with linear
/// interpolation
ColorTable(const vtkm::Range& range, ColorSpace space = ColorSpace::RGB);
ColorTable(const vtkm::Range& range, ColorSpace space = ColorSpace::LAB);
/// Construct a color table with 2 positions
//
......@@ -156,7 +182,7 @@ public:
ColorTable(const vtkm::Range& range,
const vtkm::Vec<float, 3>& rgb1,
const vtkm::Vec<float, 3>& rgb2,
ColorSpace space = ColorSpace::RGB);
ColorSpace space = ColorSpace::LAB);
/// Construct color and alpha and table with 2 positions
///
......@@ -164,13 +190,18 @@ public:
ColorTable(const vtkm::Range& range,
const vtkm::Vec<float, 4>& rgba1,
const vtkm::Vec<float, 4>& rgba2,
ColorSpace space = ColorSpace::RGB);
ColorSpace space = ColorSpace::LAB);
~ColorTable();
bool LoadPreset(vtkm::cont::ColorTable::Preset preset);
/// Returns the name of all preset color tables
///
/// This list will include all presets defined in vtkm::cont::ColorTable::Preset and could
/// include extras as well.
///
std::set<std::string> GetPresets() const;
/// Load a preset color table
......@@ -237,8 +268,8 @@ public:
void SetNaNColor(const vtkm::Vec<float, 3>& c);
const vtkm::Vec<float, 3>& GetNaNColor() const;
/// Remove all existing all values in both color and alpha tables
/// doesn't remove the clamping, below, and above range state or colors
/// Remove all existing values in both color and alpha tables.
/// Does not remove the clamping, below, and above range state or colors.
void Clear();
/// Remove only color table values
......@@ -635,9 +666,12 @@ public:
/// This object is only valid as long as the ColorTable is unmodified
vtkm::cont::VirtualObjectHandle<vtkm::exec::ColorTableBase>* GetHandleForExecution() const;
//Todo:
//
// 1. Implement Preset Methods
/// \brief returns the modified count for the virtual object handle of the exec color table
///
/// The modified count allows consumers of a shared color table to keep track
/// if the color table has been modified since the last time they used it.
vtkm::Id GetModifiedCount() const;
};
}
} //namespace vtkm::cont
......
......@@ -34,6 +34,22 @@ namespace cont
{
namespace detail
{
template <typename T>
inline T* get_ptr(T* t)
{
return t;
}
#if defined(VTKM_MSVC)
//ArrayPortalToIteratorBegin could be returning a checked_array_iterator so
//we need to grab the underlying pointer
template <typename T>
inline T* get_ptr(stdext::checked_array_iterator<T*> t)
{
return t.base();
}
#endif
struct map_color_table
{
template <typename DeviceAdapter, typename ColorTable, typename... Args>
......@@ -81,23 +97,11 @@ struct transfer_color_table_to_device
portal->ColorSize = static_cast<vtkm::Int32>(internals->ColorPosHandle.GetNumberOfValues());
portal->OpacitySize = static_cast<vtkm::Int32>(internals->OpacityPosHandle.GetNumberOfValues());
#if !defined(VTKM_MSVC) || (defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL == 0)
portal->ColorNodes = vtkm::cont::ArrayPortalToIteratorBegin(p1);
portal->RGB = vtkm::cont::ArrayPortalToIteratorBegin(p2);
portal->ONodes = vtkm::cont::ArrayPortalToIteratorBegin(p3);
portal->Alpha = vtkm::cont::ArrayPortalToIteratorBegin(p4);
portal->MidSharp = vtkm::cont::ArrayPortalToIteratorBegin(p5);
#else
//ArrayPortalToIteratorBegin is returning a checked_array_iterator so
//we need to grab the underlying pointer
portal->ColorNodes = vtkm::cont::ArrayPortalToIteratorBegin(p1).base();
portal->RGB = vtkm::cont::ArrayPortalToIteratorBegin(p2).base();
portal->ONodes = vtkm::cont::ArrayPortalToIteratorBegin(p3).base();
portal->Alpha = vtkm::cont::ArrayPortalToIteratorBegin(p4).base();
portal->MidSharp = vtkm::cont::ArrayPortalToIteratorBegin(p5).base();
#endif
portal->ColorNodes = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p1));
portal->RGB = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p2));
portal->ONodes = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p3));
portal->Alpha = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p4));
portal->MidSharp = detail::get_ptr(vtkm::cont::ArrayPortalToIteratorBegin(p5));
return true;
}
};
......
......@@ -36,7 +36,7 @@ namespace detail
struct ColorTableInternals
{
ColorSpace CSpace = ColorSpace::RGB;
ColorSpace CSpace = ColorSpace::LAB;
vtkm::Range TableRange = { 1.0, 0.0 };
//Host side version of the ColorTableBase. This holds data such as:
......
......@@ -110,19 +110,35 @@ template VTKM_CONT_EXPORT CoordinateSystem::CoordinateSystem(
template VTKM_CONT_EXPORT CoordinateSystem::CoordinateSystem(
std::string name,
const vtkm::cont::ArrayHandle<
vtkm::Vec<vtkm::FloatDefault, 3>,
vtkm::Vec<vtkm::Float32, 3>,
vtkm::cont::internal::StorageTagCartesianProduct<
vtkm::cont::ArrayHandle<vtkm::FloatDefault, vtkm::cont::StorageTagBasic>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault, vtkm::cont::StorageTagBasic>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault, vtkm::cont::StorageTagBasic>>>&);
vtkm::cont::ArrayHandle<vtkm::Float32, vtkm::cont::StorageTagBasic>,
vtkm::cont::ArrayHandle<vtkm::Float32, vtkm::cont::StorageTagBasic>,
vtkm::cont::ArrayHandle<vtkm::Float32, vtkm::cont::StorageTagBasic>>>&);
template VTKM_CONT_EXPORT CoordinateSystem::CoordinateSystem(
std::string name,
const vtkm::cont::ArrayHandle<
vtkm::Vec<vtkm::FloatDefault, 3>,
vtkm::cont::internal::StorageTagCompositeVector<vtkm::Vec<vtkm::FloatDefault, 3>(
vtkm::cont::ArrayHandle<vtkm::FloatDefault, vtkm::cont::StorageTagBasic>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault, vtkm::cont::StorageTagBasic>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault, vtkm::cont::StorageTagBasic>)>>&);
vtkm::Vec<vtkm::Float64, 3>,
vtkm::cont::internal::StorageTagCartesianProduct<
vtkm::cont::ArrayHandle<vtkm::Float64, vtkm::cont::StorageTagBasic>,
vtkm::cont::ArrayHandle<vtkm::Float64, vtkm::cont::StorageTagBasic>,
vtkm::cont::ArrayHandle<vtkm::Float64, vtkm::cont::StorageTagBasic>>>&);
template VTKM_CONT_EXPORT CoordinateSystem::CoordinateSystem(
std::string name,
const vtkm::cont::ArrayHandle<
vtkm::Vec<vtkm::Float32, 3>,
vtkm::cont::internal::StorageTagCompositeVector<vtkm::Vec<vtkm::Float32, 3>(
vtkm::cont::ArrayHandle<vtkm::Float32, vtkm::cont::StorageTagBasic>,
vtkm::cont::ArrayHandle<vtkm::Float32, vtkm::cont::StorageTagBasic>,
vtkm::cont::ArrayHandle<vtkm::Float32, vtkm::cont::StorageTagBasic>)>>&);
template VTKM_CONT_EXPORT CoordinateSystem::CoordinateSystem(
std::string name,
const vtkm::cont::ArrayHandle<
vtkm::Vec<vtkm::Float64, 3>,
vtkm::cont::internal::StorageTagCompositeVector<vtkm::Vec<vtkm::Float64, 3>(
vtkm::cont::ArrayHandle<vtkm::Float64, vtkm::cont::StorageTagBasic>,
vtkm::cont::ArrayHandle<vtkm::Float64, vtkm::cont::StorageTagBasic>,
vtkm::cont::ArrayHandle<vtkm::Float64, vtkm::cont::StorageTagBasic>)>>&);
template VTKM_CONT_EXPORT CoordinateSystem::CoordinateSystem(std::string name,
const vtkm::cont::DynamicArrayHandle&);
......
......@@ -57,10 +57,16 @@ public:
// For std::exception compatibility:
const char* what() const noexcept override { return this->Message.c_str(); }
/// Returns true if this exception is device independent. For exceptions that
/// are not device independent, `vtkm::TryExecute`, for example, may try
/// executing the code on other available devices.
bool GetIsDeviceIndependent() const { return this->IsDeviceIndependent; }
protected:
Error() {}
Error(const std::string message)
Error(const std::string& message, bool is_device_independent = false)
: Message(message)
, IsDeviceIndependent(is_device_independent)
{
}
......@@ -68,6 +74,7 @@ protected:
private:
std::string Message;
bool IsDeviceIndependent;
};
VTKM_SILENCE_WEAK_VTABLE_WARNING_END
......
......@@ -6,9 +6,9 @@
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
// Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
......@@ -17,46 +17,34 @@
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_cont_DecomposerMultiBlock_h
#define vtk_m_cont_DecomposerMultiBlock_h
#ifndef vtk_m_cont_ErrorFilterExecution_h
#define vtk_m_cont_ErrorFilterExecution_h
#include <vtkm/cont/vtkm_cont_export.h>
#include <vtkm/internal/ExportMacros.h>
#include <vtkm/thirdparty/diy/Configure.h>
// clang-format off
VTKM_THIRDPARTY_PRE_INCLUDE
#include VTKM_DIY(diy/assigner.hpp)
VTKM_THIRDPARTY_POST_INCLUDE
// clang-format on
#include <vtkm/cont/Error.h>
namespace vtkm
{
namespace cont
{
/// \brief DIY Decomposer that uses `MultiBlock` existing decomposition.
///
/// To create partners for various reduce operations, DIY requires a decomposer.
/// This class provides an implementation that can use the multiblock's
/// decomposition.
///
class VTKM_CONT_EXPORT DecomposerMultiBlock
VTKM_SILENCE_WEAK_VTABLE_WARNING_START
/// This class is primarily intended to filters to throw in the control
/// environment to indicate an execution failure due to misconfiguration e.g.
/// incorrect parameters, etc. This is a device independent exception i.e. when
/// thrown, unlike most other exceptions, VTK-m will not try to re-execute the
/// filter on another available device.
class VTKM_ALWAYS_EXPORT ErrorFilterExecution : public vtkm::cont::Error
{
public:
VTKM_CONT DecomposerMultiBlock(const diy::Assigner& assigner)
: divisions{ assigner.nblocks() }
ErrorFilterExecution(const std::string& message)
: Error(message, /*is_device_independent=*/true)
{
}
using DivisionVector = std::vector<int>;
/// this public member is needed to satisfy decomposer concept for
/// partners in DIY.
DivisionVector divisions;
};
VTKM_SILENCE_WEAK_VTABLE_WARNING_END
}
}
} // namespace vtkm::cont
#endif
......@@ -23,7 +23,6 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/AssignerMultiBlock.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DecomposerMultiBlock.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/EnvironmentTracker.h>
......@@ -37,6 +36,7 @@ VTKM_THIRDPARTY_PRE_INCLUDE
#include VTKM_DIY(diy/decomposition.hpp)
#include VTKM_DIY(diy/master.hpp)
#include VTKM_DIY(diy/partners/all-reduce.hpp)
#include VTKM_DIY(diy/partners/broadcast.hpp)
#include VTKM_DIY(diy/partners/swap.hpp)
#include VTKM_DIY(diy/reduce.hpp)
VTKM_THIRDPARTY_POST_INCLUDE
......@@ -214,10 +214,22 @@ VTKM_CONT vtkm::Bounds MultiBlock::GetBounds(vtkm::Id coordinate_system_index) c
[]() -> void* { return new vtkm::Bounds(); },
[](void* ptr) { delete static_cast<vtkm::Bounds*>(ptr); });
// create the assigner that assigns blocks to ranks.
// AssignerMultiBlock is similar to diy::ContiguousAssigner except the number
// of blocks on each rank is defermiend by the blocks in the MultiBlock on
// each rank and those can be different.
vtkm::cont::AssignerMultiBlock assigner(*this);
const int nblocks = assigner.nblocks(); // this is the total number of blocks across all ranks.
if (nblocks == 0)
{
// short circuit if there are no blocks in this multiblock globally.
return vtkm::Bounds();
}
// populate master with blocks from `this`.
diy::decompose(world.rank(), assigner, master);
diy::RegularDecomposer<diy::DiscreteBounds> decomposer(1, diy::interval(0, nblocks - 1), nblocks);
decomposer.decompose(world.rank(), assigner, master);
auto self = (*this);
master.foreach ([&](vtkm::Bounds* data, const diy::Master::ProxyWithLink& cp) {
......@@ -232,32 +244,61 @@ VTKM_CONT vtkm::Bounds MultiBlock::GetBounds(vtkm::Id coordinate_system_index) c
}
});
vtkm::cont::DecomposerMultiBlock decomposer(assigner);
diy::RegularSwapPartners partners(decomposer, /*k=*/2);
// lets do a reduction to block-0.
diy::RegularMergePartners partners(decomposer, /*k=*/2);
auto callback =
[](vtkm::Bounds* data, const diy::ReduceProxy& srp, const diy::RegularSwapPartners&) {
[](vtkm::Bounds* data, const diy::ReduceProxy& srp, const diy::RegularMergePartners&) {
const auto selfid = srp.gid();