From 408beefc0a642731ddf72035e40c8adff15bf050 Mon Sep 17 00:00:00 2001 From: nadavi Date: Wed, 26 May 2021 19:43:36 +0000 Subject: [PATCH] Implement RuntimeDeviceConfiguration --- vtkm/cont/CMakeLists.txt | 3 + vtkm/cont/Initialize.cxx | 153 ++++++-------- vtkm/cont/RuntimeDeviceInformation.cxx | 196 +++++++++++++++++- vtkm/cont/RuntimeDeviceInformation.h | 36 +++- vtkm/cont/RuntimeDeviceTracker.h | 2 +- vtkm/cont/cuda/DeviceAdapterCuda.h | 1 + vtkm/cont/cuda/internal/CMakeLists.txt | 1 + .../internal/RuntimeDeviceConfigurationCuda.h | 51 +++++ vtkm/cont/internal/CMakeLists.txt | 4 + vtkm/cont/internal/OptionParser.h | 6 +- vtkm/cont/internal/OptionParserArguments.h | 97 +++++++++ .../internal/RuntimeDeviceConfiguration.cxx | 95 +++++++++ .../internal/RuntimeDeviceConfiguration.h | 54 +++++ .../RuntimeDeviceConfigurationOptions.cxx | 71 +++++++ .../RuntimeDeviceConfigurationOptions.h | 50 +++++ vtkm/cont/internal/RuntimeDeviceOption.cxx | 105 ++++++++++ vtkm/cont/internal/RuntimeDeviceOption.h | 58 ++++++ vtkm/cont/kokkos/DeviceAdapterKokkos.h | 1 + vtkm/cont/kokkos/internal/CMakeLists.txt | 1 + .../RuntimeDeviceConfigurationKokkos.h | 92 ++++++++ vtkm/cont/openmp/DeviceAdapterOpenMP.h | 1 + vtkm/cont/openmp/internal/CMakeLists.txt | 1 + .../RuntimeDeviceConfigurationOpenMP.h | 63 ++++++ vtkm/cont/serial/DeviceAdapterSerial.h | 1 + vtkm/cont/serial/internal/CMakeLists.txt | 1 + .../RuntimeDeviceConfigurationSerial.h | 38 ++++ vtkm/cont/tbb/DeviceAdapterTBB.h | 1 + vtkm/cont/tbb/internal/CMakeLists.txt | 1 + .../internal/RuntimeDeviceConfigurationTBB.h | 52 +++++ vtkm/cont/testing/Testing.h | 67 +----- 30 files changed, 1143 insertions(+), 160 deletions(-) create mode 100644 vtkm/cont/cuda/internal/RuntimeDeviceConfigurationCuda.h create mode 100644 vtkm/cont/internal/OptionParserArguments.h create mode 100644 vtkm/cont/internal/RuntimeDeviceConfiguration.cxx create mode 100644 vtkm/cont/internal/RuntimeDeviceConfiguration.h create mode 100644 vtkm/cont/internal/RuntimeDeviceConfigurationOptions.cxx create mode 100644 vtkm/cont/internal/RuntimeDeviceConfigurationOptions.h create mode 100644 vtkm/cont/internal/RuntimeDeviceOption.cxx create mode 100644 vtkm/cont/internal/RuntimeDeviceOption.h create mode 100644 vtkm/cont/kokkos/internal/RuntimeDeviceConfigurationKokkos.h create mode 100644 vtkm/cont/openmp/internal/RuntimeDeviceConfigurationOpenMP.h create mode 100644 vtkm/cont/serial/internal/RuntimeDeviceConfigurationSerial.h create mode 100644 vtkm/cont/tbb/internal/RuntimeDeviceConfigurationTBB.h diff --git a/vtkm/cont/CMakeLists.txt b/vtkm/cont/CMakeLists.txt index bc77e3293..0026e528f 100644 --- a/vtkm/cont/CMakeLists.txt +++ b/vtkm/cont/CMakeLists.txt @@ -145,6 +145,9 @@ set(sources internal/Buffer.cxx internal/DeviceAdapterMemoryManager.cxx internal/DeviceAdapterMemoryManagerShared.cxx + internal/RuntimeDeviceConfiguration.cxx + internal/RuntimeDeviceConfigurationOptions.cxx + internal/RuntimeDeviceOption.cxx Initialize.cxx Logging.cxx RuntimeDeviceTracker.cxx diff --git a/vtkm/cont/Initialize.cxx b/vtkm/cont/Initialize.cxx index 9ba7e8558..3091b25cf 100644 --- a/vtkm/cont/Initialize.cxx +++ b/vtkm/cont/Initialize.cxx @@ -13,6 +13,7 @@ #include #include #include +#include #if defined(VTKM_ENABLE_KOKKOS) #include @@ -26,17 +27,7 @@ namespace opt = vtkm::cont::internal::option; namespace { -enum OptionIndex -{ - UNKNOWN, - DEVICE, - LOGLEVEL, // not parsed by this parser, but by loguru - HELP, - DEPRECATED_DEVICE, - DEPRECATED_LOGLEVEL -}; - -struct VtkmArg : public opt::Arg +struct VtkmDeviceArg : public opt::Arg { static opt::ArgStatus IsDevice(const opt::Option& option, bool msg) { @@ -48,20 +39,21 @@ struct VtkmArg : public opt::Arg VTKM_LOG_ALWAYS_S(vtkm::cont::LogLevel::Error, "Missing device after option '" << std::string(option.name, static_cast(option.namelen)) - << "'.\nValid devices are: " << VtkmArg::GetValidDeviceNames() << "\n"); + << "'.\nValid devices are: " << VtkmDeviceArg::GetValidDeviceNames() + << "\n"); } return opt::ARG_ILLEGAL; } auto id = vtkm::cont::make_DeviceAdapterId(option.arg); - if (!VtkmArg::DeviceIsAvailable(id)) + if (!VtkmDeviceArg::DeviceIsAvailable(id)) { VTKM_LOG_ALWAYS_S(vtkm::cont::LogLevel::Error, "Unavailable device specificed after option '" << std::string(option.name, static_cast(option.namelen)) << "': '" - << option.arg - << "'.\nValid devices are: " << VtkmArg::GetValidDeviceNames() << "\n"); + << option.arg << "'.\nValid devices are: " + << VtkmDeviceArg::GetValidDeviceNames() << "\n"); return opt::ARG_ILLEGAL; } @@ -93,7 +85,6 @@ struct VtkmArg : public opt::Arg } return result; } - static std::string GetValidDeviceNames() { std::ostringstream names; @@ -102,66 +93,16 @@ struct VtkmArg : public opt::Arg for (vtkm::Int8 i = 0; i < VTKM_MAX_DEVICE_ADAPTER_ID; ++i) { auto id = vtkm::cont::make_DeviceAdapterId(i); - if (VtkmArg::DeviceIsAvailable(id)) + if (VtkmDeviceArg::DeviceIsAvailable(id)) { names << "\"" << id.GetName() << "\" "; } } return names.str(); } - - static opt::ArgStatus Required(const opt::Option& option, bool msg) - { - if (option.arg == nullptr) - { - if (msg) - { - VTKM_LOG_ALWAYS_S(vtkm::cont::LogLevel::Error, - "Missing argument after option '" - << std::string(option.name, static_cast(option.namelen)) - << "'.\n"); - } - return opt::ARG_ILLEGAL; - } - else - { - return opt::ARG_OK; - } - } - - // Method used for guessing whether an option that do not support (perhaps that calling - // program knows about it) has an option attached to it (which should also be ignored). - static opt::ArgStatus UnknownOption(const opt::Option& option, bool msg) - { - // If we don't have an arg, obviously we don't have an arg. - if (option.arg == nullptr) - { - return opt::ARG_NONE; - } - - // The opt::Arg::Optional method will return that the ARG is OK if and only if - // the argument is attached to the option (e.g. --foo=bar). If that is the case, - // then we definitely want to report that the argument is OK. - if (opt::Arg::Optional(option, msg) == opt::ARG_OK) - { - return opt::ARG_OK; - } - - // Now things get tricky. Maybe the next argument is an option or maybe it is an - // argument for this option. We will guess that if the next argument does not - // look like an option, we will treat it as such. - if (option.arg[0] == '-') - { - return opt::ARG_NONE; - } - else - { - return opt::ARG_OK; - } - } }; -} // end anon namespace +} // namespace namespace vtkm { @@ -187,7 +128,9 @@ InitializeResult Initialize(int& argc, char* argv[], InitializeOptions opts) vtkm::cont::InitLogging(argc, argv, loggingFlag); } + #ifdef VTKM_ENABLE_KOKKOS + // TODO: remove this once runtime config updates are completely implemented vtkm::cont::kokkos::internal::Initialize(argc, argv); #endif @@ -195,41 +138,54 @@ InitializeResult Initialize(int& argc, char* argv[], InitializeOptions opts) std::vector usage; if ((opts & InitializeOptions::AddHelp) != InitializeOptions::None) { - usage.push_back({ UNKNOWN, 0, "", "", VtkmArg::UnknownOption, "Usage information:\n" }); + usage.push_back({ opt::OptionIndex::UNKNOWN, + 0, + "", + "", + opt::VtkmArg::UnknownOption, + "Usage information:\n" }); } usage.push_back( - { DEVICE, + { opt::OptionIndex::DEVICE, 0, "", "vtkm-device", - VtkmArg::IsDevice, + VtkmDeviceArg::IsDevice, " --vtkm-device \tForce device to dev. Omit device to list available devices." }); - usage.push_back({ DEPRECATED_DEVICE, + usage.push_back({ opt::OptionIndex::DEPRECATED_DEVICE, 0, "d", "device", - VtkmArg::IsDevice, + VtkmDeviceArg::IsDevice, " --device, -d \tDEPRECATED: use --vtkm-device to set the device" }); - usage.push_back( - { LOGLEVEL, 0, "", loggingFlagName.c_str(), VtkmArg::Required, loggingHelp.c_str() }); - usage.push_back({ DEPRECATED_LOGLEVEL, + usage.push_back({ opt::OptionIndex::LOGLEVEL, + 0, + "", + loggingFlagName.c_str(), + opt::VtkmArg::Required, + loggingHelp.c_str() }); + usage.push_back({ opt::OptionIndex::DEPRECATED_LOGLEVEL, 0, "v", "", - VtkmArg::Required, + opt::VtkmArg::Required, " -v <#|INFO|WARNING|ERROR|FATAL|OFF> \tDEPRECATED: use --vtkm-log-level to " "set the log level" }); if ((opts & InitializeOptions::AddHelp) != InitializeOptions::None) { - usage.push_back({ HELP, + usage.push_back({ opt::OptionIndex::HELP, 0, "h", "vtkm-help", opt::Arg::None, " --vtkm-help, -h \tPrint usage information." }); } + + // Bring in extra args used by the runtime device configuration options + vtkm::cont::internal::RuntimeDeviceConfigurationOptions runtimeDeviceOptions(usage); + // Required to collect unknown arguments when help is off. - usage.push_back({ UNKNOWN, 0, "", "", VtkmArg::UnknownOption, "" }); + usage.push_back({ opt::OptionIndex::UNKNOWN, 0, "", "", opt::VtkmArg::UnknownOption, "" }); usage.push_back({ 0, 0, 0, 0, 0, 0 }); { @@ -255,38 +211,38 @@ InitializeResult Initialize(int& argc, char* argv[], InitializeOptions opts) exit(1); } - if (options[HELP]) + if (options[opt::OptionIndex::HELP]) { std::cerr << config.Usage; exit(0); } - if (options[DEPRECATED_LOGLEVEL]) + if (options[opt::OptionIndex::DEPRECATED_LOGLEVEL]) { VTKM_LOG_S(vtkm::cont::LogLevel::Error, "Supplied Deprecated log level flag: " - << std::string{ options[DEPRECATED_LOGLEVEL].name } << ", use " << loggingFlag - << " instead."); + << std::string{ options[opt::OptionIndex::DEPRECATED_LOGLEVEL].name } << ", use " + << loggingFlag << " instead."); #ifdef VTKM_ENABLE_LOGGING loguru::g_stderr_verbosity = - loguru::get_verbosity_from_name(options[DEPRECATED_LOGLEVEL].arg); + loguru::get_verbosity_from_name(options[opt::OptionIndex::DEPRECATED_LOGLEVEL].arg); #endif // VTKM_ENABLE_LOGGING } - if (options[DEVICE] || options[DEPRECATED_DEVICE]) + if (options[opt::OptionIndex::DEVICE] || options[opt::OptionIndex::DEPRECATED_DEVICE]) { const char* arg = nullptr; - if (options[DEPRECATED_DEVICE]) + if (options[opt::OptionIndex::DEPRECATED_DEVICE]) { VTKM_LOG_S(vtkm::cont::LogLevel::Error, "Supplied Deprecated device flag " - << std::string{ options[DEPRECATED_DEVICE].name } + << std::string{ options[opt::OptionIndex::DEPRECATED_DEVICE].name } << ", use --vtkm-device instead"); - arg = options[DEPRECATED_DEVICE].arg; + arg = options[opt::OptionIndex::DEPRECATED_DEVICE].arg; } - if (options[DEVICE]) + if (options[opt::OptionIndex::DEVICE]) { - arg = options[DEVICE].arg; + arg = options[opt::OptionIndex::DEVICE].arg; } auto id = vtkm::cont::make_DeviceAdapterId(arg); if (id != vtkm::cont::DeviceAdapterTagAny{}) @@ -306,9 +262,9 @@ InitializeResult Initialize(int& argc, char* argv[], InitializeOptions opts) } else if ((opts & InitializeOptions::RequireDevice) != InitializeOptions::None) { - auto devices = VtkmArg::GetValidDeviceNames(); + 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 -d or --device.\n" + std::cerr << "Target device must be specified via --vtkm-device.\n" "Valid devices: " << devices << std::endl; if ((opts & InitializeOptions::AddHelp) != InitializeOptions::None) @@ -318,7 +274,9 @@ InitializeResult Initialize(int& argc, char* argv[], InitializeOptions opts) exit(1); } - for (const opt::Option* opt = options[UNKNOWN]; opt != nullptr; opt = opt->next()) + + for (const opt::Option* opt = options[opt::OptionIndex::UNKNOWN]; opt != nullptr; + opt = opt->next()) { if ((opts & InitializeOptions::ErrorOnBadOption) != InitializeOptions::None) { @@ -359,7 +317,8 @@ InitializeResult Initialize(int& argc, char* argv[], InitializeOptions opts) { copyArg = true; } - for (const opt::Option* opt = options[UNKNOWN]; !copyArg && opt != nullptr; opt = opt->next()) + for (const opt::Option* opt = options[opt::OptionIndex::UNKNOWN]; !copyArg && opt != nullptr; + opt = opt->next()) { if (thisArg == opt->name) { @@ -392,6 +351,12 @@ InitializeResult Initialize(int& argc, char* argv[], InitializeOptions opts) } } argc = destArg; + + { + runtimeDeviceOptions.Initialize(options.get()); + vtkm::cont::RuntimeDeviceInformation runtimeDevice; + runtimeDevice.GetRuntimeConfiguration(config.Device, runtimeDeviceOptions, argc, argv); + } } return config; diff --git a/vtkm/cont/RuntimeDeviceInformation.cxx b/vtkm/cont/RuntimeDeviceInformation.cxx index 937c3882c..f21440f87 100644 --- a/vtkm/cont/RuntimeDeviceInformation.cxx +++ b/vtkm/cont/RuntimeDeviceInformation.cxx @@ -14,6 +14,7 @@ #include #include #include +#include //Bring in each device adapters runtime class #include @@ -79,6 +80,65 @@ public: } }; +class RuntimeDeviceConfigurationInvalid + : public vtkm::cont::internal::RuntimeDeviceConfigurationBase +{ +public: + VTKM_CONT virtual ~RuntimeDeviceConfigurationInvalid() override final {} + + VTKM_CONT virtual void Initialize( + const vtkm::cont::internal::RuntimeDeviceConfigurationOptions&) const override final + { + throw vtkm::cont::ErrorBadDevice( + "Tried to initialiez the runtime device configuration for an invalid device"); + } + VTKM_CONT virtual void Initialize(const vtkm::cont::internal::RuntimeDeviceConfigurationOptions&, + int&, + char*[]) const override final + { + throw vtkm::cont::ErrorBadDevice( + "Tried to initialiez the runtime device configuration for an invalid device"); + } + + VTKM_CONT virtual vtkm::cont::DeviceAdapterId GetDevice() const override final + { + return vtkm::cont::DeviceAdapterTagUndefined{}; + } + + VTKM_CONT virtual void SetThreads(const vtkm::Id&) const override final + { + throw vtkm::cont::ErrorBadDevice("Tried to set the number of threads on an invalid device"); + } + + VTKM_CONT virtual void SetNumaRegions(const vtkm::Id&) const override final + { + throw vtkm::cont::ErrorBadDevice( + "Tried to set the number of numa regions on an invalid device"); + } + + VTKM_CONT virtual void SetDeviceInstance(const vtkm::Id&) const override final + { + throw vtkm::cont::ErrorBadDevice("Tried to set the device instance on an invalid device"); + } + + VTKM_CONT virtual vtkm::Id GetThreads() const override final + { + throw vtkm::cont::ErrorBadDevice("Tried to get the number of threads on an invalid device"); + } + + VTKM_CONT virtual vtkm::Id GetNumaRegions() const override final + { + throw vtkm::cont::ErrorBadDevice( + "Tried to get the number of numa regions on an invalid device"); + } + + VTKM_CONT virtual vtkm::Id GetDeviceInstance() const override final + { + throw vtkm::cont::ErrorBadDevice("Tried to get the device instance on an invalid device"); + } +}; + + struct VTKM_NEVER_EXPORT InitializeDeviceNames { vtkm::cont::DeviceAdapterNameType* Names; @@ -149,6 +209,54 @@ struct VTKM_NEVER_EXPORT InitializeDeviceMemoryManagers } }; +struct VTKM_NEVER_EXPORT InitializeRuntimeDeviceConfigurations +{ + std::unique_ptr* RuntimeConfigurations; + vtkm::cont::internal::RuntimeDeviceConfigurationOptions RuntimeConfigurationOptions; + + VTKM_CONT + InitializeRuntimeDeviceConfigurations( + std::unique_ptr* runtimeConfigurations, + const vtkm::cont::internal::RuntimeDeviceConfigurationOptions& configOptions) + : RuntimeConfigurations(runtimeConfigurations) + , RuntimeConfigurationOptions(configOptions) + { + if (!configOptions.IsInitialized()) + { + VTKM_LOG_S(vtkm::cont::LogLevel::Warn, + "Initializing 'RuntimeDeviceConfigurations' with uninitialized configOptions. Did " + "you call vtkm::cont::Initialize?"); + } + } + + template + VTKM_CONT void CreateRuntimeConfiguration(Device device, int& argc, char* argv[], std::true_type) + { + auto id = device.GetValue(); + + if (id > 0 && id < VTKM_MAX_DEVICE_ADAPTER_ID) + { + this->RuntimeConfigurations[id].reset( + new vtkm::cont::internal::RuntimeDeviceConfiguration); + this->RuntimeConfigurations[id]->Initialize(RuntimeConfigurationOptions, argc, argv); + } + } + + template + VTKM_CONT void CreateRuntimeConfiguration(Device, int&, char**, std::false_type) + { + // No runtime configuration for invalid devices. + } + + template + VTKM_CONT void operator()(Device device, int& argc, char* argv[]) + { + this->CreateRuntimeConfiguration( + device, argc, argv, std::integral_constant{}); + } +}; + + struct VTKM_NEVER_EXPORT RuntimeDeviceInformationFunctor { bool Exists = false; @@ -239,7 +347,61 @@ private: DeviceMemoryManagers[VTKM_MAX_DEVICE_ADAPTER_ID]; DeviceAdapterMemoryManagerInvalid InvalidManager; }; -} + +class RuntimeDeviceConfigurations +{ +public: + static vtkm::cont::internal::RuntimeDeviceConfigurationBase& GetRuntimeDeviceConfiguration( + vtkm::cont::DeviceAdapterId device, + const vtkm::cont::internal::RuntimeDeviceConfigurationOptions& configOptions, + int& argc, + char* argv[]) + { + const auto id = device.GetValue(); + if (device.IsValueValid()) + { + auto&& runtimeConfiguration = Instance(configOptions, argc, argv).DeviceConfigurations[id]; + if (runtimeConfiguration) + { + return *runtimeConfiguration.get(); + } + else + { + return Instance(configOptions, argc, argv).InvalidConfiguration; + } + } + else + { + return Instance(configOptions, argc, argv).InvalidConfiguration; + } + } + +private: + static RuntimeDeviceConfigurations& Instance( + const vtkm::cont::internal::RuntimeDeviceConfigurationOptions& configOptions, + int& argc, + char* argv[]) + { + static RuntimeDeviceConfigurations instance{ configOptions, argc, argv }; + return instance; + } + + RuntimeDeviceConfigurations( + const vtkm::cont::internal::RuntimeDeviceConfigurationOptions configOptions, + int& argc, + char* argv[]) + { + InitializeRuntimeDeviceConfigurations functor(this->DeviceConfigurations, configOptions); + vtkm::ListForEach(functor, VTKM_DEFAULT_DEVICE_ADAPTER_LIST(), argc, argv); + } + + friend struct InitializeRuntimeDeviceConfigurations; + + std::unique_ptr + DeviceConfigurations[VTKM_MAX_DEVICE_ADAPTER_ID]; + RuntimeDeviceConfigurationInvalid InvalidConfiguration; +}; +} // namespace namespace vtkm { @@ -326,8 +488,38 @@ RuntimeDeviceInformation::GetMemoryManager(DeviceAdapterId device) const else { throw vtkm::cont::ErrorBadValue( - "Attempted to get a DeviceAdapterMemoryManager for an invalid device."); + "Attempted to get a DeviceAdapterMemoryManager for an invalid device '" + device.GetName() + + "'"); } } + +VTKM_CONT vtkm::cont::internal::RuntimeDeviceConfigurationBase& +RuntimeDeviceInformation::GetRuntimeConfiguration( + DeviceAdapterId device, + const vtkm::cont::internal::RuntimeDeviceConfigurationOptions& configOptions, + int& argc, + char* argv[]) const +{ + return RuntimeDeviceConfigurations::GetRuntimeDeviceConfiguration( + device, configOptions, argc, argv); } + +VTKM_CONT vtkm::cont::internal::RuntimeDeviceConfigurationBase& +RuntimeDeviceInformation::GetRuntimeConfiguration( + DeviceAdapterId device, + const vtkm::cont::internal::RuntimeDeviceConfigurationOptions& configOptions) const +{ + int placeholder; + return this->GetRuntimeConfiguration(device, configOptions, placeholder, nullptr); +} + +VTKM_CONT vtkm::cont::internal::RuntimeDeviceConfigurationBase& +RuntimeDeviceInformation::GetRuntimeConfiguration(DeviceAdapterId device) const +{ + vtkm::cont::internal::RuntimeDeviceConfigurationOptions placeholder; + return this->GetRuntimeConfiguration(device, placeholder); +} + + } // namespace vtkm::cont +} // namespace vtkm diff --git a/vtkm/cont/RuntimeDeviceInformation.h b/vtkm/cont/RuntimeDeviceInformation.h index 49af37d85..51fc870db 100644 --- a/vtkm/cont/RuntimeDeviceInformation.h +++ b/vtkm/cont/RuntimeDeviceInformation.h @@ -12,6 +12,7 @@ #include #include +#include #include namespace vtkm @@ -53,8 +54,41 @@ public: /// VTKM_CONT vtkm::cont::internal::DeviceAdapterMemoryManagerBase& GetMemoryManager(DeviceAdapterId id) const; + + /// Returns a reference to a `RuntimeDeviceConfiguration` that will work with the + /// given device. If the device in question is not valid, a placeholder + /// `InvalidRuntimeDeviceConfiguration` will be returned. Attempting to + /// call any of the methods of this object will result in a runtime exception. + /// The fully loaded version of this method is automatically called at the end + /// of `vkmt::cont::Initialize` which performs automated setup of all runtime + /// devices using parsed vtkm arguments. + /// + /// params: + /// configOptions - VTKm provided options that should be included when initializing + /// a given RuntimeDeviceConfiguration + /// argc - The number of command line arguments to parse when Initializing + /// a given RuntimeDeviceConfiguration + /// argv - The extra command line arguments to parse when Initializing a given + /// RuntimeDeviceConfiguration. This argument is mainlued used in conjuction + /// with Kokkos config arg parsing to include specific --kokkos command + /// line flags and environment variables. + VTKM_CONT + vtkm::cont::internal::RuntimeDeviceConfigurationBase& GetRuntimeConfiguration( + DeviceAdapterId id, + const vtkm::cont::internal::RuntimeDeviceConfigurationOptions& configOptions, + int& argc, + char* argv[] = nullptr) const; + + VTKM_CONT + vtkm::cont::internal::RuntimeDeviceConfigurationBase& GetRuntimeConfiguration( + DeviceAdapterId id, + const vtkm::cont::internal::RuntimeDeviceConfigurationOptions& configOptions) const; + + VTKM_CONT + vtkm::cont::internal::RuntimeDeviceConfigurationBase& GetRuntimeConfiguration( + DeviceAdapterId id) const; }; -} } // namespace vtkm::cont +} // namespace vtkm #endif //vtk_m_cont_RuntimeDeviceInformation_h diff --git a/vtkm/cont/RuntimeDeviceTracker.h b/vtkm/cont/RuntimeDeviceTracker.h index 0ab1b5379..9d594e2ec 100644 --- a/vtkm/cont/RuntimeDeviceTracker.h +++ b/vtkm/cont/RuntimeDeviceTracker.h @@ -226,4 +226,4 @@ vtkm::cont::RuntimeDeviceTracker& GetRuntimeDeviceTracker(); } } // namespace vtkm::cont -#endif //vtk_m_filter_RuntimeDeviceTracker_h +#endif //vtk_m_cont_RuntimeDeviceTracker_h diff --git a/vtkm/cont/cuda/DeviceAdapterCuda.h b/vtkm/cont/cuda/DeviceAdapterCuda.h index b0101c4f1..4a905cf5f 100644 --- a/vtkm/cont/cuda/DeviceAdapterCuda.h +++ b/vtkm/cont/cuda/DeviceAdapterCuda.h @@ -22,6 +22,7 @@ #include #include +#include #ifndef VTKM_NO_DEPRECATED_VIRTUAL #include #endif //VTKM_NO_DEPRECATED_VIRTUAL diff --git a/vtkm/cont/cuda/internal/CMakeLists.txt b/vtkm/cont/cuda/internal/CMakeLists.txt index 21459c44a..0c53cdc4a 100644 --- a/vtkm/cont/cuda/internal/CMakeLists.txt +++ b/vtkm/cont/cuda/internal/CMakeLists.txt @@ -16,6 +16,7 @@ set(headers DeviceAdapterTagCuda.h DeviceAdapterTimerImplementationCuda.h MakeThrustIterator.h + RuntimeDeviceConfigurationCuda.h ScopedCudaStackSize.h ThrustExceptionHandler.h ) diff --git a/vtkm/cont/cuda/internal/RuntimeDeviceConfigurationCuda.h b/vtkm/cont/cuda/internal/RuntimeDeviceConfigurationCuda.h new file mode 100644 index 000000000..1c8eeec4b --- /dev/null +++ b/vtkm/cont/cuda/internal/RuntimeDeviceConfigurationCuda.h @@ -0,0 +1,51 @@ +//============================================================================ +// 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. +//============================================================================ +#ifndef vtk_m_cont_cuda_internal_RuntimeDeviceConfigurationCuda_h +#define vtk_m_cont_cuda_internal_RuntimeDeviceConfigurationCuda_h + +#include +#include + +namespace vtkm +{ +namespace cont +{ +namespace internal +{ + +template <> +class RuntimeDeviceConfiguration + : public vtkm::cont::internal::RuntimeDeviceConfigurationBase +{ + VTKM_CONT vtkm::cont::DeviceAdapterId GetDevice() const override final + { + return vtkm::cont::DeviceAdapterTagCuda{}; + } + + VTKM_CONT void Initialize(const RuntimeDeviceConfigurationOptions&) const override final + { + // TODO: Init cuda runtime from parsed configOptions + } + + VTKM_CONT void SetDeviceInstance(const vtkm::Id&) const override final + { + // TODO: set the cuda device instance + } + + VTKM_CONT vtkm::Id GetDeviceInstance() const override final + { + // TODO: Get the cuda device instance (also maybe a list of available devices?) + } +}; +} // namespace vtkm::cont::internal +} // namespace vtkm::cont +} // namespace vtkm + +#endif //vtk_m_cont_cuda_internal_RuntimeDeviceConfigurationCuda_h diff --git a/vtkm/cont/internal/CMakeLists.txt b/vtkm/cont/internal/CMakeLists.txt index f0eee5bab..7f0a45233 100644 --- a/vtkm/cont/internal/CMakeLists.txt +++ b/vtkm/cont/internal/CMakeLists.txt @@ -27,10 +27,14 @@ set(headers IteratorFromArrayPortal.h KXSort.h OptionParser.h + OptionParserArguments.h ParallelRadixSort.h ParallelRadixSortInterface.h PointLocatorBase.h ReverseConnectivityBuilder.h + RuntimeDeviceConfiguration.h + RuntimeDeviceConfigurationOptions.h + RuntimeDeviceOption.h StorageDeprecated.h StorageError.h Variant.h diff --git a/vtkm/cont/internal/OptionParser.h b/vtkm/cont/internal/OptionParser.h index 1be547707..2e0d6127d 100644 --- a/vtkm/cont/internal/OptionParser.h +++ b/vtkm/cont/internal/OptionParser.h @@ -32,6 +32,7 @@ namespace cont namespace internal { + // Check to make sure that optionparser.h has not been included before. If it has, remove its // header guard so we can include it again under our namespace. #ifdef OPTIONPARSER_H_ @@ -53,9 +54,10 @@ namespace internal // Remove the header guard for other inclusion. #undef OPTIONPARSER_H_ #endif -} -} + } // namespace vtkm::cont::internal +} // namespace vtkm::cont +} // namespace vtkm VTKM_THIRDPARTY_POST_INCLUDE diff --git a/vtkm/cont/internal/OptionParserArguments.h b/vtkm/cont/internal/OptionParserArguments.h new file mode 100644 index 000000000..a45954d95 --- /dev/null +++ b/vtkm/cont/internal/OptionParserArguments.h @@ -0,0 +1,97 @@ +//============================================================================ +// 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. +//============================================================================ +#ifndef vtk_m_cont_internal_OptionParserArguments_h +#define vtk_m_cont_internal_OptionParserArguments_h + +#include +#include + +namespace vtkm +{ +namespace cont +{ +namespace internal +{ +namespace option +{ + +// Store options supported by the parser here for usage in multiple modules +enum OptionIndex +{ + UNKNOWN, + DEVICE, + LOGLEVEL, // not parsed by this parser, but by loguru + HELP, + DEPRECATED_DEVICE, + DEPRECATED_LOGLEVEL, + NUM_THREADS, + NUMA_REGIONS, + DEVICE_INSTANCE +}; + +struct VtkmArg : public option::Arg +{ + static option::ArgStatus Required(const option::Option& option, bool msg) + { + if (option.arg == nullptr) + { + if (msg) + { + VTKM_LOG_ALWAYS_S(vtkm::cont::LogLevel::Error, + "Missing argument after option '" + << std::string(option.name, static_cast(option.namelen)) + << "'.\n"); + } + return option::ARG_ILLEGAL; + } + else + { + return option::ARG_OK; + } + } + + // Method used for guessing whether an option that do not support (perhaps that calling + // program knows about it) has an option attached to it (which should also be ignored). + static option::ArgStatus UnknownOption(const option::Option& option, bool msg) + { + // If we don't have an arg, obviously we don't have an arg. + if (option.arg == nullptr) + { + return option::ARG_NONE; + } + + // The option::Arg::Optional method will return that the ARG is OK if and only if + // the argument is attached to the option (e.g. --foo=bar). If that is the case, + // then we definitely want to report that the argument is OK. + if (option::Arg::Optional(option, msg) == option::ARG_OK) + { + return option::ARG_OK; + } + + // Now things get tricky. Maybe the next argument is an option or maybe it is an + // argument for this option. We will guess that if the next argument does not + // look like an option, we will treat it as such. + if (option.arg[0] == '-') + { + return option::ARG_NONE; + } + else + { + return option::ARG_OK; + } + } +}; + +} // namespace vtkm::cont::internal::option +} // namespace vtkm::cont::internal +} // namespace vtkm::cont +} // namespace vtkm + +#endif // vtk_m_cont_internal_OptionParserArguments_h diff --git a/vtkm/cont/internal/RuntimeDeviceConfiguration.cxx b/vtkm/cont/internal/RuntimeDeviceConfiguration.cxx new file mode 100644 index 000000000..b67ab7501 --- /dev/null +++ b/vtkm/cont/internal/RuntimeDeviceConfiguration.cxx @@ -0,0 +1,95 @@ +//============================================================================ +// 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 + +#include + +namespace vtkm +{ +namespace cont +{ +namespace internal +{ + +RuntimeDeviceConfigurationBase::~RuntimeDeviceConfigurationBase() noexcept = default; + +void RuntimeDeviceConfigurationBase::Initialize( + const RuntimeDeviceConfigurationOptions& configOptions) const +{ + if (configOptions.VTKmNumThreads.IsSet()) + { + this->SetThreads(configOptions.VTKmNumThreads.GetValue()); + } + if (configOptions.VTKmNumaRegions.IsSet()) + { + this->SetNumaRegions(configOptions.VTKmNumaRegions.GetValue()); + } + if (configOptions.VTKmDeviceInstance.IsSet()) + { + this->SetDeviceInstance(configOptions.VTKmDeviceInstance.GetValue()); + } +} + +void RuntimeDeviceConfigurationBase::Initialize( + const RuntimeDeviceConfigurationOptions& configOptions, + int&, + char*[]) const +{ + this->Initialize(configOptions); +} + +void RuntimeDeviceConfigurationBase::SetThreads(const vtkm::Id&) const +{ + VTKM_LOG_S(vtkm::cont::LogLevel::Warn, + "Called 'SetThreads' for unsupported Device '" << this->GetDevice().GetName() + << "', no-op"); +} + +void RuntimeDeviceConfigurationBase::SetNumaRegions(const vtkm::Id&) const +{ + VTKM_LOG_S(vtkm::cont::LogLevel::Warn, + "Called 'SetNumaRegions' for unsupported Device '" << this->GetDevice().GetName() + << "', no-op"); +} + +void RuntimeDeviceConfigurationBase::SetDeviceInstance(const vtkm::Id&) const +{ + VTKM_LOG_S(vtkm::cont::LogLevel::Warn, + "Called 'SetDeviceInstance' for unsupported Device '" << this->GetDevice().GetName() + << "', no-op"); +} + +vtkm::Id RuntimeDeviceConfigurationBase::GetThreads() const +{ + VTKM_LOG_S(vtkm::cont::LogLevel::Warn, + "Called 'GetThreads' for unsupported Device '" << this->GetDevice().GetName() + << "', returning -1"); + return -1; +} + +vtkm::Id RuntimeDeviceConfigurationBase::GetNumaRegions() const +{ + VTKM_LOG_S(vtkm::cont::LogLevel::Warn, + "Called 'GetNumaRegions' for unsupported Device '" << this->GetDevice().GetName() + << "', returning -1"); + return -1; +} + +vtkm::Id RuntimeDeviceConfigurationBase::GetDeviceInstance() const +{ + VTKM_LOG_S(vtkm::cont::LogLevel::Warn, + "Called 'GetDeviceInstance' for unsupported Device '" << this->GetDevice().GetName() + << "', returning -1"); + return -1; +} + +} // namespace vtkm::cont::internal +} // namespace vtkm::cont +} // namespace vtkm diff --git a/vtkm/cont/internal/RuntimeDeviceConfiguration.h b/vtkm/cont/internal/RuntimeDeviceConfiguration.h new file mode 100644 index 000000000..ee25fd062 --- /dev/null +++ b/vtkm/cont/internal/RuntimeDeviceConfiguration.h @@ -0,0 +1,54 @@ +//============================================================================ +// 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. +//============================================================================ +#ifndef vtk_m_cont_internal_RuntimeDeviceConfiguration_h +#define vtk_m_cont_internal_RuntimeDeviceConfiguration_h + +#include + +#include +#include + +#include + +namespace vtkm +{ +namespace cont +{ +namespace internal +{ + +class VTKM_CONT_EXPORT RuntimeDeviceConfigurationBase +{ +public: + VTKM_CONT virtual ~RuntimeDeviceConfigurationBase() noexcept; + VTKM_CONT virtual vtkm::cont::DeviceAdapterId GetDevice() const = 0; + + VTKM_CONT virtual void Initialize(const RuntimeDeviceConfigurationOptions& configOptions) const; + VTKM_CONT virtual void Initialize(const RuntimeDeviceConfigurationOptions& configOptions, + int&, + char*[]) const; + + VTKM_CONT virtual void SetThreads(const vtkm::Id&) const; + VTKM_CONT virtual void SetNumaRegions(const vtkm::Id&) const; + VTKM_CONT virtual void SetDeviceInstance(const vtkm::Id&) const; + + VTKM_CONT virtual vtkm::Id GetThreads() const; + VTKM_CONT virtual vtkm::Id GetNumaRegions() const; + VTKM_CONT virtual vtkm::Id GetDeviceInstance() const; +}; + +template +class RuntimeDeviceConfiguration; + +} // namespace vtkm::cont::internal +} // namespace vtkm::cont +} // namespace vtkm + +#endif // vtk_m_cont_internal_RuntimeDeviceConfiguration_h diff --git a/vtkm/cont/internal/RuntimeDeviceConfigurationOptions.cxx b/vtkm/cont/internal/RuntimeDeviceConfigurationOptions.cxx new file mode 100644 index 000000000..de33076ed --- /dev/null +++ b/vtkm/cont/internal/RuntimeDeviceConfigurationOptions.cxx @@ -0,0 +1,71 @@ +//============================================================================ +// 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 + +namespace vtkm +{ +namespace cont +{ +namespace internal +{ + +RuntimeDeviceConfigurationOptions::RuntimeDeviceConfigurationOptions() + : VTKmNumThreads(option::OptionIndex::NUM_THREADS, "VTKM_NUM_THREADS") + , VTKmNumaRegions(option::OptionIndex::NUMA_REGIONS, "VTKM_NUMA_REGIONS") + , VTKmDeviceInstance(option::OptionIndex::DEVICE_INSTANCE, "VTKM_DEVICE_INSTANCE") + , Initialized(false) +{ +} + +RuntimeDeviceConfigurationOptions::~RuntimeDeviceConfigurationOptions() noexcept = default; + +RuntimeDeviceConfigurationOptions::RuntimeDeviceConfigurationOptions( + std::vector& usage) + : RuntimeDeviceConfigurationOptions() +{ + usage.push_back( + { option::OptionIndex::NUM_THREADS, + 0, + "", + "vtkm-num-threads", + option::VtkmArg::Required, + " --vtkm-num-threads \tSets the number of threads to use for the selected device" }); + usage.push_back( + { option::OptionIndex::NUMA_REGIONS, + 0, + "", + "vtkm-numa-regions", + option::VtkmArg::Required, + " --vtkm-numa-regions \tSets the number of numa regions when using kokkos/OpenMP" }); + usage.push_back({ option::OptionIndex::DEVICE_INSTANCE, + 0, + "", + "vtkm-device-instance", + option::VtkmArg::Required, + " --vtkm-device-instance \tSets the device instance to use when using " + "kokkos/cuda" }); +} + +void RuntimeDeviceConfigurationOptions::Initialize(const option::Option* options) +{ + this->VTKmNumThreads.Initialize(options); + this->VTKmNumaRegions.Initialize(options); + this->VTKmDeviceInstance.Initialize(options); + this->Initialized = true; +} + +bool RuntimeDeviceConfigurationOptions::IsInitialized() const +{ + return this->Initialized; +} + +} // namespace vtkm::cont::internal +} // namespace vtkm::cont +} // namespace vtkm diff --git a/vtkm/cont/internal/RuntimeDeviceConfigurationOptions.h b/vtkm/cont/internal/RuntimeDeviceConfigurationOptions.h new file mode 100644 index 000000000..d0416da25 --- /dev/null +++ b/vtkm/cont/internal/RuntimeDeviceConfigurationOptions.h @@ -0,0 +1,50 @@ +//============================================================================ +// 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. +//============================================================================ +#ifndef vtk_m_cont_internal_RuntimeDeviceConfigurationOptions_h +#define vtk_m_cont_internal_RuntimeDeviceConfigurationOptions_h + +#include + +#include +#include + +#include + +namespace vtkm +{ +namespace cont +{ +namespace internal +{ + +class VTKM_CONT_EXPORT RuntimeDeviceConfigurationOptions +{ +public: + VTKM_CONT RuntimeDeviceConfigurationOptions(); + VTKM_CONT RuntimeDeviceConfigurationOptions(std::vector& usage); + + VTKM_CONT virtual ~RuntimeDeviceConfigurationOptions() noexcept; + + VTKM_CONT void Initialize(const option::Option* options); + VTKM_CONT bool IsInitialized() const; + + RuntimeDeviceOption VTKmNumThreads; + RuntimeDeviceOption VTKmNumaRegions; + RuntimeDeviceOption VTKmDeviceInstance; + +private: + bool Initialized; +}; + +} // namespace vtkm::cont::internal +} // namespace vtkm::cont +} // namespace vtkm + +#endif // vtk_m_cont_internal_RuntimeDeviceConfigurationOptions_h diff --git a/vtkm/cont/internal/RuntimeDeviceOption.cxx b/vtkm/cont/internal/RuntimeDeviceOption.cxx new file mode 100644 index 000000000..e0bfd9379 --- /dev/null +++ b/vtkm/cont/internal/RuntimeDeviceOption.cxx @@ -0,0 +1,105 @@ +//============================================================================ +// 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 + +#include + +#include + +namespace vtkm +{ +namespace cont +{ +namespace internal +{ + +namespace +{ + +VTKM_CONT vtkm::Id ParseOption(const std::string& input, const std::string& source) +{ + try + { + size_t pos; + auto value = std::stoi(input, &pos, 10); + if (pos != input.size()) + { + throw vtkm::cont::ErrorBadValue("Value '" + input + "' from source: '" + source + + "' has dangling characters, throwing"); + } + return value; + } + catch (const std::invalid_argument&) + { + throw vtkm::cont::ErrorBadValue("Value '" + input + + "' failed to parse as integer from source: '" + source + "'"); + } + catch (const std::out_of_range&) + { + throw vtkm::cont::ErrorBadValue("Value '" + input + "' out of range for source: '" + source + + "'"); + } +} + +} // namespace + +RuntimeDeviceOption::RuntimeDeviceOption(const option::OptionIndex& index, + const std::string& envName) + : Index(index) + , EnvName(envName) + , Source(RuntimeDeviceOptionSource::NOT_SET) +{ +} + +RuntimeDeviceOption::~RuntimeDeviceOption() noexcept = default; + +void RuntimeDeviceOption::Initialize(const option::Option* options) +{ + this->SetOptionFromEnvironment(); + this->SetOptionFromOptionsArray(options); +} + +void RuntimeDeviceOption::SetOptionFromEnvironment() +{ + if (std::getenv(EnvName.c_str()) != nullptr) + { + this->Value = ParseOption(std::getenv(EnvName.c_str()), "ENVIRONMENT: '" + EnvName + "'"); + this->Source = RuntimeDeviceOptionSource::ENVIRONMENT; + } +} + +void RuntimeDeviceOption::SetOptionFromOptionsArray(const option::Option* options) +{ + if (options[this->Index]) + { + this->Value = ParseOption(options[this->Index].arg, + "COMMAND_LINE: '" + std::string{ options[this->Index].name } + "'"); + this->Source = RuntimeDeviceOptionSource::COMMAND_LINE; + } +} + +void RuntimeDeviceOption::SetOption(const vtkm::Id& value) +{ + this->Value = value; + this->Source = RuntimeDeviceOptionSource::IN_CODE; +} + +vtkm::Id RuntimeDeviceOption::GetValue() const +{ + return this->Value; +} +bool RuntimeDeviceOption::IsSet() const +{ + return Source != RuntimeDeviceOptionSource::NOT_SET; +} + +} // namespace vtkm::cont::internal +} // namespace vtkm::cont +} // namespace vtkm diff --git a/vtkm/cont/internal/RuntimeDeviceOption.h b/vtkm/cont/internal/RuntimeDeviceOption.h new file mode 100644 index 000000000..2903f35df --- /dev/null +++ b/vtkm/cont/internal/RuntimeDeviceOption.h @@ -0,0 +1,58 @@ +//============================================================================ +// 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. +//============================================================================ +#ifndef vtk_m_cont_internal_RuntimeDeviceOption_h +#define vtk_m_cont_internal_RuntimeDeviceOption_h + +#include + +#include +#include + +namespace vtkm +{ +namespace cont +{ +namespace internal +{ + +enum class RuntimeDeviceOptionSource +{ + COMMAND_LINE, + ENVIRONMENT, + IN_CODE, + NOT_SET +}; + +class VTKM_CONT_EXPORT RuntimeDeviceOption +{ +public: + VTKM_CONT RuntimeDeviceOption(const option::OptionIndex& index, const std::string& envName); + + VTKM_CONT virtual ~RuntimeDeviceOption() noexcept; + + VTKM_CONT void Initialize(const option::Option* options); + VTKM_CONT void SetOptionFromEnvironment(); + VTKM_CONT void SetOptionFromOptionsArray(const option::Option* options); + VTKM_CONT void SetOption(const vtkm::Id& value); + VTKM_CONT vtkm::Id GetValue() const; + VTKM_CONT bool IsSet() const; + +private: + const option::OptionIndex Index; + const std::string EnvName; + RuntimeDeviceOptionSource Source; + vtkm::Id Value; +}; + +} // namespace vtkm::cont::internal +} // namespace vtkm::cont +} // namespace vtkm + +#endif // vtk_m_cont_internal_RuntimeDeviceOption_h diff --git a/vtkm/cont/kokkos/DeviceAdapterKokkos.h b/vtkm/cont/kokkos/DeviceAdapterKokkos.h index dda6093ec..76b921839 100644 --- a/vtkm/cont/kokkos/DeviceAdapterKokkos.h +++ b/vtkm/cont/kokkos/DeviceAdapterKokkos.h @@ -19,6 +19,7 @@ #include #include #include +#include #ifndef VTKM_NO_DEPRECATED_VIRTUAL #include #endif //VTKM_NO_DEPRECATED_VIRTUAL diff --git a/vtkm/cont/kokkos/internal/CMakeLists.txt b/vtkm/cont/kokkos/internal/CMakeLists.txt index 0a48f0b6c..077c3046c 100644 --- a/vtkm/cont/kokkos/internal/CMakeLists.txt +++ b/vtkm/cont/kokkos/internal/CMakeLists.txt @@ -16,6 +16,7 @@ set(headers Initialize.h KokkosAlloc.h KokkosTypes.h + RuntimeDeviceConfigurationKokkos.h ) if (NOT VTKm_NO_DEPRECATED_VIRTUAL) diff --git a/vtkm/cont/kokkos/internal/RuntimeDeviceConfigurationKokkos.h b/vtkm/cont/kokkos/internal/RuntimeDeviceConfigurationKokkos.h new file mode 100644 index 000000000..deda2be2d --- /dev/null +++ b/vtkm/cont/kokkos/internal/RuntimeDeviceConfigurationKokkos.h @@ -0,0 +1,92 @@ +//============================================================================ +// 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. +//============================================================================ +#ifndef vtk_m_cont_kokkos_internal_RuntimeDeviceConfigurationKokkos_h +#define vtk_m_cont_kokkos_internal_RuntimeDeviceConfigurationKokkos_h + +#include +#include + +#include + +namespace vtkm +{ +namespace cont +{ +namespace internal +{ + +template <> +class RuntimeDeviceConfiguration + : public vtkm::cont::internal::RuntimeDeviceConfigurationBase +{ +public: + VTKM_CONT vtkm::cont::DeviceAdapterId GetDevice() const override final + { + return vtkm::cont::DeviceAdapterTagKokkos{}; + } + + VTKM_CONT void Initialize(const RuntimeDeviceConfigurationOptions&) const override final + { + // TODO: load the kokkos config options + } + + VTKM_CONT void Initialize(const RuntimeDeviceConfigurationOptions& configOptions, + int& argc, + char* argv[]) const override final + { + // TODO: load the --kokkos command line args and store them for setting later + this->ParseKokkosArgs(argc, argv); + this->Initialize(configOptions); + } + + VTKM_CONT void SetThreads(const vtkm::Id& numThreads) const override final + { + // TODO: set the kokkos config object's num threads + } + + VTKM_CONT void SetNumaRegions(const vtkm::Id& numaRegions) const override final + { + // TODO: set the kokkos config object's numa regions + } + + VTKM_CONT void SetDeviceInstance(const vtkm::Id& deviceInstance) const override final + { + // TODO: set the kokkos config object's device instance + } + + VTKM_CONT vtkm::Id GetThreads() const override final + { + // TODO: get the value of the kokkos config object's num threads + } + + VTKM_CONT vtkm::Id GetNumaRegions() const override final + { + // TODO: get the value of the kokkos config object's numa regions + } + + VTKM_CONT vtkm::Id GetDeviceInstance() const override final + { + // TODO: get the value of the kokkos config object's device instance + } + + VTKM_CONT void ParseKokkosArgs(int& argc, char* argv[]) const + { + // TODO: ugh, kokkos. Manually parse the kokkos config args, store them for usage + } + +private: + Kokkos::InitArguments ParsedCommandLineArgs; + Kokkos::InitArguments VTKmInitializedArgs; +}; +} // namespace vtkm::cont::internal +} // namespace vtkm::cont +} // namespace vtkm + +#endif //vtk_m_cont_kokkos_internal_RuntimeDeviceConfigurationKokkos_h diff --git a/vtkm/cont/openmp/DeviceAdapterOpenMP.h b/vtkm/cont/openmp/DeviceAdapterOpenMP.h index 656156842..235bc0f21 100644 --- a/vtkm/cont/openmp/DeviceAdapterOpenMP.h +++ b/vtkm/cont/openmp/DeviceAdapterOpenMP.h @@ -17,6 +17,7 @@ #ifdef VTKM_ENABLE_OPENMP #include #include +#include #ifndef VTKM_NO_DEPRECATED_VIRTUAL #include #endif //VTKM_NO_DEPRECATED_VIRTUAL diff --git a/vtkm/cont/openmp/internal/CMakeLists.txt b/vtkm/cont/openmp/internal/CMakeLists.txt index 46cc37664..16c7f06df 100644 --- a/vtkm/cont/openmp/internal/CMakeLists.txt +++ b/vtkm/cont/openmp/internal/CMakeLists.txt @@ -18,6 +18,7 @@ set(headers ParallelRadixSortOpenMP.h ParallelScanOpenMP.h ParallelSortOpenMP.h + RuntimeDeviceConfigurationOpenMP.h ) if (NOT VTKm_NO_DEPRECATED_VIRTUAL) diff --git a/vtkm/cont/openmp/internal/RuntimeDeviceConfigurationOpenMP.h b/vtkm/cont/openmp/internal/RuntimeDeviceConfigurationOpenMP.h new file mode 100644 index 000000000..22d888c33 --- /dev/null +++ b/vtkm/cont/openmp/internal/RuntimeDeviceConfigurationOpenMP.h @@ -0,0 +1,63 @@ +//============================================================================ +// 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. +//============================================================================ +#ifndef vtk_m_cont_openmp_internal_RuntimeDeviceConfigurationOpenMP_h +#define vtk_m_cont_openmp_internal_RuntimeDeviceConfigurationOpenMP_h + +#include +#include + +namespace vtkm +{ +namespace cont +{ +namespace internal +{ + +template <> +class RuntimeDeviceConfiguration + : public vtkm::cont::internal::RuntimeDeviceConfigurationBase +{ + VTKM_CONT vtkm::cont::DeviceAdapterId GetDevice() const override final + { + return vtkm::cont::DeviceAdapterTagOpenMP{}; + } + + VTKM_CONT void Initialize(const RuntimeDeviceConfigurationOptions&) const override final + { + // TODO: Initialize threads/numa regions in OpenMP + } + + VTKM_CONT void SetThreads(const vtkm::Id&) const override final + { + // TODO: Set the threads in OpenMP + } + + VTKM_CONT void SetNumaRegions(const vtkm::Id&) const override final + { + // TODO: Set the numa regions in OpenMP + } + + VTKM_CONT vtkm::Id GetThreads() const override final + { + // TODO: Get the number of OpenMP threads + return 0; + } + + VTKM_CONT vtkm::Id GetNumaRegions() const override final + { + // TODO: Get the number of OpenMP NumaRegions + return 0; + } +}; +} // namespace vtkm::cont::internal +} // namespace vtkm::cont +} // namespace vtkm + +#endif //vtk_m_cont_openmp_internal_RuntimeDeviceConfigurationOpenMP_h diff --git a/vtkm/cont/serial/DeviceAdapterSerial.h b/vtkm/cont/serial/DeviceAdapterSerial.h index 5b6dbb5c8..d10ff7af5 100644 --- a/vtkm/cont/serial/DeviceAdapterSerial.h +++ b/vtkm/cont/serial/DeviceAdapterSerial.h @@ -14,6 +14,7 @@ // clang-format off #include #include +#include #include #include #ifndef VTKM_NO_DEPRECATED_VIRTUAL diff --git a/vtkm/cont/serial/internal/CMakeLists.txt b/vtkm/cont/serial/internal/CMakeLists.txt index 22c9b7f0e..ed935b464 100644 --- a/vtkm/cont/serial/internal/CMakeLists.txt +++ b/vtkm/cont/serial/internal/CMakeLists.txt @@ -13,6 +13,7 @@ set(headers DeviceAdapterMemoryManagerSerial.h DeviceAdapterRuntimeDetectorSerial.h DeviceAdapterTagSerial.h + RuntimeDeviceConfigurationSerial.h ) if (NOT VTKm_NO_DEPRECATED_VIRTUAL) diff --git a/vtkm/cont/serial/internal/RuntimeDeviceConfigurationSerial.h b/vtkm/cont/serial/internal/RuntimeDeviceConfigurationSerial.h new file mode 100644 index 000000000..d83b652d4 --- /dev/null +++ b/vtkm/cont/serial/internal/RuntimeDeviceConfigurationSerial.h @@ -0,0 +1,38 @@ +//============================================================================ +// 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. +//============================================================================ +#ifndef vtk_m_cont_serial_internal_RuntimeDeviceConfigurationSerial_h +#define vtk_m_cont_serial_internal_RuntimeDeviceConfigurationSerial_h + +#include +#include + +namespace vtkm +{ +namespace cont +{ +namespace internal +{ + +template <> +class RuntimeDeviceConfiguration + : public vtkm::cont::internal::RuntimeDeviceConfigurationBase +{ + VTKM_CONT vtkm::cont::DeviceAdapterId GetDevice() const override final + { + return vtkm::cont::DeviceAdapterTagSerial{}; + } + + VTKM_CONT void Initialize(const RuntimeDeviceConfigurationOptions&) const override final {} +}; +} +} +} + +#endif //vtk_m_cont_serial_internal_RuntimeDeviceConfigurationSerial_h diff --git a/vtkm/cont/tbb/DeviceAdapterTBB.h b/vtkm/cont/tbb/DeviceAdapterTBB.h index 59ad9c7df..18a9e46fd 100644 --- a/vtkm/cont/tbb/DeviceAdapterTBB.h +++ b/vtkm/cont/tbb/DeviceAdapterTBB.h @@ -16,6 +16,7 @@ #ifdef VTKM_ENABLE_TBB #include #include +#include #ifndef VTKM_NO_DEPRECATED_VIRTUAL #include #endif //VTKM_NO_DEPRECATED_VIRTUAL diff --git a/vtkm/cont/tbb/internal/CMakeLists.txt b/vtkm/cont/tbb/internal/CMakeLists.txt index 1283307be..6bbc8b14d 100644 --- a/vtkm/cont/tbb/internal/CMakeLists.txt +++ b/vtkm/cont/tbb/internal/CMakeLists.txt @@ -15,6 +15,7 @@ set(headers DeviceAdapterTagTBB.h FunctorsTBB.h ParallelSortTBB.h + RuntimeDeviceConfigurationTBB.h ) if (NOT VTKm_NO_DEPRECATED_VIRTUAL) diff --git a/vtkm/cont/tbb/internal/RuntimeDeviceConfigurationTBB.h b/vtkm/cont/tbb/internal/RuntimeDeviceConfigurationTBB.h new file mode 100644 index 000000000..c34e764a5 --- /dev/null +++ b/vtkm/cont/tbb/internal/RuntimeDeviceConfigurationTBB.h @@ -0,0 +1,52 @@ +//============================================================================ +// 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. +//============================================================================ +#ifndef vtk_m_cont_tbb_internal_RuntimeDeviceConfigurationTBB_h +#define vtk_m_cont_tbb_internal_RuntimeDeviceConfigurationTBB_h + +#include +#include + +namespace vtkm +{ +namespace cont +{ +namespace internal +{ + +template <> +class RuntimeDeviceConfiguration + : public vtkm::cont::internal::RuntimeDeviceConfigurationBase +{ + VTKM_CONT vtkm::cont::DeviceAdapterId GetDevice() const override final + { + return vtkm::cont::DeviceAdapterTagTBB{}; + } + + VTKM_CONT void Initialize(const RuntimeDeviceConfigurationOptions&) const override final + { + // TODO: vtk-m initialize should set the number of threads + } + + VTKM_CONT virtual void SetThreads(const vtkm::Id&) const override final + { + // TODO: vtk-m set the number of global threads + } + + VTKM_CONT virtual vtkm::Id GetThreads() const override final + { + // TODO: Get number of TBB threads here (essentially just threads supported by architecture) + return 0; + } +}; +} // namespace vktm::cont::internal +} // namespace vtkm::cont +} // namespace vtkm + +#endif //vtk_m_cont_tbb_internal_RuntimeDeviceConfigurationTBB_h diff --git a/vtkm/cont/testing/Testing.h b/vtkm/cont/testing/Testing.h index d51561018..87e94c9a2 100644 --- a/vtkm/cont/testing/Testing.h +++ b/vtkm/cont/testing/Testing.h @@ -73,59 +73,6 @@ enum TestOptionsIndex DEPRECATED_WRITEDIR // base dir for generated regression test images }; -struct TestVtkmArg : public opt::Arg -{ - static opt::ArgStatus Required(const opt::Option& option, bool msg) - { - if (option.arg == nullptr) - { - if (msg) - { - VTKM_LOG_ALWAYS_S(vtkm::cont::LogLevel::Error, - "Missing argument after option '" - << std::string(option.name, static_cast(option.namelen)) - << "'.\n"); - } - return opt::ARG_ILLEGAL; - } - else - { - return opt::ARG_OK; - } - } - - // Method used for guessing whether an option that do not support (perhaps that calling - // program knows about it) has an option attached to it (which should also be ignored). - static opt::ArgStatus Unknown(const opt::Option& option, bool msg) - { - // If we don't have an arg, obviously we don't have an arg. - if (option.arg == nullptr) - { - return opt::ARG_NONE; - } - - // The opt::Arg::Optional method will return that the ARG is OK if and only if - // the argument is attached to the option (e.g. --foo=bar). If that is the case, - // then we definitely want to report that the argument is OK. - if (opt::Arg::Optional(option, msg) == opt::ARG_OK) - { - return opt::ARG_OK; - } - - // Now things get tricky. Maybe the next argument is an option or maybe it is an - // argument for this option. We will guess that if the next argument does not - // look like an option, we will treat it as such. - if (option.arg[0] == '-') - { - return opt::ARG_NONE; - } - else - { - return opt::ARG_OK; - } - } -}; - struct Testing { public: @@ -305,7 +252,7 @@ private: 0, "", "vtkm-data-dir", - TestVtkmArg::Required, + opt::VtkmArg::Required, " --vtkm-data-dir " " \tPath to the " "base data directory in the VTK-m " @@ -314,7 +261,7 @@ private: 0, "", "vtkm-baseline-dir", - TestVtkmArg::Required, + opt::VtkmArg::Required, " --vtkm-baseline-dir " " " "\tPath to the base dir " @@ -324,7 +271,7 @@ private: 0, "", "vtkm-write-dir", - TestVtkmArg::Required, + opt::VtkmArg::Required, " --vtkm-write-dir " " " "\tPath to the write dir " @@ -334,7 +281,7 @@ private: 0, "D", "data-dir", - TestVtkmArg::Required, + opt::VtkmArg::Required, " --data-dir " " " "\tDEPRECATED: use --vtkm-data-dir instead" }); @@ -342,7 +289,7 @@ private: 0, "B", "baseline-dir", - TestVtkmArg::Required, + opt::VtkmArg::Required, " --baseline-dir " " " "\tDEPRECATED: use --vtkm-baseline-dir instead" }); @@ -350,13 +297,13 @@ private: 0, "", "write-dir", - TestVtkmArg::Required, + opt::VtkmArg::Required, " --write-dir " " " "\tDEPRECATED: use --vtkm-write-dir instead" }); // Required to collect unknown arguments when help is off. - usage.push_back({ TEST_UNKNOWN, 0, "", "", TestVtkmArg::Unknown, "" }); + usage.push_back({ TEST_UNKNOWN, 0, "", "", opt::VtkmArg::UnknownOption, "" }); usage.push_back({ 0, 0, 0, 0, 0, 0 });