"""Abstractions for constructing QEC architectures."""importjsonfromcollections.abcimportMappingfromdataclassesimportdataclassfromtypingimportAny,Protocolfromguppylang.defsimportGuppyFunctionDefinitionfromhugrimportHugrfromhugr.metadataimportMetadatafromhugr.opsimportModulefromhugr.packageimportPackagefromhugr.passes.composableimportComposablePassfromtket.passesimportNormalizefrom._compileimportLogicalCompiler,ReplacementCompiler,UncompilableErrorfrom._implement_opsimport(ImplementOps,ImplementOpsSpec,OpReplacements,TyReplacements,implement_ops,)__all__=["EncodeSpec","EncoderParams","ImplementOps","ImplementOpsSpec","LogicalCompiler","OpReplacements","ReplacementCompiler","TyReplacements","UncompilableError","annotate_encoding","encode","implement_ops",]
[docs]@dataclass(frozen=True,kw_only=True)classEncodeSpec:"""A QEC-code-specific collection of passes that together fully encode a computation."""compile:LogicalCompiler|None=None"""Pass to lower the computation to a logical level."""logical_passes:list[ComposablePass]|None=None"""Additional passes to run on the logical HUGR."""implement_ops:ImplementOps|None=None"""Lowers the logical computation to a physical level."""
[docs]defencode(hugr:Package|GuppyFunctionDefinition[[],None],spec:EncodeSpec,*,passes:list[ComposablePass]|None=None,)->Package:""" Encodes the given package (or Guppy function, directly compiled to a package for convenience) by applying four stages: 1. running the given computational passes; 2. lowering the operations in the package to logical operations and potentially performing static optimizations (e.g. resolving some qubit address assignments statically); 3. running additional logical passes (e.g. inserting additional QEC cycles); and 4. implementing the logical operations with physical gates. The returned runnable package is guaranteed to be semantically equivalent to the given one. :param hugr: The package to encode (or Guppy function for convenience). :param spec: See ``EncoderSpec``. :param passes: Computational passes to run on the given package. Defaults to one run of ``Normalize``. :return: The encoded runnable package. """ifisinstance(hugr,GuppyFunctionDefinition):hugr=hugr.compile_function()assertlen(hugr.modules)==1,"Given package contains more than one module"assertnotisinstance(hugr.modules[0].entrypoint_op(),Module),("Cannot process module-rooted HUGRs")# 1. Passes with computational -> computationalfortket_passinpassesor[Normalize()]:tket_pass(hugr.modules[0],inplace=True)# 2. Lower computational -> logicalifspec.compileisnotNone:hugr=spec.compile(hugr)# 3. Passes with logical -> logicalfortket_passinspec.logical_passesor[]:tket_pass(hugr.modules[0],inplace=True)# 4. Lower logical -> physicalifspec.implement_opsisnotNone:hugr=spec.implement_ops(hugr,as_bytes=False)returnhugr
[docs]defencoding(self)->str:"""The encoding to annotate on a program."""
[docs]defparams(self)->Mapping[str,Any]:"""The parameters to annotate on a program. Implementations should return values that support serialization to JSON."""
class_MetadataEncoding(Metadata[Mapping[str,Any]]):"""Metadata key for annotating parameters with which to encode a program."""KEY="guppyft.encoding"
[docs]defannotate_encoding(hugr:Package|Hugr[Any],params:EncoderParams)->None:try:json.dumps(params.params(),check_circular=True)exceptTypeErrorase:raiseValueError("Could not serialize parameters")fromeformoduleinhugr.modulesifisinstance(hugr,Package)else[hugr]:module[module.module_root].metadata[_MetadataEncoding]={"encoding":params.encoding(),"params":params.params(),}