Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide default size to some variable types with unspecified size #81

Closed
wants to merge 2 commits into from

Conversation

rmshaffer
Copy link
Contributor

In some cases, expressions were assigned types without a size. One side effect of this is that OpenQASM subroutines can sometimes be generated with an unsized (i.e. machine-sized) return type, e.g. float rather than float[64].

For example,

@subroutine
def product(prog: Program) -> FloatVar:
    a = IntVar(2, "a")
    prog.declare(a)
    return a * 2.5

prog = Program()
z = FloatVar(0.0, "z")
prog.set(z, product(prog))

would produce an OpenQASM subroutine defined as

def product() -> float {
    int[32] a = 2;
    return a * 2.5;
}

where the return type is a machine-sized float rather than an explicitly-sized type (e.g. float[64]).

This change cleans up these cases (at least, the ones I was able to find) so that the variables have default sizes specified explicitly, which seems more consistent with the typical behavior of oqpy.

@rmshaffer rmshaffer marked this pull request as ready for review November 13, 2023 18:54
Copy link
Collaborator

@jcjaskula-aws jcjaskula-aws left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the problem is bigger than the type size. When one uses the overloaded return python keyword, the type hint is ignored leading to counter-intuitive behavior:


@oqpy.subroutine
def product(prog: oqpy.Program) -> oqpy.IntVar[64]:
    a = oqpy.IntVar(2, "a")
    prog.declare(a)
    return a * 2.5

prog = oqpy.Program()
z = oqpy.FloatVar(0.0, "z")
prog.set(z, product(prog))

produces actually:

OPENQASM 3.0;
def product() -> float {
    int[32] a = 2;
    return a * 2.5;
}
float[64] z = 0.0;
z = product();

Because of the limitation of the return keyword (cannot have multiple returns in a single subroutine), I wonder if we should discourage/deprecate it.

Concerning the default type size behavior, I would vote for making the machine-sized type default everywhere. Users could always force the size with the __class_getitem__ mechanism.

@anuragm
Copy link
Contributor

anuragm commented Nov 29, 2023


@oqpy.subroutine
def product(prog: oqpy.Program) -> oqpy.IntVar[64]:
    a = oqpy.IntVar(2, "a")
    prog.declare(a)
    return a * 2.5

prog = oqpy.Program()
z = oqpy.FloatVar(0.0, "z")
prog.set(z, product(prog))

This happens because oqpy.IntVar[64] is not returning a new class, but rather a functool.partial function object. We should instead create a new class for each _SizedVar equivalent (using the type metaclass) and return that. https://docs.python.org/3/reference/datamodel.html#the-purpose-of-class-getitem

@jcjaskula-aws
Copy link
Collaborator

This happens because oqpy.IntVar[64] is not returning a new class, but rather a functool.partial function object. We should instead create a new class for each _SizedVar equivalent (using the type metaclass) and return that. https://docs.python.org/3/reference/datamodel.html#the-purpose-of-class-getitem

Still does not work with IntVar. In this particular case, it is really the return path that sets the OQ3 return type, not the Python type hint.

@rmshaffer
Copy link
Contributor Author

rmshaffer commented Nov 30, 2023

Because of the limitation of the return keyword (cannot have multiple returns in a single subroutine), I wonder if we should discourage/deprecate it.

@jcjaskula-aws I'm a little confused by this comment - what would be the way to return values from a subroutine without using the return keyword?

@jcjaskula-aws
Copy link
Collaborator

jcjaskula-aws commented Nov 30, 2023

You can use prog.returns (code here). This can be used at multiple locations within a subroutine.

@rmshaffer rmshaffer closed this May 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants