Compare commits

...

4 Commits

Author SHA1 Message Date
Gunther Weber
4725bd66d7 Merge branch 'vtkwriter-save-global-fields' into 'master'
Write global fields when saving to VTK files

See merge request vtk/vtk-m!2684
2024-07-03 08:28:31 -04:00
Kenneth Moreland
5df372db2b Merge topic 'env-options'
310579b9a Load options from environment variables

Acked-by: Kitware Robot <kwrobot@kitware.com>
Acked-by: Li-Ta Lo <ollie@lanl.gov>
Merge-request: !3243
2024-07-02 16:31:08 -04:00
Kenneth Moreland
310579b9a7 Load options from environment variables
Some common VTK-m options such as the device and log level could be
specified on the command line but not through environment variables. It is
not always possible to set VTK-m command line options, so environment
variables are added.

Also added documentation to the user's guide about what options are
available and how to set them.
2024-07-02 12:47:34 -04:00
Gunther H. Weber
118a2a4d51 Write globas fields when saving to VTK files 2022-01-25 14:43:51 -08:00
6 changed files with 168 additions and 26 deletions

@ -0,0 +1,9 @@
## Load options from environment variables
Some common VTK-m options such as the device and log level could be
specified on the command line but not through environment variables. It is
not always possible to set VTK-m command line options, so environment
variables are added.
Also added documentation to the user's guide about what options are
available and how to set them.

@ -19,6 +19,44 @@ But it can also optionally take the ``argc`` and ``argv`` arguments to the ``mai
|VTKm| accepts arguments that, for example, configure the compute device to use or establish logging levels.
Any arguments that are handled by |VTKm| are removed from the ``argc``/``argv`` list so that your program can then respond to the remaining arguments.
Many options can also be set with environment variables.
If both the environment variable and command line argument are provided, the command line argument is used.
The following table lists the currently supported options.
.. list-table:: |VTKm| command line arguments and environment variable options.
:widths: 23 22 15 40
:header-rows: 1
* - Command Line Argument
- Environment Variable
- Default Value
- Description
* - ``--vtkm-help``
-
-
- Causes the program to print information about |VTKm| command line arguments and then exits the program.
* - ``--vtkm-log-level``
- ``VTKM_LOG_LEVEL``
- ``WARNING``
- Specifies the logging level.
Valid values are ``INFO``, ``WARNING``, ``ERROR``, ``FATAL``, and ``OFF``.
This can also be set to a numeric value for the logging level.
* - ``--vtkm-device``
- ``VTKM_DEVICE``
-
- Force |VTKm| to use the specified device.
If not specified or ``Any`` given, then any available device may be used.
* - ``--vtkm-num-threads``
- ``VTKM_NUM_THREADS``
-
- Set the number of threads to use on a multi-core device.
If not specified, the device will use the cores available in the system.
* - ``--vtkm-device-instance``
- ``VTKM_DEVICE_INSTANCE``
-
- Selects the device to use when more than one device device of a given type is available.
The device is specified with a numbered index.
:func:`vtkm::cont::Initialize` returns a :struct:`vtkm::cont::InitializeResult` structure.
This structure contains information about the supported arguments and options selected during initialization.

