This commit is contained in:
Dave Pugmire 2022-11-10 16:31:52 -05:00
commit 6390b606b7
13 changed files with 215 additions and 75 deletions

@ -13,6 +13,13 @@
CMAKE_BUILD_TYPE: "RelWithDebInfo"
CMAKE_GENERATOR: "Ninja"
# This is needed for the smoke_test, while we use rocm 5 to build VTK-m the
# smoke_test needs 4.5 since Kokkos is built agains rocm 4.5
LD_LIBRARY_PATH: "/opt/rocm-4.5.0/lib:${LD_LIBRARY_PATH}"
LIBRARY_PATH: "/opt/rocm-4.5.0/lib:${LIBRARY_PATH}"
# While Kokkos and VTK-m uses ROCm 4.5.0 runtime/sdk, we need to build
# VTK-m with HIPCC from ROCM 5
CMAKE_HIP_COMPILER: "/opt/rocm-default/llvm/bin/clang++"
Kokkos_CXX_COMPILER: "/opt/rocm-default/llvm/bin/clang++"
CMAKE_HIP_ARCHITECTURES: "gfx908"
@ -33,7 +40,7 @@
ninja
spectrum-mpi
zstd
VTKM_SETTINGS: kokkos+hip+spock+ccache+no_virtual+no_rendering
VTKM_SETTINGS: kokkos+hip+spock+ccache+no_rendering
interruptible: true
.setup_env_ecpci: &setup_env_ecpci |

@ -72,9 +72,10 @@ build:ubuntu2004_hip_kokkos:
- .run_automatically
variables:
CMAKE_BUILD_TYPE: "RelWithDebInfo"
VTKM_SETTINGS: "benchmarks+kokkos+hip+no_virtual+no_rendering+ccache"
VTKM_SETTINGS: "benchmarks+kokkos+hip+no_rendering+ccache"
CMAKE_PREFIX_PATH: "/opt/rocm/lib/cmake"
LD_LIBRARY_PATH: "/opt/rocm/lib"
CMAKE_HIP_COMPILER: "/opt/rocm/llvm/bin/clang++"
Kokkos_CXX_COMPILER: "/opt/rocm/llvm/bin/clang++"
CMAKE_HIP_ARCHITECTURES: "gfx900"

@ -0,0 +1,11 @@
# Fix VTKM_LOG_SCOPE
The `VTKM_LOG_SCOPE` macro was not working as intended. It was supposed to
print a log message immediately and then print a second log message when
leaving the scope along with the number of seconds that elapsed between the
two messages.
This was not what was happening. The second log message was being printed
immediately after the first. This is because the scope was taken inside of
the `LogScope` method. The macro has been rewritten to put the tracking in
the right scope.

@ -0,0 +1,8 @@
# Attach compressed ZFP data as WholeDatSet field
Previously, point fields compressed by ZFP were attached as point fields
on the output. However, using them as a point field would cause
problems. So, instead attache them as `WholeDataSet` fields.
Also fixed a problem where the 1D decompressor created an output of the
wrong size.

