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

Method visit_ListComp

python/cudaq/kernel/ast_bridge.py:4041–4444  ·  view source on GitHub ↗

This method currently supports lowering simple list comprehensions to the MLIR. By simple, we mean expressions like `[expr(iter) for iter in iterable]` or `myList = [exprThatReturns(iter) for iter in iterable]`, optionally with `if` filter clause.

(self, node)

Source from the content-addressed store, hash-verified

4039 self.emitFatalError(f"unknown function call", node)
4040
4041 def visit_ListComp(self, node):
4042 """This method currently supports lowering simple list comprehensions to
4043 the MLIR.
4044
4045 By simple, we mean expressions like `[expr(iter) for iter in iterable]`
4046 or `myList = [exprThatReturns(iter) for iter in iterable]`, optionally
4047 with `if` filter clause.
4048 """
4049 if len(node.generators) > 1:
4050 self.emitFatalError(
4051 "CUDA-Q only supports single generators for list comprehension.",
4052 node)
4053
4054 if_clauses = node.generators[0].ifs
4055 hasFilter = len(if_clauses) > 0
4056
4057 self.visit(node.generators[0].iter)
4058 iterable = self.popValue()
4059 orig_iterable_type = iterable.type
4060 if cc.StdvecType.isinstance(iterable.type):
4061 iterableSize = cc.StdvecSizeOp(self.getIntegerType(),
4062 iterable).result
4063 iterTy = cc.StdvecType.getElementType(iterable.type)
4064 iterArrPtrTy = cc.PointerType.get(cc.ArrayType.get(iterTy))
4065 iterable = cc.StdvecDataOp(iterArrPtrTy, iterable).result
4066 elif quake.VeqType.isinstance(iterable.type):
4067 iterableSize = quake.VeqSizeOp(self.getIntegerType(),
4068 iterable).result
4069 iterTy = quake.RefType.get()
4070 else:
4071 self.emitFatalError(
4072 "CUDA-Q only supports list comprehension on ranges and arrays",
4073 node)
4074
4075 def process_void_list():
4076 # NOTE: This does not actually create a valid value, and will fail
4077 # if something tries to use the value that this was supposed to
4078 # create later on. Keeping this to keep existing functionality, but
4079 # this is a bit questionable. Aside from no list being produced,
4080 # this should work regardless of what we iterate over or what
4081 # expression we evaluate.
4082 self.emitWarning(
4083 "produced elements in list comprehension contain None - "
4084 "expression will be evaluated but no list is generated", node)
4085 forNode = ast.For()
4086 forNode.iter = node.generators[0].iter
4087 forNode.target = node.generators[0].target
4088 forNode.body = [node.elt]
4089 forNode.orelse = []
4090 forNode.lineno = node.lineno
4091 # This loop could be marked as invariant if we didn't use
4092 # `visit_For`, but that would be premature optimization.
4093 self.visit_For(forNode)
4094
4095 def evalFilter():
4096 cond = None
4097 for if_node in if_clauses:
4098 self.visit(if_node)

Callers

nothing calls this directly

Calls 11

emitFatalErrorMethod · 0.95
visitMethod · 0.95
popValueMethod · 0.95
getIntegerTypeMethod · 0.95
pushValueMethod · 0.95
getVeqTypeMethod · 0.95
getConstantIntMethod · 0.95
createForLoopMethod · 0.95
getElementTypeMethod · 0.80
getMethod · 0.45

Tested by

no test coverage detected