@ -17,6 +17,7 @@
#include <vtkm/thirdparty/diy/environment.h>
#include <cstdlib>
#include <memory>
#include <sstream>
@ -123,7 +124,7 @@ InitializeResult Initialize(int& argc, char* argv[], InitializeOptions opts)
}
else
{
vtkm::cont::InitLogging(argc, argv, loggingFlag);
vtkm::cont::InitLogging(argc, argv, loggingFlag, "VTKM_LOG_LEVEL");
}
if (!vtkmdiy::mpi::environment::initialized())
{
@ -225,37 +226,70 @@ InitializeResult Initialize(int& argc, char* argv[], InitializeOptions opts)
vtkm::cont::DeviceAdapterTagAny{}, runtimeDeviceOptions, argc, argv);
}
// Check for device on command line.
if (options[opt::OptionIndex::DEVICE])
{
const char* arg = options[opt::OptionIndex::DEVICE].arg;
auto id = vtkm::cont::make_DeviceAdapterId(arg);
if (id != vtkm::cont::DeviceAdapterTagAny{})
config.Device = vtkm::cont::make_DeviceAdapterId(arg);
}
// If not on command line, check for device in environment variable.
if (config.Device == vtkm::cont::DeviceAdapterTagUndefined{})
{
const char* deviceEnv = std::getenv("VTKM_DEVICE");
if (deviceEnv != nullptr)
{
vtkm::cont::GetRuntimeDeviceTracker().ForceDevice(id);
auto id = vtkm::cont::make_DeviceAdapterId(std::getenv("VTKM_DEVICE"));
if (VtkmDeviceArg::DeviceIsAvailable(id))
{
config.Device = id;
}
else
{
// Got invalid device. Log an error, but continue to do the default action for
// the device (i.e., ignore the environment variable setting).
VTKM_LOG_S(vtkm::cont::LogLevel::Error,
"Invalid device `"
<< deviceEnv
<< "` specified in VTKM_DEVICE environment variable. Ignoring.");
VTKM_LOG_S(vtkm::cont::LogLevel::Error,
"Valid devices are: " << VtkmDeviceArg::GetValidDeviceNames());
}
}
}
// If still not defined, check to see if "any" device should be added.
if ((config.Device == vtkm::cont::DeviceAdapterTagUndefined{}) &&
(opts & InitializeOptions::DefaultAnyDevice) != InitializeOptions::None)
{
config.Device = vtkm::cont::DeviceAdapterTagAny{};
}
// Set the state for the device selected.
if (config.Device == vtkm::cont::DeviceAdapterTagUndefined{})
{
if ((opts & InitializeOptions::RequireDevice) != InitializeOptions::None)
{
auto devices = VtkmDeviceArg::GetValidDeviceNames();
VTKM_LOG_S(vtkm::cont::LogLevel::Fatal, "Device not given on command line.");
std::cerr << "Target device must be specified via --vtkm-device.\n"
"Valid devices: "
<< devices << std::endl;
if ((opts & InitializeOptions::AddHelp) != InitializeOptions::None)
{
std::cerr << config.Usage;
}
exit(1);
}
else
{
vtkm::cont::GetRuntimeDeviceTracker().Reset();
// No device specified. Do nothing and let VTK-m decide what it is going to do.
}
config.Device = id;
}
else if ((opts & InitializeOptions::DefaultAnyDevice) != InitializeOptions::None)
else if (config.Device == vtkm::cont::DeviceAdapterTagAny{})
{
vtkm::cont::GetRuntimeDeviceTracker().Reset();
config.Device = vtkm::cont::DeviceAdapterTagAny{};
}
else if ((opts & InitializeOptions::RequireDevice) != InitializeOptions::None)
else
{
auto devices = VtkmDeviceArg::GetValidDeviceNames();
VTKM_LOG_S(vtkm::cont::LogLevel::Error, "Device not given on command line.");
std::cerr << "Target device must be specified via --vtkm-device.\n"
"Valid devices: "
<< devices << std::endl;
if ((opts & InitializeOptions::AddHelp) != InitializeOptions::None)
{
std::cerr << config.Usage;
}
exit(1);
vtkm::cont::GetRuntimeDeviceTracker().ForceDevice(config.Device);
}