@ -340,24 +340,50 @@ int getVerbosityByLevel(LogLevel level)
return static_cast<loguru::Verbosity>(level);
}
namespace detail
{
struct LogScope::InternalStruct : loguru::LogScopeRAII
{
template <typename... Ts>
InternalStruct(Ts&&... args)
: loguru::LogScopeRAII(std::forward<Ts>(args)...)
{
}
};
VTKM_CONT
void LogScope(LogLevel level, const char* file, unsigned line, const char* format...)
LogScope::LogScope(LogLevel level, const char* file, unsigned line, const char* format...)
{
auto verbosity = getVerbosityByLevel(level);
if (verbosity > loguru::current_verbosity_cutoff())
{
loguru::LogScopeRAII();
this->Internals = std::make_unique<InternalStruct>();
}
else
{
va_list args;
va_start(args, format);
loguru::LogScopeRAII(verbosity, file, line, format, args);
this->Internals = std::make_unique<InternalStruct>(verbosity, file, line, format, args);
va_end(args);
}
}
LogScope::~LogScope() = default;
} // namespace detail
VTKM_CONT
void LogScope(LogLevel level, const char* file, unsigned line, const char* format...)
{
// This does not scope right, but neither did the deprecated method this is replacing.
va_list args;
va_start(args, format);
detail::LogScope scopedVar{ level, file, line, format, args };
va_end(args);
}
VTKM_CONT
void LogCond(LogLevel level, bool cond, const char* file, unsigned line, const char* format...)
{

@ -13,11 +13,13 @@
#include <vtkm/internal/Configure.h>
#include <vtkm/internal/ExportMacros.h>
#include <vtkm/Deprecated.h>
#include <vtkm/Types.h>
#include <vtkm/cont/vtkm_cont_export.h>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <typeindex>
@ -187,6 +189,15 @@
/// and then cast appropriately, as described here:
/// https://gitlab.kitware.com/vtk/vtk-m/-/issues/358#note_550157
#define VTKM_CONCAT_IMPL(s1, s2) s1##s2
#define VTKM_CONCAT(s1, s2) VTKM_CONCAT_IMPL(s1, s2)
#ifdef __COUNTER__
#define VTKM_ANONYMOUS_VARIABLE VTKM_CONCAT(vtk_m_anonymous_, __COUNTER__)
#else
#define VTKM_ANONYMOUS_VARIABLE VTKM_CONCAT(vtk_m_anonymous_, __LINE__)
#endif
#if defined(VTKM_ENABLE_LOGGING)
#define VTKM_LOG_IF_S(level, cond, ...) \
@ -198,7 +209,8 @@
#define VTKM_LOG_S(level, ...) VTKM_LOG_IF_S(level, true, __VA_ARGS__)
#define VTKM_LOG_F(level, ...) VTKM_LOG_IF_F(level, true, __VA_ARGS__)
#define VTKM_LOG_SCOPE(level, ...) vtkm::cont::LogScope(level, __FILE__, __LINE__, __VA_ARGS__)
#define VTKM_LOG_SCOPE(level, ...) \
vtkm::cont::detail::LogScope VTKM_ANONYMOUS_VARIABLE { level, __FILE__, __LINE__, __VA_ARGS__ }
#define VTKM_LOG_SCOPE_FUNCTION(level) VTKM_LOG_SCOPE(level, __func__)
#define VTKM_LOG_ALWAYS_S(level, ...) VTKM_LOG_S(level, __VA_ARGS__)
@ -494,16 +506,37 @@ VTKM_CONT_EXPORT
VTKM_CONT
void LogCond(LogLevel level, bool cond, const char* file, unsigned line, const char* format...);
namespace detail
{
/**
* \brief Logs a scoped message with a printf-like format.
*
* The indentation level will be determined based on its LogLevel and it will
* print out its wall time upon exiting its scope.
*
* \param level Desired LogLevel value for the log message.
* \param cond When false this function is no-op.
* \param format Printf like format string.
* print out its wall time upon exiting its scope. The scope starts from when
* the object is created to when it is destroyed.
*/
class VTKM_CONT_EXPORT LogScope
{
struct InternalStruct;
std::unique_ptr<InternalStruct> Internals;
public:
/*
* \param level Desired LogLevel value for the log message.
* \param cond When false this function is no-op.
* \param format Printf like format string.
*/
VTKM_CONT
LogScope(LogLevel level, const char* file, unsigned line, const char* format...);
VTKM_CONT ~LogScope();
};
} // namespace detail
VTKM_DEPRECATED(1.9, "Use VTKM_LOG_SCOPE macro.")
VTKM_CONT_EXPORT
VTKM_CONT
void LogScope(LogLevel level, const char* file, unsigned line, const char* format...);

@ -317,7 +317,9 @@ VTKM_CONT GhostCellRemove::GhostCellRemove()
VTKM_CONT vtkm::cont::DataSet GhostCellRemove::DoExecute(const vtkm::cont::DataSet& input)
{
const vtkm::cont::UnknownCellSet& cells = input.GetCellSet();
const auto& field = this->GetFieldFromDataSet(input);
const vtkm::cont::Field& field =
(this->GetUseGhostCellsAsField() ? input.GetGhostCellField()
: this->GetFieldFromDataSet(input));
vtkm::cont::ArrayHandle<vtkm::UInt8> fieldArray;
vtkm::cont::ArrayCopyShallowIfPossible(field.GetData(), fieldArray);

@ -44,6 +44,11 @@ public:
VTKM_CONT
bool GetRemoveAllGhost() const { return this->RemoveAll; }
VTKM_CONT
bool GetUseGhostCellsAsField() const { return this->UseGhostCellsAsField; }
VTKM_CONT
void SetUseGhostCellsAsField(bool flag) { this->UseGhostCellsAsField = flag; }
VTKM_CONT
bool GetRemoveByType() const { return !this->RemoveAll; }
VTKM_CONT
@ -53,6 +58,7 @@ private:
VTKM_CONT
vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input) override;
bool UseGhostCellsAsField = true;
bool RemoveAll = false;
bool RemoveField = false;
vtkm::UInt8 RemoveVals = 0;

@ -84,6 +84,7 @@ vtkm::cont::DataSet MakeUniform(vtkm::Id numI,
vtkm::Id numJ,
vtkm::Id numK,
int numLayers,
std::string& ghostName,
bool addMidGhost = false)
{
vtkm::cont::DataSet ds;
@ -94,8 +95,14 @@ vtkm::cont::DataSet MakeUniform(vtkm::Id numI,
ds = vtkm::cont::DataSetBuilderUniform::Create(vtkm::Id3(numI + 1, numJ + 1, numK + 1));
auto ghosts = StructuredGhostCellArray(numI, numJ, numK, numLayers, addMidGhost);
ds.AddGhostCellField(ghosts);
if (ghostName == "default")
{
ds.AddGhostCellField(ghosts);
}
else
{
ds.AddGhostCellField(ghostName, ghosts);
}
return ds;
}
@ -103,6 +110,7 @@ vtkm::cont::DataSet MakeRectilinear(vtkm::Id numI,
vtkm::Id numJ,
vtkm::Id numK,
int numLayers,
std::string& ghostName,
bool addMidGhost = false)
{
vtkm::cont::DataSet ds;
@ -128,7 +136,14 @@ vtkm::cont::DataSet MakeRectilinear(vtkm::Id numI,
auto ghosts = StructuredGhostCellArray(numI, numJ, numK, numLayers, addMidGhost);
ds.AddGhostCellField(ghosts);
if (ghostName == "default")
{
ds.AddGhostCellField(ghosts);
}
else
{
ds.AddGhostCellField(ghostName, ghosts);
}
return ds;
}
@ -164,11 +179,15 @@ static void MakeExplicitCells(const CellSetType& cellSet,
}
}
vtkm::cont::DataSet MakeExplicit(vtkm::Id numI, vtkm::Id numJ, vtkm::Id numK, int numLayers)
vtkm::cont::DataSet MakeExplicit(vtkm::Id numI,
vtkm::Id numJ,
vtkm::Id numK,
int numLayers,
std::string& ghostName)
{
using CoordType = vtkm::Vec3f_32;
vtkm::cont::DataSet dsUniform = MakeUniform(numI, numJ, numK, numLayers);
vtkm::cont::DataSet dsUniform = MakeUniform(numI, numJ, numK, numLayers, ghostName);
auto coordData = dsUniform.GetCoordinateSystem(0).GetDataAsMultiplexer();
vtkm::Id numPts = coordData.GetNumberOfValues();
@ -205,7 +224,14 @@ vtkm::cont::DataSet MakeExplicit(vtkm::Id numI, vtkm::Id numJ, vtkm::Id numK, in
auto ghosts = StructuredGhostCellArray(numI, numJ, numK, numLayers);
ds.AddGhostCellField(ghosts);
if (ghostName == "default")
{
ds.AddGhostCellField(ghosts);
}
else
{
ds.AddGhostCellField(ghostName, ghosts);
}
return ds;
}
@ -235,70 +261,74 @@ void TestGhostCellRemove()
std::vector<std::string> dsTypes = { "uniform", "rectilinear", "explicit" };
for (auto& dsType : dsTypes)
{
vtkm::cont::DataSet ds;
if (dsType == "uniform")
ds = MakeUniform(nx, ny, nz, layer);
else if (dsType == "rectilinear")
ds = MakeRectilinear(nx, ny, nz, layer);
else if (dsType == "explicit")
ds = MakeExplicit(nx, ny, nz, layer);
std::vector<std::string> removeType = { "all", "byType" };
for (auto& rt : removeType)
std::vector<std::string> nameTypes = { "default", "user-specified" };
for (auto& nameType : nameTypes)
{
vtkm::filter::entity_extraction::GhostCellRemove ghostCellRemoval;
ghostCellRemoval.RemoveGhostField();
vtkm::cont::DataSet ds;
if (dsType == "uniform")
ds = MakeUniform(nx, ny, nz, layer, nameType);
else if (dsType == "rectilinear")
ds = MakeRectilinear(nx, ny, nz, layer, nameType);
else if (dsType == "explicit")
ds = MakeExplicit(nx, ny, nz, layer, nameType);
if (rt == "all")
ghostCellRemoval.RemoveAllGhost();
else if (rt == "byType")
ghostCellRemoval.RemoveByType(vtkm::CellClassification::Ghost);
auto output = ghostCellRemoval.Execute(ds);
vtkm::Id numCells = output.GetNumberOfCells();
//Validate the output.
vtkm::Id numCellsReq = (nx - 2 * layer) * (ny - 2 * layer);
if (nz != 0)
numCellsReq *= (nz - 2 * layer);
VTKM_TEST_ASSERT(numCellsReq == numCells, "Wrong number of cells in output");
if (dsType == "uniform" || dsType == "rectilinear")
std::vector<std::string> removeType = { "all", "byType" };
for (auto& rt : removeType)
{
if (nz == 0)
vtkm::filter::entity_extraction::GhostCellRemove ghostCellRemoval;
ghostCellRemoval.RemoveGhostField();
if (rt == "all")
ghostCellRemoval.RemoveAllGhost();
else if (rt == "byType")
ghostCellRemoval.RemoveByType(vtkm::CellClassification::Ghost);
auto output = ghostCellRemoval.Execute(ds);
vtkm::Id numCells = output.GetNumberOfCells();
//Validate the output.
vtkm::Id numCellsReq = (nx - 2 * layer) * (ny - 2 * layer);
if (nz != 0)
numCellsReq *= (nz - 2 * layer);
VTKM_TEST_ASSERT(numCellsReq == numCells, "Wrong number of cells in output");
if (dsType == "uniform" || dsType == "rectilinear")
{
VTKM_TEST_ASSERT(output.GetCellSet().CanConvert<vtkm::cont::CellSetStructured<2>>(),
"Wrong cell type for explicit conversion");
if (nz == 0)
{
VTKM_TEST_ASSERT(output.GetCellSet().CanConvert<vtkm::cont::CellSetStructured<2>>(),
"Wrong cell type for explicit conversion");
}
else if (nz > 0)
{
VTKM_TEST_ASSERT(output.GetCellSet().CanConvert<vtkm::cont::CellSetStructured<3>>(),
"Wrong cell type for explicit conversion");
}
}
else if (nz > 0)
else
{
VTKM_TEST_ASSERT(output.GetCellSet().CanConvert<vtkm::cont::CellSetStructured<3>>(),
VTKM_TEST_ASSERT(output.GetCellSet().IsType<vtkm::cont::CellSetExplicit<>>(),
"Wrong cell type for explicit conversion");
}
}
else
// For structured, test the case where we have a ghost in the 'middle' of the cells.
// This will produce an explicit cellset.
if (dsType == "uniform" || dsType == "rectilinear")
{
if (dsType == "uniform")
ds = MakeUniform(nx, ny, nz, layer, nameType, true);
else if (dsType == "rectilinear")
ds = MakeRectilinear(nx, ny, nz, layer, nameType, true);
vtkm::filter::entity_extraction::GhostCellRemove ghostCellRemoval;
ghostCellRemoval.RemoveGhostField();
auto output = ghostCellRemoval.Execute(ds);
VTKM_TEST_ASSERT(output.GetCellSet().IsType<vtkm::cont::CellSetExplicit<>>(),
"Wrong cell type for explicit conversion");
}
}
// For structured, test the case where we have a ghost in the 'middle' of the cells.
// This will produce an explicit cellset.
if (dsType == "uniform" || dsType == "rectilinear")
{
if (dsType == "uniform")
ds = MakeUniform(nx, ny, nz, layer, true);
else if (dsType == "rectilinear")
ds = MakeRectilinear(nx, ny, nz, layer, true);
vtkm::filter::entity_extraction::GhostCellRemove ghostCellRemoval;
ghostCellRemoval.RemoveGhostField();
auto output = ghostCellRemoval.Execute(ds);
VTKM_TEST_ASSERT(output.GetCellSet().IsType<vtkm::cont::CellSetExplicit<>>(),
"Wrong cell type for explicit conversion");
}
}
}
}

@ -30,8 +30,12 @@ VTKM_CONT vtkm::cont::DataSet ZFPCompressor1D::DoExecute(const vtkm::cont::DataS
compressed = compressor.Compress(concrete, rate, field.GetNumberOfValues());
});
// TODO: is it really PointField or WHOLE_MESH, should we do it the same way as Histogram?
return this->CreateResultFieldPoint(input, "compressed", compressed);
// Note: the compressed array is set as a WholeDataSet field. It is really associated with
// the points, but the size does not match and problems will occur if the user attempts to
// use it as a point data set. The decompressor will place the data back as a point field.
// (This might cause issues if cell fields are ever supported.)
return this->CreateResultField(
input, "compressed", vtkm::cont::Field::Association::WholeDataSet, compressed);
}
} // namespace zfp
} // namespace filter

