diff --git a/include/cudaq/Optimizer/Dialect/Quake/QuakeOps.td b/include/cudaq/Optimizer/Dialect/Quake/QuakeOps.td index 15968a2e4b..802be8d2e4 100644 --- a/include/cudaq/Optimizer/Dialect/Quake/QuakeOps.td +++ b/include/cudaq/Optimizer/Dialect/Quake/QuakeOps.td @@ -316,6 +316,8 @@ def quake_InitializeStateOp : QuakeOp<"init_state", [MemoryEffects<[MemAlloc, let assemblyFormat = [{ $targets `,` $state `:` functional-type(operands, results) attr-dict }]; + + let hasVerifier = 1; } def quake_RelaxSizeOp : QuakeOp<"relax_size", [Pure]> { diff --git a/lib/Frontend/nvqpp/ConvertExpr.cpp b/lib/Frontend/nvqpp/ConvertExpr.cpp index b7a0d28ec8..ddc05456c3 100644 --- a/lib/Frontend/nvqpp/ConvertExpr.cpp +++ b/lib/Frontend/nvqpp/ConvertExpr.cpp @@ -2402,6 +2402,10 @@ bool QuakeBridgeVisitor::VisitCXXConstructExpr(clang::CXXConstructExpr *x) { builder.create(loc, size); } else { std::size_t arraySize = arrTy.getSize(); + if (!std::has_single_bit(arraySize)) { + reportClangError(x, mangler, + "state vector must be a power of 2 in length"); + } numQubits = builder.create( loc, std::countr_zero(arraySize), 64); } diff --git a/lib/Optimizer/Dialect/Quake/QuakeOps.cpp b/lib/Optimizer/Dialect/Quake/QuakeOps.cpp index be9a291796..3a939f57af 100644 --- a/lib/Optimizer/Dialect/Quake/QuakeOps.cpp +++ b/lib/Optimizer/Dialect/Quake/QuakeOps.cpp @@ -496,6 +496,19 @@ LogicalResult quake::ExtractRefOp::verify() { return success(); } +//===----------------------------------------------------------------------===// +// InitializeStateOp +//===----------------------------------------------------------------------===// + +LogicalResult quake::InitializeStateOp::verify() { + auto veqTy = cast(getTargets().getType()); + if (veqTy.hasSpecifiedSize()) + if (!std::has_single_bit(veqTy.getSize())) + return emitOpError("initialize state vector must be power of 2, but is " + + std::to_string(veqTy.getSize()) + " instead."); + return success(); +} + //===----------------------------------------------------------------------===// // RelaxSizeOp //===----------------------------------------------------------------------===// diff --git a/runtime/cudaq/builder/kernel_builder.cpp b/runtime/cudaq/builder/kernel_builder.cpp index 3ad6382c55..3cf0cdd3aa 100644 --- a/runtime/cudaq/builder/kernel_builder.cpp +++ b/runtime/cudaq/builder/kernel_builder.cpp @@ -529,9 +529,12 @@ QuakeValue qalloc(ImplicitLocOpBuilder &builder, std::size_t hash, throw std::runtime_error( "Could not create code for setting the state global data."); + if (!std::has_single_bit(size)) + throw std::runtime_error("state vector must be a power of 2 in length"); + // Allocate the qubits Value qubits = builder.create( - quake::VeqType::get(context, std::log2(size))); + quake::VeqType::get(context, std::countr_zero(size))); // Get the pointer to the global auto f64Ty = builder.getF64Type();