@ -30,7 +30,7 @@
#endif // VTKM_ENABLE_LOGGING
#include <cassert>
#include <cstdlib>
#include <iomanip>
#include <sstream>
#include <stdexcept>
@ -108,7 +108,10 @@ namespace cont
{
VTKM_CONT
void InitLogging(int& argc, char* argv[], const std::string& loggingFlag)
void InitLogging(int& argc,
char* argv[],
const std::string& loggingFlag,
const std::string& loggingEnv)
{
SetLogLevelName(vtkm::cont::LogLevel::Off, "Off");
SetLogLevelName(vtkm::cont::LogLevel::Fatal, "FATL");
@ -130,8 +133,16 @@ void InitLogging(int& argc, char* argv[], const std::string& loggingFlag)
loguru::set_verbosity_to_name_callback(&verbosityToNameCallback);
loguru::set_name_to_verbosity_callback(&nameToVerbosityCallback);
// Set the default log level to warning
SetStderrLogLevel(vtkm::cont::LogLevel::Warn);
const char* envLevel = std::getenv(loggingEnv.c_str());
if (envLevel != nullptr)
{
SetStderrLogLevel(envLevel);
}
else
{
// Set the default log level to warning
SetStderrLogLevel(vtkm::cont::LogLevel::Warn);
}
loguru::init(argc, argv, loggingFlag.c_str());
}
#else // VTKM_ENABLE_LOGGING

@ -371,7 +371,10 @@ enum class LogLevel
*/
VTKM_CONT_EXPORT
VTKM_CONT
void InitLogging(int& argc, char* argv[], const std::string& loggingFlag = "--vtkm-log-level");
void InitLogging(int& argc,
char* argv[],
const std::string& loggingFlag = "--vtkm-log-level",
const std::string& loggingEnv = "VTKM_LOG_LEVEL");
VTKM_CONT_EXPORT
VTKM_CONT
void InitLogging();

@ -392,6 +392,46 @@ void WriteCellFields(std::ostream& out,
}
}
void WriteGlobalFields(std::ostream& out,
const vtkm::cont::DataSet& dataSet,
vtkm::io::FileType fileType)
{
// count number of global arrays
int n = 0;
for (vtkm::Id f = 0; f < dataSet.GetNumberOfFields(); f++)
{
if (dataSet.GetField(f).IsFieldGlobal())
n++;
}
if (n < 1)
return;
// write header
out << "FIELD FieldData " << n << '\n';
// write fields
for (vtkm::Id f = 0; f < dataSet.GetNumberOfFields(); f++)
{
const vtkm::cont::Field field = dataSet.GetField(f);
if (!field.IsFieldGlobal())
{
continue;
}
std::string name = field.GetName();
int nComponents = field.GetData().GetNumberOfComponentsFlat();
int nValues = field.GetData().GetNumberOfValues();
std::string typeName = GetFieldTypeName(field.GetData());
out << name << " " << nComponents << " " << nValues << " " << typeName << '\n';
OutputArrayData(field.GetData(), out, fileType);
out << "METADATA\nINFORMATION 0\n\n";
}
}
template <class CellSetType>
void WriteDataSetAsUnstructured(std::ostream& out,
const vtkm::cont::DataSet& dataSet,
@ -406,10 +446,13 @@ void WriteDataSetAsUnstructured(std::ostream& out,
template <vtkm::IdComponent DIM>
void WriteDataSetAsStructuredPoints(std::ostream& out,
const vtkm::cont::ArrayHandleUniformPointCoordinates& points,
const vtkm::cont::CellSetStructured<DIM>& cellSet)
const vtkm::cont::CellSetStructured<DIM>& cellSet,
const vtkm::cont::DataSet& dataSet,
vtkm::io::FileType fileType)
{
out << "DATASET STRUCTURED_POINTS\n";
WriteGlobalFields(out, dataSet, fileType);
WriteDimensions(out, cellSet);
auto portal = points.ReadPortal();
@ -472,7 +515,11 @@ void WriteDataSetAsStructured(std::ostream& out,
{
// uniform is written as "structured points"
WriteDataSetAsStructuredPoints(
out, coordSystem.AsArrayHandle<vtkm::cont::ArrayHandleUniformPointCoordinates>(), cellSet);
out,
coordSystem.AsArrayHandle<vtkm::cont::ArrayHandleUniformPointCoordinates>(),
cellSet,
dataSet,
fileType);
}
else if (coordSystem.IsType<ArrayHandleRectilinearCoordinates<vtkm::Float32>>())
{