Skip to content

Commit

Permalink
refactor: hoist extern definitions to program
Browse files Browse the repository at this point in the history
  • Loading branch information
erichulburd committed Sep 20, 2024
1 parent afa979d commit 957b470
Show file tree
Hide file tree
Showing 20 changed files with 994 additions and 1,342 deletions.
6 changes: 3 additions & 3 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

146 changes: 18 additions & 128 deletions quil-py/quil/instructions/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,6 @@ class Instruction:
Pragma,
Pulse,
RawCapture,
ReservedPragma,
Reset,
SetFrequency,
SetPhase,
Expand Down Expand Up @@ -155,7 +154,6 @@ class Instruction:
Pragma,
Pulse,
RawCapture,
ReservedPragma,
Reset,
SetFrequency,
SetPhase,
Expand Down Expand Up @@ -198,7 +196,6 @@ class Instruction:
def is_pragma(self) -> bool: ...
def is_pulse(self) -> bool: ...
def is_raw_capture(self) -> bool: ...
def is_reserved_pragma(self) -> bool: ...
def is_reset(self) -> bool: ...
def is_set_frequency(self) -> bool: ...
def is_set_phase(self) -> bool: ...
Expand Down Expand Up @@ -277,8 +274,6 @@ class Instruction:
@staticmethod
def from_raw_capture(inner: RawCapture) -> Instruction: ...
@staticmethod
def from_reserved_pragma(inner: ReservedPragma) -> Instruction: ...
@staticmethod
def from_set_frequency(inner: SetFrequency) -> Instruction: ...
@staticmethod
def from_set_phase(inner: SetPhase) -> Instruction: ...
Expand Down Expand Up @@ -358,8 +353,6 @@ class Instruction:
def to_pulse(self) -> Pulse: ...
def as_raw_capture(self) -> Optional[RawCapture]: ...
def to_raw_capture(self) -> RawCapture: ...
def as_reserved_pragma(self) -> Optional[ReservedPragma]: ...
def to_reserved_pragma(self) -> ReservedPragma: ...
def as_reset(self) -> Optional[Reset]: ...
def to_reset(self) -> Reset: ...
def as_set_frequency(self) -> Optional[SetFrequency]: ...
Expand Down Expand Up @@ -1191,13 +1184,13 @@ class FrameIdentifier:

@final
class CallArgument:
"""An argument to a `Call` instruction.
"""An argument to a ``Call`` instruction.
This may be expressed as an identifier, a memory reference, or an immediate value. Memory references and identifiers require a corresponding memory region declaration by the time of
compilation (at the time of call argument resolution and memory graph construction to be more precise).
Additionally, an argument's resolved type must match the expected type of the corresponding `ExternParameter`
in the `Externsignature`.
Additionally, an argument's resolved type must match the expected type of the corresponding ``ExternParameter``
in the ``ExternSignature``.
"""
def inner(self) -> Union[List[List[Expression]], List[int], PauliSum]:
"""Returns the inner value of the variant. Raises a ``RuntimeError`` if inner data doesn't exist."""
Expand Down Expand Up @@ -1229,40 +1222,13 @@ class CallArgument:
If any part of the instruction can't be converted to valid Quil, it will be printed in a human-readable debug format.
"""

@final
class CallArguments:
"""A list of `CallArgument`s for a single `CALL`.
This abstract is necessary for the inner workings of the `CallArgument` type resolution.
"""

def inner(self) -> Union[List[List[Expression]], List[int], PauliSum]:
"""Returns the inner value of the variant. Raises a ``RuntimeError`` if inner data doesn't exist."""
...
def is_arguments(self) -> bool: ...
def as_arguments(self) -> Optional[List["CallArgument"]]: ...
def to_arguments(self) -> List["CallArgument"]: ...
@staticmethod
def from_arguments(inner: List["CallArgument"]) -> "CallArguments": ...
def to_quil(self) -> str:
"""Attempt to convert the instruction to a valid Quil string.
Raises an exception if the instruction can't be converted to valid Quil.
"""
...
def to_quil_or_debug(self) -> str:
"""Convert the instruction to a Quil string.
If any part of the instruction can't be converted to valid Quil, it will be printed in a human-readable debug format.
"""

class CallValidationError(ValueError):
"""An error that may occur when performing operations on a ``Call``."""
class CallError(ValueError):
"""An error that may occur when initializing a ``Call``."""

...

class Call:
"""An instruction to an external function declared within an `ExternDefinition`.
"""An instruction to an external function declared within a `PRAGMA EXTERN` instruction.
These calls are generally specific to a particular hardware or virtual machine
backend. For further detail, see:
Expand All @@ -1273,7 +1239,7 @@ class Call:
* `quil#87 <https://github.com/quil-lang/quil/issues/87>`_
Also see `ExternDefinition`.
Also see ``ExternSignature``.
"""
def __new__(
cls,
Expand All @@ -1285,9 +1251,9 @@ class Call:
@name.setter
def name(self, name: str) -> None: ...
@property
def arguments(self) -> "CallArguments": ...
def arguments(self) -> List[CallArgument]: ...
@arguments.setter
def arguments(self, arguments: "CallArguments") -> None: ...
def arguments(self, arguments: List[CallArgument]) -> None: ...
def to_quil(self) -> str:
"""Attempt to convert the instruction to a valid Quil string.
Expand All @@ -1311,13 +1277,13 @@ class Call:

