mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-09-08 13:23:51 +00:00
Add vtkm::cont::Initialize.
Also - Renamed vtkm::cont::make_DeviceAdapterIdFromName to just overload make_DeviceAdapterId. - Refactored CMake logic for unit tests - Since we're now querying the device tracker for the names, they cannot be all caps. - Updated usages of InitLogging to use Initialize instead. - Added changelog.
This commit is contained in:
parent
83d5af6159
commit
cdb1f5680a
@ -402,15 +402,15 @@ function(vtkm_unit_tests)
|
||||
set(backend ${VTKm_UT_BACKEND})
|
||||
|
||||
set(enable_all_backends ${VTKm_UT_ALL_BACKENDS})
|
||||
set(all_backends SERIAL)
|
||||
set(all_backends Serial)
|
||||
if (VTKm_ENABLE_CUDA)
|
||||
list(APPEND all_backends CUDA)
|
||||
list(APPEND all_backends Cuda)
|
||||
endif()
|
||||
if (VTKm_ENABLE_TBB)
|
||||
list(APPEND all_backends TBB)
|
||||
endif()
|
||||
if (VTKm_ENABLE_OPENMP)
|
||||
list(APPEND all_backends OPENMP)
|
||||
list(APPEND all_backends OpenMP)
|
||||
endif()
|
||||
|
||||
if(VTKm_UT_NAME)
|
||||
@ -440,7 +440,7 @@ function(vtkm_unit_tests)
|
||||
#cuda. This is so that we get the correctly named entry points generated
|
||||
create_test_sourcelist(test_sources ${test_prog}.cxx ${VTKm_UT_SOURCES} ${extraArgs})
|
||||
#if all backends are enabled, we can use cuda compiler to handle all possible backends.
|
||||
if(backend STREQUAL "CUDA" OR (enable_all_backends AND VTKm_ENABLE_CUDA))
|
||||
if(backend STREQUAL "Cuda" OR (enable_all_backends AND VTKm_ENABLE_CUDA))
|
||||
vtkm_compile_as_cuda(cu_srcs ${VTKm_UT_SOURCES})
|
||||
set(VTKm_UT_SOURCES ${cu_srcs})
|
||||
endif()
|
||||
@ -458,28 +458,29 @@ function(vtkm_unit_tests)
|
||||
set (current_backend "")
|
||||
set(device_command_line_argument "")
|
||||
endif()
|
||||
string(TOUPPER "${current_backend}" upper_backend)
|
||||
foreach (test ${VTKm_UT_SOURCES})
|
||||
get_filename_component(tname ${test} NAME_WE)
|
||||
if(VTKm_UT_MPI AND VTKm_ENABLE_MPI)
|
||||
add_test(NAME ${tname}${current_backend}
|
||||
add_test(NAME ${tname}${upper_backend}
|
||||
COMMAND ${MPIEXEC} ${MPIEXEC_NUMPROC_FLAG} 3 ${MPIEXEC_PREFLAGS}
|
||||
$<TARGET_FILE:${test_prog}> ${tname} ${device_command_line_argument} ${VTKm_UT_TEST_ARGS}
|
||||
${MPIEXEC_POSTFLAGS}
|
||||
)
|
||||
else()
|
||||
add_test(NAME ${tname}${current_backend}
|
||||
add_test(NAME ${tname}${upper_backend}
|
||||
COMMAND ${test_prog} ${tname} ${device_command_line_argument} ${VTKm_UT_TEST_ARGS}
|
||||
)
|
||||
endif()
|
||||
|
||||
#determine the timeout for all the tests based on the backend. CUDA tests
|
||||
#generally require more time because of kernel generation.
|
||||
if (current_backend STREQUAL "CUDA")
|
||||
if (current_backend STREQUAL "Cuda")
|
||||
set(timeout 1500)
|
||||
else()
|
||||
set(timeout 180)
|
||||
endif()
|
||||
if(current_backend STREQUAL "OPENMP")
|
||||
if(current_backend STREQUAL "OpenMP")
|
||||
#We need to have all OpenMP tests run serially as they
|
||||
#will uses all the system cores, and we will cause a N*N thread
|
||||
#explosion which causes the tests to run slower than when run
|
||||
@ -489,7 +490,7 @@ function(vtkm_unit_tests)
|
||||
set(run_serial False)
|
||||
endif()
|
||||
|
||||
set_tests_properties("${tname}${current_backend}" PROPERTIES
|
||||
set_tests_properties("${tname}${upper_backend}" PROPERTIES
|
||||
TIMEOUT ${timeout}
|
||||
RUN_SERIAL ${run_serial}
|
||||
)
|
||||
|
@ -1283,7 +1283,7 @@ int BenchmarkBody(int argc, char* argv[])
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
vtkm::cont::InitLogging(argc, argv);
|
||||
vtkm::cont::Initialize(argc, argv);
|
||||
|
||||
int retval = 1;
|
||||
try
|
||||
|
20
docs/changelog/initialize.md
Normal file
20
docs/changelog/initialize.md
Normal file
@ -0,0 +1,20 @@
|
||||
# vtkm::cont::Initialize
|
||||
|
||||
A new initialization function, vtkm::cont::Initialize, has been added.
|
||||
Initialization is not required, but will configure the logging utilities (when
|
||||
enabled) and allows forcing a device via a `-d` or `--device` command line
|
||||
option.
|
||||
|
||||
|
||||
Usage:
|
||||
|
||||
```
|
||||
#include <vtkm/cont/Initialize.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
auto config = vtkm::cont::Initialize(argc, argv);
|
||||
|
||||
...
|
||||
}
|
||||
```
|
@ -31,7 +31,7 @@
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
static const vtkm::cont::LogLevel CosmoLogLevel = vtkm::cont::LogLevel(1);
|
||||
static const vtkm::cont::LogLevel CosmoLogLevel = vtkm::cont::LogLevel::UserFirst;
|
||||
|
||||
void TestCosmoCenterFinder(const char* fileName)
|
||||
{
|
||||
@ -122,7 +122,7 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
vtkm::cont::SetLogLevelName(CosmoLogLevel, "Cosmo");
|
||||
vtkm::cont::SetStderrLogLevel(CosmoLogLevel);
|
||||
vtkm::cont::InitLogging(argc, argv);
|
||||
vtkm::cont::Initialize(argc, argv);
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
static const vtkm::cont::LogLevel CosmoLogLevel = vtkm::cont::LogLevel(1);
|
||||
static const vtkm::cont::LogLevel CosmoLogLevel = vtkm::cont::LogLevel::UserFirst;
|
||||
|
||||
void TestCosmoHaloFinder(const char* fileName)
|
||||
{
|
||||
@ -116,7 +116,7 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
vtkm::cont::SetLogLevelName(CosmoLogLevel, "Cosmo");
|
||||
vtkm::cont::SetStderrLogLevel(CosmoLogLevel);
|
||||
vtkm::cont::InitLogging(argc, argv);
|
||||
vtkm::cont::Initialize(argc, argv);
|
||||
|
||||
if (argc < 2)
|
||||
{
|
||||
|
@ -89,6 +89,7 @@ set(headers
|
||||
FieldRangeCompute.h
|
||||
FieldRangeGlobalCompute.h
|
||||
ImplicitFunctionHandle.h
|
||||
Initialize.h
|
||||
Logging.h
|
||||
MultiBlock.h
|
||||
PointLocator.h
|
||||
@ -144,6 +145,7 @@ set(sources
|
||||
internal/SimplePolymorphicContainer.cxx
|
||||
internal/SimplePolymorphicContainer.cxx
|
||||
internal/VirtualObjectTransfer.cxx
|
||||
Initialize.cxx
|
||||
Logging.cxx
|
||||
MultiBlock.cxx
|
||||
RuntimeDeviceInformation.cxx
|
||||
|
218
vtkm/cont/Initialize.cxx
Normal file
218
vtkm/cont/Initialize.cxx
Normal file
@ -0,0 +1,218 @@
|
||||
//============================================================================
|
||||
// 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 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2018 UT-Battelle, LLC.
|
||||
// Copyright 2018 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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.
|
||||
//============================================================================
|
||||
|
||||
#include <vtkm/cont/Initialize.h>
|
||||
|
||||
#include <vtkm/cont/Logging.h>
|
||||
#include <vtkm/cont/RuntimeDeviceTracker.h>
|
||||
#include <vtkm/cont/internal/OptionParser.h>
|
||||
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
namespace opt = vtkm::cont::internal::option;
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
enum OptionIndex
|
||||
{
|
||||
PREAMBLE, // usage header strings
|
||||
DEVICE,
|
||||
LOGLEVEL, // not parsed by this parser, but by loguru
|
||||
HELP
|
||||
};
|
||||
|
||||
struct VtkmArg : public opt::Arg
|
||||
{
|
||||
static opt::ArgStatus IsDevice(const opt::Option& option, bool msg)
|
||||
{
|
||||
// Device must be specified if option is present:
|
||||
if (option.arg == nullptr)
|
||||
{
|
||||
if (msg)
|
||||
{
|
||||
VTKM_LOG_ALWAYS_S(vtkm::cont::LogLevel::Error,
|
||||
"Missing device after option '"
|
||||
<< std::string(option.name, static_cast<size_t>(option.namelen))
|
||||
<< "'.\nValid devices are: "
|
||||
<< VtkmArg::GetValidDeviceNames()
|
||||
<< "\n");
|
||||
}
|
||||
return opt::ARG_ILLEGAL;
|
||||
}
|
||||
|
||||
auto id = vtkm::cont::make_DeviceAdapterId(option.arg);
|
||||
|
||||
if (!VtkmArg::DeviceIsAvailable(id))
|
||||
{
|
||||
VTKM_LOG_ALWAYS_S(vtkm::cont::LogLevel::Error,
|
||||
"Unavailable device specificed after option '"
|
||||
<< std::string(option.name, static_cast<size_t>(option.namelen))
|
||||
<< "': '"
|
||||
<< option.arg
|
||||
<< "'.\nValid devices are: "
|
||||
<< VtkmArg::GetValidDeviceNames()
|
||||
<< "\n");
|
||||
return opt::ARG_ILLEGAL;
|
||||
}
|
||||
|
||||
return opt::ARG_OK;
|
||||
}
|
||||
|
||||
static bool DeviceIsAvailable(vtkm::cont::DeviceAdapterId id)
|
||||
{
|
||||
if (id == vtkm::cont::DeviceAdapterTagAny{})
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (id.GetValue() <= 0 || id.GetValue() >= VTKM_MAX_DEVICE_ADAPTER_ID ||
|
||||
id == vtkm::cont::DeviceAdapterTagUndefined{})
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker();
|
||||
bool result = false;
|
||||
try
|
||||
{
|
||||
result = tracker.CanRunOn(id);
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
result = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static std::string GetValidDeviceNames()
|
||||
{
|
||||
std::ostringstream names;
|
||||
names << "\"Any\" ";
|
||||
|
||||
auto tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker();
|
||||
for (vtkm::Int8 i = 0; i < VTKM_MAX_DEVICE_ADAPTER_ID; ++i)
|
||||
{
|
||||
auto id = vtkm::cont::make_DeviceAdapterId(i);
|
||||
if (VtkmArg::DeviceIsAvailable(id))
|
||||
{
|
||||
names << "\"" << tracker.GetDeviceName(id) << "\" ";
|
||||
}
|
||||
}
|
||||
return names.str();
|
||||
}
|
||||
};
|
||||
|
||||
static opt::Descriptor Usage[] = {
|
||||
{ PREAMBLE, 0, "", "", opt::Arg::None, "Usage information:\n" },
|
||||
{ DEVICE,
|
||||
0,
|
||||
"d",
|
||||
"device",
|
||||
VtkmArg::IsDevice,
|
||||
" --device, -d [dev] \tForce device to dev. Omit device to list available devices." },
|
||||
{ LOGLEVEL, 0, "v", "", opt::Arg::None, " -v \tSpecify a log level (when logging is enabled)." },
|
||||
{ HELP, 0, "h", "help", opt::Arg::None, " --help, -h \tPrint usage information." },
|
||||
{ 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
} // end anon namespace
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
VTKM_CONT
|
||||
InitializeResult Initialize(int& argc, char* argv[], InitializeOptions opts)
|
||||
{
|
||||
InitializeResult config;
|
||||
|
||||
// initialize logging first -- it'll pop off the options it consumes:
|
||||
if (argc == 0 || argv == nullptr)
|
||||
{
|
||||
vtkm::cont::InitLogging();
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkm::cont::InitLogging(argc, argv);
|
||||
}
|
||||
|
||||
{ // Parse VTKm options:
|
||||
// Remove argv[0] (executable name) if present:
|
||||
int vtkmArgc = argc > 0 ? argc - 1 : 0;
|
||||
char** vtkmArgv = vtkmArgc > 0 ? argv + 1 : argv;
|
||||
|
||||
opt::Stats stats(Usage, argc, argv);
|
||||
std::unique_ptr<opt::Option[]> options{ new opt::Option[stats.options_max] };
|
||||
std::unique_ptr<opt::Option[]> buffer{ new opt::Option[stats.buffer_max] };
|
||||
opt::Parser parse(Usage, vtkmArgc, vtkmArgv, options.get(), buffer.get());
|
||||
|
||||
if (parse.error())
|
||||
{
|
||||
opt::printUsage(std::cerr, Usage);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (options[HELP])
|
||||
{
|
||||
opt::printUsage(std::cout, Usage);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (options[DEVICE])
|
||||
{
|
||||
auto id = vtkm::cont::make_DeviceAdapterId(options[DEVICE].arg);
|
||||
auto tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker();
|
||||
VTKM_LOG_S(vtkm::cont::LogLevel::Info,
|
||||
"Forcing device '" << tracker.GetDeviceName(id) << "'");
|
||||
tracker.ForceDevice(id);
|
||||
config.Device = id;
|
||||
}
|
||||
else if ((opts & InitializeOptions::RequireDevice) != InitializeOptions::None)
|
||||
{
|
||||
auto devices = VtkmArg::GetValidDeviceNames();
|
||||
VTKM_LOG_ALWAYS_S(vtkm::cont::LogLevel::Error,
|
||||
"Target device must be specified via -d or --device.\n"
|
||||
"Valid devices: "
|
||||
<< devices
|
||||
<< "\n");
|
||||
opt::printUsage(std::cerr, Usage);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for (int i = 0; i < parse.nonOptionsCount(); i++)
|
||||
{
|
||||
config.Arguments.push_back(std::string(parse.nonOption(i)));
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
InitializeResult Initialize()
|
||||
{
|
||||
vtkm::cont::InitLogging();
|
||||
return InitializeResult{};
|
||||
}
|
||||
}
|
||||
} // end namespace vtkm::cont
|
94
vtkm/cont/Initialize.h
Normal file
94
vtkm/cont/Initialize.h
Normal file
@ -0,0 +1,94 @@
|
||||
//============================================================================
|
||||
// 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 2016 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2016 UT-Battelle, LLC.
|
||||
// Copyright 2016 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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_Initialize_h
|
||||
#define vtk_m_cont_Initialize_h
|
||||
|
||||
#include <vtkm/cont/internal/DeviceAdapterTag.h>
|
||||
#include <vtkm/cont/vtkm_cont_export.h>
|
||||
#include <vtkm/internal/ExportMacros.h>
|
||||
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace cont
|
||||
{
|
||||
|
||||
struct InitializeResult
|
||||
{
|
||||
/// Device passed into -d, or undefined
|
||||
DeviceAdapterId Device = DeviceAdapterTagUndefined{};
|
||||
|
||||
/// Non-option arguments
|
||||
std::vector<std::string> Arguments;
|
||||
};
|
||||
|
||||
enum class InitializeOptions
|
||||
{
|
||||
None = 0x0,
|
||||
RequireDevice = 0x1
|
||||
};
|
||||
|
||||
// Allow options to be used as a bitfield
|
||||
inline InitializeOptions operator|(const InitializeOptions& lhs, const InitializeOptions& rhs)
|
||||
{
|
||||
using T = std::underlying_type<InitializeOptions>::type;
|
||||
return static_cast<InitializeOptions>(static_cast<T>(lhs) | static_cast<T>(rhs));
|
||||
}
|
||||
inline InitializeOptions operator&(const InitializeOptions& lhs, const InitializeOptions& rhs)
|
||||
{
|
||||
using T = std::underlying_type<InitializeOptions>::type;
|
||||
return static_cast<InitializeOptions>(static_cast<T>(lhs) & static_cast<T>(rhs));
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the VTKm library, parsing arguments when provided:
|
||||
* - Sets log level names when logging is configured.
|
||||
* - Sets the calling thread as the main thread for logging purposes.
|
||||
* - Sets the default log level to the argument provided to -v.
|
||||
* - Forces usage of the device name passed to -d or --device.
|
||||
* - Prints usage when -h is passed.
|
||||
*
|
||||
* The parameterless version only sets up log level names.
|
||||
*
|
||||
* Additional options may be supplied via the @a opts argument, such as
|
||||
* requiring the -d option.
|
||||
*
|
||||
* Results are available in the returned InitializeResult.
|
||||
*
|
||||
* @note This method may call exit() on parse error.
|
||||
* @{
|
||||
*/
|
||||
VTKM_CONT_EXPORT
|
||||
VTKM_CONT
|
||||
InitializeResult Initialize(int& argc,
|
||||
char* argv[],
|
||||
InitializeOptions opts = InitializeOptions::None);
|
||||
VTKM_CONT_EXPORT
|
||||
VTKM_CONT
|
||||
InitializeResult Initialize();
|
||||
/**@}*/
|
||||
}
|
||||
} // end namespace vtkm::cont
|
||||
|
||||
|
||||
#endif // vtk_m_cont_Initialize_h
|
@ -40,9 +40,10 @@
|
||||
#include <vtkm/testing/Testing.h> // for HumanSize
|
||||
|
||||
#include <cassert>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <unordered_map>
|
||||
|
||||
#ifdef VTKM_ENABLE_LOGGING
|
||||
namespace
|
||||
{
|
||||
|
||||
@ -61,7 +62,7 @@ using LevelMapType = std::unordered_map<vtkm::cont::LogLevel, std::string, LogHa
|
||||
static bool Initialized = false;
|
||||
static LevelMapType LogLevelNames;
|
||||
|
||||
void setLogLevelName(vtkm::cont::LogLevel level, const std::string& name)
|
||||
void setLogLevelName(vtkm::cont::LogLevel level, const std::string& name) noexcept
|
||||
{
|
||||
// if the log has been initialized, prevent modifications of the name map
|
||||
// to prevent race conditions.
|
||||
@ -71,11 +72,25 @@ void setLogLevelName(vtkm::cont::LogLevel level, const std::string& name)
|
||||
}
|
||||
}
|
||||
|
||||
const char* verbosityToNameCallback(loguru::Verbosity verbosity)
|
||||
// Throws std::out_of_range if level not found.
|
||||
const std::string& getLogLevelName(vtkm::cont::LogLevel level)
|
||||
{
|
||||
const LevelMapType& names = LogLevelNames;
|
||||
auto name = names.find(static_cast<vtkm::cont::LogLevel>(verbosity));
|
||||
return name != names.end() ? name->second.c_str() : nullptr;
|
||||
return names.at(static_cast<vtkm::cont::LogLevel>(level));
|
||||
}
|
||||
|
||||
#ifdef VTKM_ENABLE_LOGGING
|
||||
const char* verbosityToNameCallback(loguru::Verbosity v)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Calling c_str on const string&.
|
||||
return getLogLevelName(static_cast<vtkm::cont::LogLevel>(v)).c_str();
|
||||
}
|
||||
catch (std::out_of_range&)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
loguru::Verbosity nameToVerbosityCallback(const char* name)
|
||||
@ -90,9 +105,9 @@ loguru::Verbosity nameToVerbosityCallback(const char* name)
|
||||
}
|
||||
return loguru::Verbosity_INVALID;
|
||||
}
|
||||
#endif // VTKM_ENABLE_LOGGING
|
||||
|
||||
} // end anon namespace
|
||||
#endif // VTKM_ENABLE_LOGGING
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
@ -102,7 +117,6 @@ namespace cont
|
||||
VTKM_CONT
|
||||
void InitLogging(int& argc, char* argv[])
|
||||
{
|
||||
#ifdef VTKM_ENABLE_LOGGING
|
||||
SetLogLevelName(vtkm::cont::LogLevel::Off, "Off");
|
||||
SetLogLevelName(vtkm::cont::LogLevel::Fatal, "FATL");
|
||||
SetLogLevelName(vtkm::cont::LogLevel::Error, "ERR");
|
||||
@ -114,19 +128,21 @@ void InitLogging(int& argc, char* argv[])
|
||||
SetLogLevelName(vtkm::cont::LogLevel::MemTransfer, "MemT");
|
||||
SetLogLevelName(vtkm::cont::LogLevel::Cast, "Cast");
|
||||
|
||||
|
||||
#ifdef VTKM_ENABLE_LOGGING
|
||||
loguru::set_verbosity_to_name_callback(&verbosityToNameCallback);
|
||||
loguru::set_name_to_verbosity_callback(&nameToVerbosityCallback);
|
||||
|
||||
loguru::init(argc, argv);
|
||||
|
||||
// Prevent LogLevelNames from being modified (makes thread safety easier)
|
||||
Initialized = true;
|
||||
|
||||
LOG_F(INFO, "Logging initialized.");
|
||||
#else // VTKM_ENABLE_LOGGING
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
#endif // VTKM_ENABLE_LOGGING
|
||||
|
||||
// Prevent LogLevelNames from being modified (makes thread safety easier)
|
||||
Initialized = true;
|
||||
}
|
||||
|
||||
void InitLogging()
|
||||
@ -214,17 +230,40 @@ std::string GetSizeString(vtkm::UInt64 bytes, int prec)
|
||||
VTKM_CONT
|
||||
void SetLogLevelName(LogLevel level, const std::string& name)
|
||||
{
|
||||
#ifdef VTKM_ENABLE_LOGGING
|
||||
if (Initialized)
|
||||
{
|
||||
VTKM_LOG_F(LogLevel::Error, "SetLogLevelName called after InitLogging.");
|
||||
return;
|
||||
}
|
||||
setLogLevelName(level, name);
|
||||
#else // VTKM_ENABLE_LOGGING
|
||||
(void)level;
|
||||
(void)name;
|
||||
#endif // VTKM_ENABLE_LOGGING
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
std::string GetLogLevelName(LogLevel level)
|
||||
{
|
||||
#ifdef VTKM_ENABLE_LOGGING
|
||||
{ // Check loguru lookup first:
|
||||
const char* name = loguru::get_verbosity_name(static_cast<loguru::Verbosity>(level));
|
||||
if (name)
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
try
|
||||
{
|
||||
return getLogLevelName(level);
|
||||
}
|
||||
catch (std::out_of_range&)
|
||||
{ /* fallthrough */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Create a string from the numeric value otherwise:
|
||||
using T = std::underlying_type<LogLevel>::type;
|
||||
return std::to_string(static_cast<T>(level));
|
||||
}
|
||||
}
|
||||
} // end namespace vtkm::cont
|
||||
|
@ -65,7 +65,7 @@
|
||||
/// Fatal levels are printed to stderr by default.
|
||||
///
|
||||
/// Additional logging features are enabled by calling vtkm::cont::InitLogging
|
||||
/// in an executable. This will:
|
||||
/// (or preferably, vtkm::cont::Initialize) in an executable. This will:
|
||||
/// - Set human-readable names for the log levels in the output.
|
||||
/// - Allow the stderr logging level to be set at runtime by passing a
|
||||
/// '-v [level]' argument to the executable.
|
||||
@ -169,6 +169,10 @@
|
||||
/// \def VTKM_LOG_SCOPE_FUNCTION(level)
|
||||
/// Equivalent to VTKM_LOG_SCOPE(__func__);
|
||||
|
||||
/// \def VTKM_LOG_ALWAYS_S(level, ...)
|
||||
/// This ostream-style log message is always emitted, even when logging is
|
||||
/// disabled at compile time.
|
||||
|
||||
/// \def VTKM_LOG_CAST_SUCC(inObj, outObj)
|
||||
/// \brief Convenience macro for logging the successful cast of dynamic object.
|
||||
/// \param inObj The dynamic object.
|
||||
@ -207,8 +211,10 @@
|
||||
#define VTKM_LOG_SCOPE_FUNCTION(level) \
|
||||
VTKM_LOG_SCOPE(static_cast<loguru::Verbosity>(level), __func__)
|
||||
#define VTKM_LOG_ERROR_CONTEXT(desc, data) ERROR_CONTEXT(desc, data)
|
||||
#define VTKM_LOG_ALWAYS_S(level, ...) VTKM_LOG_S(level, __VA_ARGS__)
|
||||
|
||||
// Convenience macros:
|
||||
|
||||
// Cast success:
|
||||
#define VTKM_LOG_CAST_SUCC(inObj, outObj) \
|
||||
VTKM_LOG_F(vtkm::cont::LogLevel::Cast, \
|
||||
@ -251,6 +257,12 @@
|
||||
#define VTKM_LOG_CAST_SUCC(inObj, outObj)
|
||||
#define VTKM_LOG_CAST_FAIL(inObj, outType)
|
||||
|
||||
// Always emitted. When logging is disabled, std::cerr is used.
|
||||
|
||||
#define VTKM_LOG_ALWAYS_S(level, ...) \
|
||||
(static_cast<int>(level) < 0 ? std::cerr : std::cout) << vtkm::cont::GetLogLevelName(level) \
|
||||
<< ": " << __VA_ARGS__ << "\n"
|
||||
|
||||
// TryExecute failures are still important enough to log, but we just write to
|
||||
// std::cerr when logging is disabled.
|
||||
#define VTKM_LOG_TRYEXECUTE_FAIL(errorMessage, functorName, deviceId) \
|
||||
@ -318,6 +330,9 @@ enum class LogLevel
|
||||
};
|
||||
|
||||
/**
|
||||
* This shouldn't be called directly -- prefer calling vtkm::cont::Initialize,
|
||||
* which takes care of logging as well as other initializations.
|
||||
*
|
||||
* Initializes logging. Sets up custom log level and thread names. Parses any
|
||||
* "-v [LogLevel]" arguments to set the stderr log level. This argument may
|
||||
* be either numeric, or the 4-character string printed in the output.
|
||||
@ -358,6 +373,15 @@ VTKM_CONT_EXPORT
|
||||
VTKM_CONT
|
||||
void SetLogLevelName(vtkm::cont::LogLevel level, const std::string& name);
|
||||
|
||||
/**
|
||||
* Get a human readable name for the log level. If a name has not been
|
||||
* registered via InitLogging or SetLogLevelName, the returned string just
|
||||
* contains the integer representation of the level.
|
||||
*/
|
||||
VTKM_CONT_EXPORT
|
||||
VTKM_CONT
|
||||
std::string GetLogLevelName(vtkm::cont::LogLevel level);
|
||||
|
||||
/**
|
||||
* The name to identify the current thread in the log output.
|
||||
* @{
|
||||
|
@ -269,5 +269,32 @@ DeviceAdapterNameType RuntimeDeviceTracker::GetDeviceName(DeviceAdapterId device
|
||||
// Device 0 is invalid:
|
||||
return this->Internals->DeviceNames[0];
|
||||
}
|
||||
|
||||
VTKM_CONT
|
||||
DeviceAdapterId RuntimeDeviceTracker::GetDeviceAdapterId(DeviceAdapterNameType name) const
|
||||
{
|
||||
if (name == "Any")
|
||||
{
|
||||
return vtkm::cont::DeviceAdapterTagAny{};
|
||||
}
|
||||
else if (name == "Error")
|
||||
{
|
||||
return vtkm::cont::DeviceAdapterTagError{};
|
||||
}
|
||||
else if (name == "Undefined")
|
||||
{
|
||||
return vtkm::cont::DeviceAdapterTagUndefined{};
|
||||
}
|
||||
|
||||
for (vtkm::Int8 id = 0; id < VTKM_MAX_DEVICE_ADAPTER_ID; ++id)
|
||||
{
|
||||
if (name == this->Internals->DeviceNames[id])
|
||||
{
|
||||
return vtkm::cont::make_DeviceAdapterId(id);
|
||||
}
|
||||
}
|
||||
|
||||
return vtkm::cont::DeviceAdapterTagUndefined{};
|
||||
}
|
||||
}
|
||||
} // namespace vtkm::cont
|
||||
|
@ -208,6 +208,12 @@ public:
|
||||
VTKM_CONT
|
||||
DeviceAdapterNameType GetDeviceName(DeviceAdapterId id) const;
|
||||
|
||||
/// Returns the id corresponding to the device adapter name. If @a name is
|
||||
/// not recognized, DeviceAdapterTagUndefined is returned.
|
||||
VTKM_CONT_EXPORT
|
||||
VTKM_CONT
|
||||
DeviceAdapterId GetDeviceAdapterId(DeviceAdapterNameType name) const;
|
||||
|
||||
private:
|
||||
std::shared_ptr<detail::RuntimeDeviceTrackerInternals> Internals;
|
||||
|
||||
|
@ -39,6 +39,7 @@ set(headers
|
||||
FunctorsGeneral.h
|
||||
IteratorFromArrayPortal.h
|
||||
KXSort.h
|
||||
OptionParser.h
|
||||
ParallelRadixSort.h
|
||||
ParallelRadixSortInterface.h
|
||||
ReverseConnectivityBuilder.h
|
||||
|
@ -31,5 +31,10 @@ DeviceAdapterNameType DeviceAdapterId::GetName() const
|
||||
{
|
||||
return vtkm::cont::GetGlobalRuntimeDeviceTracker().GetDeviceName(*this);
|
||||
}
|
||||
|
||||
DeviceAdapterId make_DeviceAdapterId(const DeviceAdapterNameType& name)
|
||||
{
|
||||
return vtkm::cont::GetGlobalRuntimeDeviceTracker().GetDeviceAdapterId(name);
|
||||
}
|
||||
}
|
||||
} // end namespace vtkm::cont
|
||||
|
@ -75,27 +75,8 @@ private:
|
||||
vtkm::Int8 Value;
|
||||
};
|
||||
|
||||
inline DeviceAdapterId make_DeviceAdapterIdFromName(const std::string& name)
|
||||
{
|
||||
vtkm::Int8 deviceId(VTKM_DEVICE_ADAPTER_ERROR);
|
||||
if (name == "SERIAL")
|
||||
{
|
||||
deviceId = VTKM_DEVICE_ADAPTER_SERIAL;
|
||||
}
|
||||
else if (name == "CUDA")
|
||||
{
|
||||
deviceId = VTKM_DEVICE_ADAPTER_CUDA;
|
||||
}
|
||||
else if (name == "TBB")
|
||||
{
|
||||
deviceId = VTKM_DEVICE_ADAPTER_TBB;
|
||||
}
|
||||
else if (name == "OPENMP")
|
||||
{
|
||||
deviceId = VTKM_DEVICE_ADAPTER_OPENMP;
|
||||
}
|
||||
return DeviceAdapterId(deviceId);
|
||||
}
|
||||
VTKM_CONT_EXPORT
|
||||
DeviceAdapterId make_DeviceAdapterId(const DeviceAdapterNameType& name);
|
||||
|
||||
inline DeviceAdapterId make_DeviceAdapterId(vtkm::Int8 id)
|
||||
{
|
||||
|
@ -1,3 +1,25 @@
|
||||
//=============================================================================
|
||||
//
|
||||
// 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 2018 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
||||
// Copyright 2018 UT-Battelle, LLC.
|
||||
// Copyright 2018 Los Alamos National Security.
|
||||
//
|
||||
// Under the terms of Contract DE-NA0003525 with NTESS,
|
||||
// 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.
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
* The Lean Mean C++ Option Parser
|
||||
*
|
||||
@ -228,7 +250,9 @@
|
||||
|
||||
namespace vtkm
|
||||
{
|
||||
namespace testing
|
||||
namespace cont
|
||||
{
|
||||
namespace internal
|
||||
{
|
||||
/** @brief The namespace of The Lean Mean C++ Option Parser. */
|
||||
namespace option
|
||||
@ -2958,10 +2982,10 @@ void printUsage(Function* prn,
|
||||
PrintUsageImplementation::printUsage(
|
||||
write, usage, width, last_column_min_percent, last_column_own_line_max_percent);
|
||||
}
|
||||
}
|
||||
// namespace option
|
||||
|
||||
} // namespace option
|
||||
}
|
||||
}
|
||||
// namespace vtkm::testing
|
||||
} // namespace vtkm::cont::internal
|
||||
|
||||
#endif /* OPTIONPARSER_H_ */
|
@ -22,7 +22,7 @@
|
||||
|
||||
#include <vtkm/cont/EnvironmentTracker.h>
|
||||
#include <vtkm/cont/Error.h>
|
||||
#include <vtkm/testing/OptionParser.h>
|
||||
#include <vtkm/cont/Initialize.h>
|
||||
#include <vtkm/testing/Testing.h>
|
||||
#include <vtkm/thirdparty/diy/Configure.h>
|
||||
|
||||
@ -45,23 +45,6 @@ namespace cont
|
||||
{
|
||||
namespace testing
|
||||
{
|
||||
namespace {
|
||||
using namespace vtkm::testing::option;
|
||||
// Lean parser related code
|
||||
enum optionIndex {DEVICE};
|
||||
struct Arg: public vtkm::testing::option::Arg
|
||||
{
|
||||
static ArgStatus Required(const Option& option, bool)
|
||||
{
|
||||
return option.arg == 0 ? vtkm::testing::option::ARG_ILLEGAL : vtkm::testing::option::ARG_OK;
|
||||
}
|
||||
};
|
||||
static Descriptor Usage[] =
|
||||
{
|
||||
{DEVICE, 0, "d", "device", Arg::Required, " -- device \t specify a device to run on."},
|
||||
{0,0,0,0,0,0}
|
||||
};
|
||||
}
|
||||
|
||||
struct Testing
|
||||
{
|
||||
@ -70,33 +53,7 @@ public:
|
||||
template <class Func>
|
||||
static VTKM_CONT int Run(Func function, int argc = 0, char* argv[] = nullptr)
|
||||
{
|
||||
argc-=(argc>0); argv+=(argc>0); // skip program name argv[0] if present
|
||||
Stats stats(Usage, argc, argv);
|
||||
Option* options = new Option[stats.options_max];
|
||||
Option* buffer = new Option[stats.buffer_max];
|
||||
|
||||
Parser parse(Usage, argc, argv, options, buffer);
|
||||
|
||||
if (parse.error())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (options[DEVICE])
|
||||
{
|
||||
Option* deviceOption = options[DEVICE];
|
||||
vtkm::cont::DeviceAdapterId deviceId = vtkm::cont::make_DeviceAdapterIdFromName(std::string(deviceOption->arg));
|
||||
vtkm::cont::GetGlobalRuntimeDeviceTracker().ForceDevice(deviceId);
|
||||
}
|
||||
|
||||
std::vector<std::string> nonOptions;
|
||||
for (int i = 0; i < parse.nonOptionsCount();i++)
|
||||
{
|
||||
nonOptions.push_back(std::string(parse.nonOption(i)));
|
||||
}
|
||||
|
||||
delete[] options;
|
||||
delete[] buffer;
|
||||
vtkm::cont::Initialize(argc, argv);
|
||||
|
||||
try
|
||||
{
|
||||
@ -129,38 +86,12 @@ public:
|
||||
template <class Func>
|
||||
static VTKM_CONT int RunOnDevice(Func function, int argc = 0, char* argv[] = nullptr)
|
||||
{
|
||||
argc-=(argc>0); argv+=(argc>0); // skip program name argv[0] if present
|
||||
Stats stats(Usage, argc, argv);
|
||||
Option* options = new Option[stats.options_max];
|
||||
Option* buffer = new Option[stats.buffer_max];
|
||||
|
||||
Parser parse(Usage, argc, argv, options, buffer);
|
||||
|
||||
if (parse.error())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
vtkm::cont::DeviceAdapterId deviceId = vtkm::cont::make_DeviceAdapterId(VTKM_DEVICE_ADAPTER_ERROR);
|
||||
if (options[DEVICE])
|
||||
{
|
||||
Option* deviceOption = options[DEVICE];
|
||||
deviceId = vtkm::cont::make_DeviceAdapterIdFromName(std::string(deviceOption->arg));
|
||||
vtkm::cont::GetGlobalRuntimeDeviceTracker().ForceDevice(deviceId);
|
||||
}
|
||||
|
||||
std::vector<std::string> nonOptions;
|
||||
for (int i = 0; i < parse.nonOptionsCount();i++)
|
||||
{
|
||||
nonOptions.push_back(std::string(parse.nonOption(i)));
|
||||
}
|
||||
|
||||
delete[] options;
|
||||
delete[] buffer;
|
||||
auto opts = vtkm::cont::InitializeOptions::RequireDevice;
|
||||
auto config = vtkm::cont::Initialize(argc, argv, opts);
|
||||
|
||||
try
|
||||
{
|
||||
function(deviceId);
|
||||
function(config.Device);
|
||||
}
|
||||
catch (vtkm::testing::Testing::TestFailure& error)
|
||||
{
|
||||
|
@ -22,7 +22,6 @@ set(headers
|
||||
Testing.h
|
||||
TestingMath.h
|
||||
TestingGeometry.h
|
||||
OptionParser.h
|
||||
VecTraitsTests.h
|
||||
)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user