qcor.cpp 6.94 KB
Newer Older
Mccaskey, Alex's avatar
Mccaskey, Alex committed
1
#include "qcor.hpp"
2
#include "/home/project/xacc/xacc/XACC.hpp"
3
#include "qpu_handler.hpp"
Mccaskey, Alex's avatar
Mccaskey, Alex committed
4

5
#include "AcceleratorBuffer.hpp"
Mccaskey, Alex's avatar
Mccaskey, Alex committed
6
7
#include "IRProvider.hpp"
#include "XACC.hpp"
8
9
10
#include "xacc_service.hpp"

#include "PauliOperator.hpp"
11
#include "FermionOperator.hpp"
12

13
#include <regex>
Mccaskey, Alex's avatar
Mccaskey, Alex committed
14
15
16
17

using namespace xacc;

namespace qcor {
18
std::map<std::string, InstructionParameter> runtimeMap = {};
Mccaskey, Alex's avatar
Mccaskey, Alex committed
19

20
21
22
23
24
25
void Initialize(int argc, char **argv) {
  std::vector<const char *> tmp(argv, argv + argc);
  std::vector<std::string> newargv;
  for (auto &t : tmp)
    newargv.push_back(std::string(t));
  Initialize(newargv);
26
27
}
void Initialize(std::vector<std::string> argv) {
28
29
30
  argv.push_back("--logger-name");
  argv.push_back("qcor");
  xacc::Initialize(argv);
31
32
}

33
34
35
36
const std::string persistCompiledCircuit(std::shared_ptr<Function> function,
                                         std::shared_ptr<Accelerator> acc) {
  srand(time(NULL));
  std::function<char()> randChar = []() -> char {
37
38
39
40
41
42
43
44
45
46
47
48
49
    const char charset[] = "0123456789"
                           "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                           "abcdefghijklmnopqrstuvwxyz";
    const size_t max_index = (sizeof(charset) - 1);
    return charset[rand() % max_index];
  };

  auto generateRandomString = [&](const int length = 10) -> const std::string {
    std::string str(length, 0);
    std::generate_n(str.begin(), length, randChar);
    return str;
  };

50
51
52
53
54
55
56
57
58
  std::string file_name;
  if (xacc::optionExists("qcor-compiled-filename")) {
    file_name = xacc::getOption("qcor-compiled-filename");
  } else {

    file_name = generateRandomString();
    // std::cout << "Generating random string " << file_name << "\n";
  }

59
60
61
62
63
  std::stringstream ss;
  function->persist(ss);
  auto persistedFunction = ss.str();
    //   xacc::getCompiler("xacc-py")->translate("", function);
//   persistedFunction = persistedFunction.substr(7, persistedFunction.length());
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
  xacc::appendCache(file_name, "compiled",
                    InstructionParameter(persistedFunction), ".qcor_cache");

  if (acc) {
    xacc::appendCache(file_name, "accelerator",
                      InstructionParameter(acc->name()), ".qcor_cache");
  } else {
    xacc::appendCache(file_name, "accelerator",
                      InstructionParameter("default-sim"), ".qcor_cache");
  }

  if (function->hasIRGenerators()) {
    xacc::appendCache(file_name, "requires-jit", InstructionParameter("true"),
                      ".qcor_cache");
  } else {
    xacc::appendCache(file_name, "requires-jit", InstructionParameter("false"),
                      ".qcor_cache");
  }

83
  return file_name;
Mccaskey, Alex's avatar
Mccaskey, Alex committed
84
85
}

86
std::shared_ptr<Function> loadCompiledCircuit(const std::string &fileName) {
87
//   std::cout << "Loading Circuit " << fileName << "\n";
88
89
90
91
  auto cache = xacc::getCache(fileName, ".qcor_cache");
  if (!cache.count("compiled")) {
    xacc::error("Invalid quantum compilation cache.");
  }
92

93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
  std::shared_ptr<Accelerator> targetAccelerator;
  if (cache["accelerator"] == "default-sim") {
    // First, if this is compiled for simulation,
    // let users set the simulator at the command line
    // if they didnt, check for tnqvm, then local-ibm
    if (xacc::optionExists("accelerator")) {
      targetAccelerator = xacc::getAccelerator();
    } else if (xacc::hasAccelerator("tnqvm")) {
      targetAccelerator = xacc::getAccelerator("tnqvm");
    } else if (xacc::hasAccelerator("local-ibm")) {
      targetAccelerator = xacc::getAccelerator("local-ibm");
    }
  } else {
    auto accStr = cache["accelerator"].as<std::string>();
    if ((accStr == "tnqvm" || accStr == "local-ibm") &&
        xacc::optionExists("accelerator")) {
      targetAccelerator = xacc::getAccelerator();
    } else {
      targetAccelerator =
          xacc::getAccelerator(cache["accelerator"].as<std::string>());
    }
  }

  // If for some reason we still dont have an
  // accelerator, force them to specify at command line
  if (!targetAccelerator) {
    targetAccelerator = xacc::getAccelerator();
  }

  xacc::setAccelerator(targetAccelerator->name());

124
  auto compiled = cache["compiled"].as<std::string>();
125
126
127
  auto loaded = xacc::getService<IRProvider>("gate")->createFunction("loaded", {});
  std::istringstream iss(compiled);
  loaded->load(iss);
128

129
//   std::cout << "Lodaded: " << loaded->toString() << "\n";
130
131
132
  if (cache["requires-jit"].as<std::string>() == "true") {
    auto runtimeMap = getRuntimeMap();

133
134
135
    // for (auto& kv : runtimeMap) {
        // std::cout << "Runtime: " << kv.first << ", " << kv.second.toString() << "\n";
    // }
136
137
138
139
140
    loaded->expandIRGenerators(runtimeMap);

    // Kick off quantum compilation
    auto qcor = xacc::getCompiler("qcor");
    loaded = qcor->compile(loaded, targetAccelerator);
141
    // std::cout << "NPARAMS: " << loaded->nParameters() << "\n";
142
143
  }

144
//   std::cout<< "Loaded IR:\n" << loaded->toString() <<"\n";
145
  return loaded;
Mccaskey, Alex's avatar
Mccaskey, Alex committed
146
147
}

148
void storeRuntimeVariable(const std::string name,
149
150
                          InstructionParameter param) {
//   std::cout << "Storing Runtime Variable " << name << ", " << param.toString() << "\n";
151
152
153
154
155
156
157
158
159
  runtimeMap.insert({name, param});
}

std::map<std::string, InstructionParameter> getRuntimeMap() {
  return runtimeMap;
}

std::future<std::shared_ptr<AcceleratorBuffer>>
submit(HandlerLambda &&totalJob) {
Mccaskey, Alex's avatar
Mccaskey, Alex committed
160
161
  // Create the QPU Handler to pass to the given
  // Handler HandlerLambda
162
163
  return std::async(std::launch::async, [=]() { // bug must be by value...
    qpu_handler handler;
Mccaskey, Alex's avatar
Mccaskey, Alex committed
164
    totalJob(handler);
165
    return handler.getResults();
Mccaskey, Alex's avatar
Mccaskey, Alex committed
166
167
168
  });
}

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
std::shared_ptr<Optimizer> getOptimizer(const std::string &name) {
  return xacc::getService<qcor::Optimizer>(name);
}
std::shared_ptr<Optimizer>
getOptimizer(const std::string &name,
             std::map<std::string, InstructionParameter> &&options) {
  auto opt = getOptimizer(name);
  opt->setOptions(options);
  return opt;
}

std::shared_ptr<Observable> getObservable(const std::string &type,
                                          const std::string &representation) {
  using namespace xacc::quantum;
  if (type == "pauli") {
    return representation.empty()
               ? std::make_shared<PauliOperator>()
               : std::make_shared<PauliOperator>(representation);
187
188
189
190
191
  } else if (type == "fermion") {
     return representation.empty()
               ? std::make_shared<FermionOperator>()
               : std::make_shared<FermionOperator>(representation);
  }else {
192
193
194
195
196
197
198
199
200
201
202
203
    xacc::error("Invalid observable type");
    return std::make_shared<PauliOperator>();
  }
}

std::shared_ptr<Observable> getObservable() {
  return getObservable("pauli", "");
}
std::shared_ptr<Observable> getObservable(const std::string &representation) {
  return getObservable("pauli", representation);
}

204
205
206
207
208
std::shared_ptr<Observable> getObservable(const std::string &type, std::map<std::string, InstructionParameter> &&options) {
    auto observable = xacc::getService<Observable>(type);
    observable->fromOptions(options);
    return observable;
}
209
210
std::shared_ptr<algorithm::Algorithm> getAlgorithm(const std::string name) {
  return xacc::getService<qcor::algorithm::Algorithm>(name);
211
212
}

Mccaskey, Alex's avatar
Mccaskey, Alex committed
213
} // namespace qcor