Skip to content

Commit

Permalink
Fix #17: don't generate loops in the kernel_builder for measurements (#…
Browse files Browse the repository at this point in the history
…1910)

* Fix #17: don't generate loops in the kernel_builder for measurements

This simplifies kernel_builder and leverages that Quake already knows
what to do with veq types.

Fix reset while we are here. There is no need to test the types of these
arguments. The verifier already does that.

Fix std::string arguments to not make copies of the string at each call
site.

* Back out change to reset. Appears to choke in codegen. Will be a
separate PR.

* Add expand measurements pass to IQM pipeline.

* Add unrolling as well.
  • Loading branch information
schweitzpgi authored Jul 13, 2024
1 parent 77b1430 commit 0f7a56b
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 44 deletions.
1 change: 1 addition & 0 deletions include/cudaq/Optimizer/CodeGen/Pipelines.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,5 @@ void addLowerToCCPipeline(mlir::OpPassManager &pm);

void addPipelineTranslateToOpenQASM(mlir::PassManager &pm);
void addPipelineTranslateToIQMJson(mlir::PassManager &pm);

} // namespace cudaq::opt
4 changes: 4 additions & 0 deletions lib/Optimizer/CodeGen/Pipelines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ void cudaq::opt::addPipelineTranslateToOpenQASM(PassManager &pm) {

void cudaq::opt::addPipelineTranslateToIQMJson(PassManager &pm) {
pm.addNestedPass<func::FuncOp>(createUnwindLoweringPass());
pm.addPass(createExpandMeasurementsPass());
LoopUnrollOptions luo;
pm.addPass(createLoopUnroll(luo));
pm.addPass(createCanonicalizerPass());
pm.addNestedPass<func::FuncOp>(createLowerToCFGPass());
pm.addNestedPass<func::FuncOp>(createQuakeAddDeallocs());
pm.addNestedPass<func::FuncOp>(createCombineQuantumAllocations());
Expand Down
55 changes: 14 additions & 41 deletions runtime/cudaq/builder/kernel_builder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -755,66 +755,39 @@ void u3(ImplicitLocOpBuilder &builder, std::vector<QuakeValue> &parameters,

template <typename QuakeMeasureOp>
QuakeValue applyMeasure(ImplicitLocOpBuilder &builder, Value value,
std::string regName) {
const std::string &regName) {
auto type = value.getType();
if (!type.isa<quake::RefType, quake::VeqType>())
throw std::runtime_error("Invalid parameter passed to mz.");

cudaq::info("kernel_builder apply measurement");

auto i1Ty = builder.getI1Type();
auto strAttr = builder.getStringAttr(regName);
auto measTy = quake::MeasureType::get(builder.getContext());
if (type.isa<quake::RefType>()) {
Value measureResult =
builder.template create<QuakeMeasureOp>(measTy, value, strAttr)
.getMeasOut();
Value bits = builder.create<quake::DiscriminateOp>(i1Ty, measureResult);
return QuakeValue(builder, bits);
Type resTy = builder.getI1Type();
Type measTy = quake::MeasureType::get(builder.getContext());
if (!type.isa<quake::RefType>()) {
resTy = cc::StdvecType::get(resTy);
measTy = cc::StdvecType::get(measTy);
}

// This must be a veq.
auto i64Ty = builder.getIntegerType(64);
Value vecSize = builder.template create<quake::VeqSizeOp>(i64Ty, value);
Value size = builder.template create<cudaq::cc::CastOp>(
i64Ty, vecSize, cudaq::cc::CastOpMode::Unsigned);
auto buff = builder.template create<cc::AllocaOp>(i1Ty, vecSize);
cudaq::opt::factory::createInvariantLoop(
builder, builder.getLoc(), size,
[&](OpBuilder &nestedBuilder, Location nestedLoc, Region &,
Block &block) {
Value iv = block.getArgument(0);
OpBuilder::InsertionGuard guard(nestedBuilder);
Value qv =
nestedBuilder.create<quake::ExtractRefOp>(nestedLoc, value, iv);
Value meas =
nestedBuilder.create<QuakeMeasureOp>(nestedLoc, measTy, qv, strAttr)
.getMeasOut();
Value bit =
nestedBuilder.create<quake::DiscriminateOp>(nestedLoc, i1Ty, meas);

auto i1PtrTy = cudaq::cc::PointerType::get(i1Ty);
auto addr = nestedBuilder.create<cc::ComputePtrOp>(
nestedLoc, i1PtrTy, buff, ValueRange{iv});
nestedBuilder.create<cc::StoreOp>(nestedLoc, bit, addr);
});
Value ret = builder.template create<cc::StdvecInitOp>(
cc::StdvecType::get(builder.getContext(), i1Ty), buff, vecSize);
return QuakeValue(builder, ret);
Value measureResult =
builder.template create<QuakeMeasureOp>(measTy, value, strAttr)
.getMeasOut();
Value bits = builder.create<quake::DiscriminateOp>(resTy, measureResult);
return QuakeValue(builder, bits);
}

QuakeValue mx(ImplicitLocOpBuilder &builder, QuakeValue &qubitOrQvec,
std::string regName) {
const std::string &regName) {
return applyMeasure<quake::MxOp>(builder, qubitOrQvec.getValue(), regName);
}

QuakeValue my(ImplicitLocOpBuilder &builder, QuakeValue &qubitOrQvec,
std::string regName) {
const std::string &regName) {
return applyMeasure<quake::MyOp>(builder, qubitOrQvec.getValue(), regName);
}

QuakeValue mz(ImplicitLocOpBuilder &builder, QuakeValue &qubitOrQvec,
std::string regName) {
const std::string &regName) {
return applyMeasure<quake::MzOp>(builder, qubitOrQvec.getValue(), regName);
}

Expand Down
5 changes: 2 additions & 3 deletions runtime/cudaq/builder/kernel_builder.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ CUDAQ_DETAILS_ONEPARAM_QIS_DECLARATION(r1)

#define CUDAQ_DETAILS_MEASURE_DECLARATION(NAME) \
QuakeValue NAME(mlir::ImplicitLocOpBuilder &builder, QuakeValue &target, \
std::string regName = "");
const std::string &regName = std::string{});

CUDAQ_DETAILS_MEASURE_DECLARATION(mx)
CUDAQ_DETAILS_MEASURE_DECLARATION(my)
Expand Down Expand Up @@ -646,9 +646,8 @@ class kernel_builder : public details::kernel_builder_base {
std::string>>> \
auto NAME(QubitValues... args) { \
std::vector<QuakeValue> values{args...}, results; \
for (auto &value : values) { \
for (auto &value : values) \
results.emplace_back(NAME(value)); \
} \
return results; \
}

Expand Down

0 comments on commit 0f7a56b

Please sign in to comment.