Commit 8895b758 authored by Mccaskey, Alex's avatar Mccaskey, Alex
Browse files

Adding option handler lambda arg to CompilerRegistry and AcceleratorRegistry,...

Adding option handler lambda arg to CompilerRegistry and AcceleratorRegistry, implemented list embedding algorithms and list solvers for DW Compiler and DW Accelerator
parent d3115a09
......@@ -152,7 +152,8 @@ public:
value<std::string>(), "The name of the solver to run on.")
("dwave-num-reads", value<std::string>(), "The number of executions on the chip for the given problem.")
("dwave-anneal-time", value<std::string>(), "The time to evolve the chip - an integer in microseconds.")
("dwave-thermalization", value<std::string>(), "The thermalization...");
("dwave-thermalization", value<std::string>(), "The thermalization...")
("dwave-list-solvers", "List the available solvers at the Qubist URL.");
return desc;
}
......@@ -162,7 +163,104 @@ public:
static void registerAccelerator() {
DWAccelerator acc;
xacc::RegisterAccelerator<xacc::quantum::DWAccelerator> DWTEMP(
"dwave", acc.getOptions());
"dwave", acc.getOptions(),
[](variables_map& args) -> bool {
if(args.count("dwave-list-solvers")) {
std::string tempApiKey, tempUrl;
auto findApiKeyInFile = [](std::string& apiKey, std::string& url,
boost::filesystem::path &p) {
std::ifstream stream(p.string());
std::string contents(
(std::istreambuf_iterator<char>(stream)),
std::istreambuf_iterator<char>());
std::vector<std::string> lines;
boost::split(lines, contents, boost::is_any_of("\n"));
for (auto l : lines) {
if (boost::contains(l, "key")) {
std::vector<std::string> split;
boost::split(split, l, boost::is_any_of(":"));
auto key = split[1];
boost::trim(key);
apiKey = key;
} else if (boost::contains(l, "url")) {
std::vector<std::string> split;
boost::split(split, l, boost::is_any_of(":"));
auto key = split[1] + ":" + split[2];
boost::trim(key);
url = key;
}
}
};
auto searchAPIKey = [&](std::string& key, std::string& url) {
// Search for the API Key in $HOME/.dwave_config,
// $DWAVE_CONFIG, or in the command line argument --dwave-api-key
auto options = RuntimeOptions::instance();
boost::filesystem::path dwaveConfig(
std::string(getenv("HOME")) + "/.dwave_config");
if (boost::filesystem::exists(dwaveConfig)) {
findApiKeyInFile(key, url, dwaveConfig);
} else if (const char * nonStandardPath = getenv("DWAVE_CONFIG")) {
boost::filesystem::path nonStandardDwaveConfig(
nonStandardPath);
findApiKeyInFile(key, url, nonStandardDwaveConfig);
} else {
// Ensure that the user has provided an api-key
if (!options->exists("dwave-api-key")) {
XACCError("Cannot list D-Wave solvers without API Key.");
}
// Set the API Key
key = (*options)["dwave-api-key"];
if (options->exists("dwave-api-url")) {
url = (*options)["dwave-api-url"];
}
}
// If its still empty, then we have a problem
if (key.empty()) {
XACCError("Error. The API Key is empty. Please place it "
"in your $HOME/.dwave_config file, $DWAVE_CONFIG env var, "
"or provide --dwave-api-key argument.");
}
};
searchAPIKey(tempApiKey, tempUrl);
boost::replace_all(tempUrl, "https://", "");
boost::replace_all(tempUrl, "/sapi", "");
std::map<std::string, std::string> headers;
// Set up the extra HTTP headers we are going to need
headers.insert(std::make_pair("X-Auth-Token", tempApiKey));
headers.insert(std::make_pair("Content-type", "application/x-www-form-urlencoded"));
headers.insert(std::make_pair("Accept", "*/*"));
// Get the Remote URL Solver data...
auto getSolverClient = fire::util::AsioNetworkingTool<SimpleWeb::HTTPS>(tempUrl, false);
auto r = getSolverClient.get("/sapi/solvers/remote", headers);
std::stringstream ss;
ss << r.content.rdbuf();
auto message = ss.str();
Document document;
document.Parse(message.c_str());
if (document.IsArray()) {
for (auto i = 0; i < document.Size(); i++) {
XACCInfo("Available D-Wave Solver: " + std::string(document[i]["id"].GetString()));
}
}
return true;
}
return false;
});
}
/**
......
......@@ -101,7 +101,8 @@ public:
"Provide the name of the "
"ParameterSetter to map logical parameters to physical parameters.")
("dwave-load-embedding", value<std::string>(), "Use the embedding in the given file.")
("dwave-persist-embedding", value<std::string>(), "Persist the computed embedding to the given file name.");
("dwave-persist-embedding", value<std::string>(), "Persist the computed embedding to the given file name.")
("dwave-list-embedding-algorithms", "List all available embedding algorithms.");
return desc;
}
......@@ -111,7 +112,17 @@ public:
static void registerCompiler() {
DWQMICompiler c;
xacc::RegisterCompiler<xacc::quantum::DWQMICompiler> DWQMITEMP(
"dwave-qmi", c.getOptions());
"dwave-qmi", c.getOptions(),
[](variables_map& args) -> bool {
if(args.count("dwave-list-embedding-algorithms")) {
auto ids = EmbeddingAlgorithmRegistry::instance()->getRegisteredIds();
for (auto i : ids) {
XACCInfo("Registered Embedding Algorithm: " + i);
}
return true;
}
return false;
});
}
/**
......
......@@ -268,6 +268,17 @@ public:
});
AcceleratorRegistry::instance()->add(name, f, options);
}
RegisterAccelerator(const std::string& name,
std::shared_ptr<options_description> options,
std::function<bool(variables_map& args)> optionHandler) {
AcceleratorRegistry::CreatorFunctionPtr f = std::make_shared<
AcceleratorRegistry::CreatorFunction>([]() {
return std::make_shared<T>();
});
AcceleratorRegistry::instance()->add(name, f, options, optionHandler);
}
};
#define RegisterAccelerator(TYPE) BOOST_DLL_ALIAS(TYPE::registerAccelerator, registerAccelerator)
......
......@@ -153,6 +153,16 @@ public:
});
CompilerRegistry::instance()->add(name, f, options);
}
RegisterCompiler(const std::string& name,
std::shared_ptr<options_description> options,
std::function<bool(variables_map& args)> optionHandler) {
CompilerRegistry::CreatorFunctionPtr f = std::make_shared<
CompilerRegistry::CreatorFunction>([]() {
return std::make_shared<T>();
});
CompilerRegistry::instance()->add(name, f, options, optionHandler);
}
};
#define RegisterCompiler(TYPE) BOOST_DLL_ALIAS(TYPE::registerCompiler, registerCompiler)
......
......@@ -218,6 +218,16 @@ public:
exit(0);
}
auto exitRequested1 = xacc::CompilerRegistry::instance()->handleOptions(clArgs);
auto exitRequested2 = xacc::AcceleratorRegistry::instance()->handleOptions(clArgs);
if (exitRequested1 || exitRequested2) {
XACCInfo(
"\n[xacc] XACC Finalizing\n[xacc::compiler] Cleaning up Compiler Registry."
"\n[xacc::accelerator] Cleaning up Accelerator Registry.");
exit(0);
}
// Add all other string options to the global runtime option
for (auto it = clArgs.begin(); it != clArgs.end();
++it) {
......
......@@ -112,6 +112,28 @@ public:
}
}
bool add(const std::string& id, CreatorFunctionPtr f,
std::shared_ptr<options_description> options,
std::function<bool(variables_map&)> optionsHandler) {
if (registry.find(id) != registry.end()) {
XACCInfo(
id
+ " already exists in Registry. Ignoring and retaining previous Registry entry");
return true;
}
if (RuntimeOptions::instance()->exists("verbose-registry"))
XACCInfo("Registry adding " + id);
bool s = registry.emplace(std::make_pair(id, f)).second;
bool s2 =
registryOptions.insert(std::make_pair(id, std::move(options))).second;
bool s3 = registryOptionHandlers.insert(std::make_pair(id, std::move(optionsHandler))).second;
if (!s || !s2) {
XACCError("Could not add " + id + " to the Registry.");
} else {
return true;
}
}
/**
* Create an instance of T by using the creation
* function found at the given key string id.
......@@ -158,6 +180,15 @@ public:
return values;
}
bool handleOptions(variables_map& map) {
for (auto& kv : registryOptionHandlers) {
if (kv.second(map)) {
return true;
}
}
return false;
}
/**
* Return the number of creation functions
* this registry contains.
......@@ -177,6 +208,9 @@ protected:
std::map<std::string, CreatorFunctionPtr> registry;
std::map<std::string, std::shared_ptr<options_description>> registryOptions;
std::map<std::string, std::function<bool(variables_map&)>> registryOptionHandlers;
};
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment