MCPcopy Create free account
hub / github.com/NVIDIA/cuda-quantum / __applyControlOrAdjoint

Method __applyControlOrAdjoint

python/cudaq/kernel/kernel_builder.py:673–730  ·  view source on GitHub ↗

Utility method for adding a Quake `ApplyOp` in the case of `cudaq.control` or `cudaq.adjoint`. This function will search recursively for all required function operations and add them to the module.

(self, target, isAdjoint, controls, *args)

Source from the content-addressed store, hash-verified

671 return
672
673 def __applyControlOrAdjoint(self, target, isAdjoint, controls, *args):
674 """
675 Utility method for adding a Quake `ApplyOp` in the case of
676 `cudaq.control` or `cudaq.adjoint`. This function will search
677 recursively for all required function operations and add them to the
678 module.
679 """
680 self.clearCache()
681 with self.insertPoint, self.loc:
682 if isinstance(target, cc.CreateLambdaOp):
683 otherFuncCloned = target
684 otherModule = self.module
685 otherFTy = FunctionType(
686 TypeAttr(target.attributes['function_type']).value).inputs
687 else:
688 otherFuncCloned, otherModule = self.__cloneOrGetFunction(
689 target.name, self.module, target)
690 assert isinstance(otherFuncCloned, func.FuncOp)
691 # Same as __addAllCalledFunctionsRecursively does for
692 # transitively called functions: a sub-kernel merged into this
693 # module is no longer an `entrypoint`.
694 if 'cudaq-entrypoint' in otherFuncCloned.operation.attributes:
695 otherFuncCloned.operation.attributes.__delitem__(
696 'cudaq-entrypoint')
697 self.__addAllCalledFunctionsRecursively(otherFuncCloned,
698 self.module,
699 otherModule)
700 otherFTy = []
701 for a in otherFuncCloned.body.blocks[0].arguments:
702 otherFTy.append(a.type)
703 mlirValues = []
704 for i, v in enumerate(args):
705 argTy = otherFTy[i]
706 if not isinstance(v, QuakeValue):
707 # here we have to map constant Python data to an MLIR Value
708 value = self.__getMLIRValueFromPythonArg(v, argTy)
709 else:
710 value = v.mlirValue
711 inTy = value.type
712
713 if (quake.VeqType.isinstance(inTy) and
714 quake.VeqType.isinstance(argTy)):
715 if quake.VeqType.hasSpecifiedSize(
716 inTy) and not quake.VeqType.hasSpecifiedSize(argTy):
717 value = quake.RelaxSizeOp(argTy, value).result
718
719 mlirValues.append(value)
720 if isAdjoint or len(controls) > 0:
721 quake.ApplyOp([], [],
722 controls,
723 mlirValues,
724 callee=FlatSymbolRefAttr.get(
725 otherFuncCloned.name.value),
726 is_adj=isAdjoint)
727 elif isinstance(otherFuncCloned, cc.CreateLambdaOp):
728 cc.CallCallableOp([], otherFuncCloned, mlirValues)
729 else:
730 func.CallOp(otherFuncCloned, mlirValues)

Callers 3

adjointMethod · 0.95
controlMethod · 0.95
apply_callMethod · 0.95

Calls 8

clearCacheMethod · 0.95
__cloneOrGetFunctionMethod · 0.95
enumerateFunction · 0.85
hasSpecifiedSizeMethod · 0.80
appendMethod · 0.45
getMethod · 0.45

Tested by

no test coverage detected