Maestro 0.3.1
Unified interface for quantum circuit simulation
Loading...
Searching...
No Matches
Simulators/Configuration.h
Go to the documentation of this file.
1
9
10#pragma once
11
12#ifndef _SIMULATOR_CONFIGURATION_H_
13#define _SIMULATOR_CONFIGURATION_H_
14
15#include <stdexcept>
16#include <string>
17#include <unordered_map>
18
19
20#include "State.h"
21#include <charconv>
22#include <stdexcept>
23
24namespace Simulators {
25
26
28 public:
34 Configuration() = default;
35
41 virtual ~Configuration() = default;
42
48 Configuration(const Configuration&) = default;
49
56
63
70
79 static int ParseGpuDevice(const std::string& value) {
80 int device = -1;
81 const auto result = std::from_chars(value.data(), value.data() + value.size(), device);
82 if (result.ec != std::errc() || result.ptr != value.data() + value.size() || device < 0)
83 throw std::invalid_argument("gpu_device must be a nonnegative integer");
84 return device;
85 }
86
87 // Keep mutually exclusive GPU SVD flags consistent before they are replayed
88 // from an unordered map into a new simulator (including network clones/jobs).
89 static std::string GpuSvdSettingGroup(const std::string& key) {
90 for (const char* group : {"matrix_product_state_use_gesvd",
91 "matrix_product_operator_use_gesvd",
92 "tensor_network_use_gesvd"}) {
93 const size_t length = std::char_traits<char>::length(group);
94 if (key == group) return group;
95 if (key.size() == length + 1 && key.compare(0, length, group) == 0 &&
96 (key.back() == 'j' || key.back() == 'p' || key.back() == 'r'))
97 return group;
98 }
99 return {};
100 }
101
102 static bool ParseGpuSvdFlag(const std::string& value) {
103 if (value == "true" || value == "1") return true;
104 if (value == "false" || value == "0") return false;
105 throw std::invalid_argument("GPU SVD flags must be true, false, 1 or 0");
106 }
107
108 void SetConfiguration(const std::string& key, const std::string& value) {
109 if (key == "gpu_device") ParseGpuDevice(value);
110 const auto svdGroup = GpuSvdSettingGroup(key);
111 if (!svdGroup.empty()) {
112 const bool enabled = ParseGpuSvdFlag(value);
113 configMap[key] = enabled ? "true" : "false";
114 if (enabled) {
115 for (const char* algorithm : {"", "j", "p", "r"}) {
116 const auto otherKey = svdGroup + algorithm;
117 const auto other = configMap.find(otherKey);
118 // Do not introduce unused optional settings on older plugins, or
119 // invalidate iterators while an existing map is being replayed.
120 if (otherKey != key && other != configMap.end()) other->second = "false";
121 }
122 }
123 return;
124 }
125 if ((key == "matrix_product_state_truncation_mode" ||
126 key == "matrix_product_operator_truncation_mode") &&
127 value != "relative_max" && value != "discarded_weight")
128 throw std::invalid_argument(
129 "Invalid truncation mode: expected relative_max or "
130 "discarded_weight");
131
132 // specially handled, ignore it
133 if (IgnoredSetting(key)) return;
134 configMap[key] = value;
135 }
136
137 void SetConfiguration(const std::string& key, long long int value) {
138 // specially handled, ignore it
139 if (IgnoredSetting(key)) return;
140 SetConfiguration(key, std::to_string(value));
141 }
142
143 void SetConfiguration(const std::string& key, double value) {
144 // specially handled, ignore it
145 if (IgnoredSetting(key)) return;
146 SetConfiguration(key, std::to_string(value));
147 }
148
157 bool IsSet(const std::string& key) const {
158 return configMap.find(key) != configMap.end();
159 }
160
169 std::string GetConfiguration(const std::string& key) const {
170 auto it = configMap.find(key);
171 if (it != configMap.end()) {
172 return it->second;
173 }
174 return "";
175 }
176
177 long long int GetConfigurationAsInt(const std::string& key) const {
178 auto it = configMap.find(key);
179 if (it != configMap.end()) {
180 return std::stoll(it->second);
181 }
182 return 0;
183 }
184
185 // For size_t-valued settings: the signed and double getters cannot represent
186 // the whole range, and a value near SIZE_MAX misconverts through double.
187 unsigned long long int GetConfigurationAsUnsigned(
188 const std::string& key) const {
189 auto it = configMap.find(key);
190 if (it != configMap.end()) {
191 return std::stoull(it->second);
192 }
193 return 0;
194 }
195
196 double GetConfigurationAsDouble(const std::string& key) const {
197 auto it = configMap.find(key);
198 if (it != configMap.end()) {
199 return std::stod(it->second);
200 }
201 return 0.0;
202 }
203
204 static bool CanBeAppliedOnInitializedSimulator(const std::string& key) {
205 if (key == "gpu_device" || key == "method" || key == "use_double_precision" ||
206 key == "precision" ||
207 key == "max_parallel_threads" || key == "parallel_state_update" ||
208 key == "statevector_parallel_threshold")
209 return false;
210
211 return true;
212 }
213
214 static bool IgnoredSetting(const std::string& key) {
215 if (key == "max_simulators" || key == "method")
216 return true;
217
218 return false;
219 }
220
221 void ApplyConfigurationToSimulator(const std::shared_ptr<Simulators::IState>& simulator) const {
222 for (const auto& [key, value] : configMap)
223 simulator->Configure(key.c_str(), value.c_str());
224 }
225
226 void ApplyConfigurationFromSimulator(const std::shared_ptr<Simulators::IState>& simulator) {
227 if (!simulator) return;
228 ApplyConfigurationFromMap(simulator->GetConfigMap());
229 }
230
231 void ApplyConfigurationFromMap(const std::unordered_map<std::string, std::string>& config) {
232 for (const auto& [key, value] : config) SetConfiguration(key, value);
233 }
234
235 const std::unordered_map<std::string, std::string>& GetConfigMap() const {
236 return configMap;
237 }
238
239 bool WasApplied(const std::string& key, const std::string& value) const {
240 auto it = configMap.find(key);
241 if (it != configMap.end())
242 return it->second == value;
243
244 return false;
245 }
246
247 private:
248 std::unordered_map<std::string, std::string>
249 configMap;
250};
251
252}
253
254#endif
255
static std::string GpuSvdSettingGroup(const std::string &key)
bool IsSet(const std::string &key) const
Check if a configuration value is set.
static int ParseGpuDevice(const std::string &value)
Set a configuration value.
Configuration(const Configuration &)=default
The copy constructor.
Configuration & operator=(const Configuration &)=default
The copy assignment operator.
static bool CanBeAppliedOnInitializedSimulator(const std::string &key)
bool WasApplied(const std::string &key, const std::string &value) const
static bool ParseGpuSvdFlag(const std::string &value)
const std::unordered_map< std::string, std::string > & GetConfigMap() const
void ApplyConfigurationFromSimulator(const std::shared_ptr< Simulators::IState > &simulator)
void ApplyConfigurationFromMap(const std::unordered_map< std::string, std::string > &config)
void SetConfiguration(const std::string &key, double value)
double GetConfigurationAsDouble(const std::string &key) const
void SetConfiguration(const std::string &key, const std::string &value)
Configuration(Configuration &&)=default
The move constructor.
void ApplyConfigurationToSimulator(const std::shared_ptr< Simulators::IState > &simulator) const
unsigned long long int GetConfigurationAsUnsigned(const std::string &key) const
long long int GetConfigurationAsInt(const std::string &key) const
static bool IgnoredSetting(const std::string &key)
Configuration & operator=(Configuration &&)=default
The move assignment operator.
Configuration()=default
The constructor.
virtual ~Configuration()=default
The destructor.
void SetConfiguration(const std::string &key, long long int value)
std::string GetConfiguration(const std::string &key) const
Get a configuration value.