@final
class ExternParameterType:
"""The type of an `ExternParameter`.
"""The type of an ``ExternParameter``.
This type is used to define the expected type of the parameter in the `ExternSignature`. May be
This type is used to define the expected type of a parameter within an ``ExternSignature``. May be
either a scalar, fixed-length vector, or variable-length vector.
Note, both scalars and fixed-length vectors are fully specified by a `ScalarType`, but are indeed
distinct types.
Note, both scalars and fixed-length vectors are fully specified by a ``ScalarType``, but are indeed
distinct ``ExternParameterType``s.
"""

def inner(self) -> Union["ScalarType", "Vector"]:
Expand Down Expand Up @@ -1351,7 +1317,7 @@ class ExternParameterType:
"""

class ExternParameter:
"""A parameter within an `ExternSignature`. These are defined by a name, mutability, and type."""
"""A parameter within an ``ExternSignature``. These are defined by a name, mutability, and type."""
def __new__(
cls,
name: str,
Expand Down Expand Up @@ -1392,9 +1358,9 @@ class ExternParameter:
"""Returns a shallow copy of the class."""

class ExternSignature:
"""The signature of an `ExternDefinition`.
"""The signature of a ``PRAGMA EXTERN`` instruction.
This signature is defined by a list of `ExternParameter`s and an
This signature is defined by a list of ``ExternParameter``s and an
optional return type. See the `Quil Specification <https://github.com/quil-lang/quil/blob/7f532c7cdde9f51eae6abe7408cc868fba9f91f6/specgen/spec/sec-other.s>`_
for details on how these signatures are formed.
"""
Expand Down Expand Up @@ -1432,60 +1398,11 @@ class ExternSignature:
def __copy__(self) -> Self:
"""Returns a shallow copy of the class."""

class ExternValidationError(ValueError):
"""An error that may occur when initializing or validating an ``ExternDefinition``."""
class ExternError(ValueError):
"""An error that may occur when initializing or validating a ``PRAGMA EXTERN`` instruction."""

...

class ExternDefinition:
"""An external function declaration.
These are generally specific to a particular hardware or virtual machine backend. Note,
these are not standard Quil instructions, but rather a type of `ReservedPragma`.
For further detail, see:
* `Other instructions and Directives <https://github.com/quil-lang/quil/blob/master/rfcs/extern-call.md>`_
in the Quil specification.
* `EXTERN / CALL RFC <https://github.com/quil-lang/quil/blob/master/rfcs/extern-call.md>`_
* `quil#87 <https://github.com/quil-lang/quil/issues/87>`_
Also see `Call`.
"""
def __new__(
cls,
name: str,
signature: Optional[ExternSignature],
) -> Self: ...
@property
def name(self) -> str: ...
@name.setter
def name(self, name: str) -> None: ...
@property
def signature(self) -> Optional[ExternSignature]: ...
@signature.setter
def signature(self, signature: ExternSignature) -> None: ...
def to_quil(self) -> str:
"""Attempt to convert the instruction to a valid Quil string.
Raises an exception if the instruction can't be converted to valid Quil.
"""
...
def to_quil_or_debug(self) -> str:
"""Convert the instruction to a Quil string.
If any part of the instruction can't be converted to valid Quil, it will be printed in a human-readable debug format.
"""
def __deepcopy__(self, _: Dict) -> Self:
"""Creates and returns a deep copy of the class.
If the instruction contains any ``QubitPlaceholder`` or ``TargetPlaceholder``, then they will be replaced with
new placeholders so resolving them in the copy will not resolve them in the original.
Should be used by passing an instance of the class to ``copy.deepcopy``
"""
def __copy__(self) -> Self:
"""Returns a shallow copy of the class."""

class Capture:
def __new__(
cls,
Expand Down Expand Up @@ -2194,33 +2111,6 @@ class PragmaArgument:
If any part of the instruction can't be converted to valid Quil, it will be printed in a human-readable debug format.
"""

@final
class ReservedPragma:
"""An instruction represented by as a specially structured `Pragma`.
Currently, this may only be an `ExternDefinition`.
"""

def inner(self) -> Union["ExternDefinition"]: # type: ignore
"""Returns the inner value of the variant. Raises a ``RuntimeError`` if inner data doesn't exist."""
...
def is_extern_definition(self) -> bool: ...
def as_extern_definition(self) -> Optional[ExternDefinition]: ...
def to_extern_definition(self) -> ExternDefinition: ...
@staticmethod
def from_extern_definition(inner: ExternDefinition) -> "ReservedPragma": ...
def to_quil(self) -> str:
"""Attempt to convert the instruction to a valid Quil string.
Raises an exception if the instruction can't be converted to valid Quil.
"""
...
def to_quil_or_debug(self) -> str:
"""Convert the instruction to a Quil string.
If any part of the instruction can't be converted to valid Quil, it will be printed in a human-readable debug format.
"""

class Include:
def __new__(cls, filename: str) -> Self: ...
@property
Expand Down
15 changes: 0 additions & 15 deletions quil-py/quil/program/__init__.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -141,21 +141,6 @@ class Program:
while ensuring that unique value is not already in use within the program.
"""
...
def resolve_call_instructions(self) -> None:
"""Resolve ``CALL`` instructions within the program.
This does two things:
1. It validates all ``EXTERN`` instructions in the program.
2. It resolves the ``CALL`` instruction data types based on the declared memory types
and ensures those match one and only one ``EXTERN`` instruction.
This method is only useful for validating program structure before it is compiled. Note,
this mutates the inner representation of the program.
:raises ProgramError: If any of the above conditions are not met.
"""
...
def resolve_placeholders_with_custom_resolvers(
self,
*,
Expand Down
Loading

0 comments on commit 957b470

Please sign in to comment.