@ -35,8 +35,12 @@ VTKM_CONT vtkm::cont::DataSet ZFPCompressor2D::DoExecute(const vtkm::cont::DataS
compressed = compressor.Compress(concrete, rate, pointDimensions);
});
// TODO: is it really PointField or WHOLE_MESH, should we do it the same way as Histogram?
return this->CreateResultFieldPoint(input, "compressed", compressed);
// Note: the compressed array is set as a WholeDataSet field. It is really associated with
// the points, but the size does not match and problems will occur if the user attempts to
// use it as a point data set. The decompressor will place the data back as a point field.
// (This might cause issues if cell fields are ever supported.)
return this->CreateResultField(
input, "compressed", vtkm::cont::Field::Association::WholeDataSet, compressed);
}
} // namespace zfp
} // namespace filter

@ -35,8 +35,12 @@ VTKM_CONT vtkm::cont::DataSet ZFPCompressor3D::DoExecute(const vtkm::cont::DataS
compressed = compressor.Compress(concrete, rate, pointDimensions);
});
// TODO: is it really PointField or WHOLE_MESH, should we do it the same way as Histogram?
return this->CreateResultFieldPoint(input, "compressed", compressed);
// Note: the compressed array is set as a WholeDataSet field. It is really associated with
// the points, but the size does not match and problems will occur if the user attempts to
// use it as a point data set. The decompressor will place the data back as a point field.
// (This might cause issues if cell fields are ever supported.)
return this->CreateResultField(
input, "compressed", vtkm::cont::Field::Association::WholeDataSet, compressed);
}
} // namespace zfp
} // namespace filter

@ -26,9 +26,13 @@ VTKM_CONT vtkm::cont::DataSet ZFPDecompressor1D::DoExecute(const vtkm::cont::Dat
vtkm::cont::ArrayHandle<vtkm::Int64> compressed;
vtkm::cont::ArrayCopyShallowIfPossible(this->GetFieldFromDataSet(input).GetData(), compressed);
vtkm::cont::CellSetStructured<1> cellSet;
input.GetCellSet().AsCellSet(cellSet);
vtkm::Id pointDimensions = cellSet.GetPointDimensions();
vtkm::cont::ArrayHandle<vtkm::Float64> decompressed;
vtkm::worklet::ZFP1DDecompressor decompressor;
decompressor.Decompress(compressed, decompressed, this->rate, compressed.GetNumberOfValues());
decompressor.Decompress(compressed, decompressed, this->rate, pointDimensions);
return this->CreateResultFieldPoint(input, "decompressed", decompressed);
}