Skip to content

Conversation

@austingmhuang
Copy link
Contributor

Context:
The resource config currently exists as a global dictionary, which is passed to plre.estimate
Issues:

  • Not very user-friendly or sustainable, as the config will continue to grow as more op-specific tolerances are added.
  • From an SW standpoint, we also don’t want a global dict like this
  • It also forces the user to make decisions about operators which they do not necessarily care about, or to need to copy-paste all of the defaults despite only being interested in changing one such parameter.
  • The user needs to rewrite the config every time they want to change something

Description of the Change:
Develops a config class, which has its own set of defaults, and makes it easy for the user to change what they wish.

Benefits:
Resolves above issues.

Possible Drawbacks:

Related GitHub Issues:
[sc-97227]

@codecov
Copy link

codecov bot commented Sep 4, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.39%. Comparing base (419615c) to head (04b531f).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #8195      +/-   ##
==========================================
- Coverage   99.39%   99.39%   -0.01%     
==========================================
  Files         550      550              
  Lines       57026    57026              
==========================================
- Hits        56683    56682       -1     
- Misses        343      344       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@austingmhuang austingmhuang requested review from astralcai, ddhawan11 and soranjh and removed request for ddhawan11 September 4, 2025 22:05
Copy link
Contributor

@astralcai astralcai left a comment

Choose a reason for hiding this comment

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

I have some architectural suggestions:

  • In general, we want to avoid having a global configuration object. In PL, a new ExecutionConfig is created for each circuit execution. I think we want something similar here. Instead of having a global mutable object, the user would create an ResourceConfig object, modify it as they please, and manually pass this object to each execution of the resource estimation pipeline.

  • The ResourceConfig object contains a lot of information, but most operators do not need any of that. The ones that do typically only need one or two values. I don't think this ResourceConfig should be passed to each operator. The config object should store operator-specific configs on an operator-by-operator basis, using something along the lines of:

    {
        ...,
        MPSPrep: {'precision': 1e-9},
        Qubitization: {'rotation_precision': 15, 'coeff_precision': 15}
    }

    and the resource estimation pipeline is responsible for extracting the necessary keyword arguments for each operator, and passing them into the operator's decomp methods as regular keyword arguments. I'm thinking something along the lines of:

    class SomeOp:
         
        @classmethod
        def resource_decomp(cls, ..., some_kwarg=...):
            ...

    and then in the actual resource estimation pipeline,

    kwargs = config.conf[cp_rep.op_type]
    resource_decomp = cp_rep.op_type.resource_decomp(**cp_rep.params, **kwargs)

    This way we don't modify the signature of the resource decomp methods to include a config that most operators are not going to use, and the operators that do support customization don't have to dig the information they need out from a potentially very large dictionary with a a bunch of entries that are irrelevant to them.

@austingmhuang
Copy link
Contributor Author

  • The ResourceConfig object contains a lot of information, but most operators do not need any of that. The ones that do typically only need one or two values. I don't think this ResourceConfig should be passed to each operator. The config object should store operator-specific configs on an operator-by-operator basis, using something along the lines of:

    {
        ...,
        MPSPrep: {'precision': 1e-9},
        Qubitization: {'rotation_precision': 15, 'coeff_precision': 15}
    }

    and the resource estimation pipeline is responsible for extracting the necessary keyword arguments for each operator, and passing them into the operator's decomp methods as regular keyword arguments. I'm thinking something along the lines of:

    class SomeOp:
         
        @classmethod
        def resource_decomp(cls, ..., some_kwarg=...):
            ...

    and then in the actual resource estimation pipeline,

    kwargs = config.conf[cp_rep.op_type]
    resource_decomp = cp_rep.op_type.resource_decomp(**cp_rep.params, **kwargs)

    This way we don't modify the signature of the resource decomp methods to include a config that most operators are not going to use, and the operators that do support customization don't have to dig the information they need out from a potentially very large dictionary with a a bunch of entries that are irrelevant to them.

Hi @astralcai , thanks for your suggestions and comments. I agree that the current design is not ideal: there is a lot of excess information that the config passes into the each resource_decomp method that is not necessary. The main issue is that we cannot avoid passing in the config into these resource_decomp methods. Here is an example that would fail without passing in config.

op1 = DummyOp(x=5)
rc = ResourceConfig()
assert DummyOp.resource_decomp(config=rc, **op1.resource_params) == [5]

def custom_res_decomp(config, x, **kwargs):
    return [x + 1]

rc.set_decomp(DummyOp, custom_res_decomp)
assert DummyOp.resource_decomp(config=rc, **op1.resource_params) == [6]

Here, notice that if we do not pass in a config to our DummyOp's resource_decomp(), there is no way for resource_decomp() to find the custom decomposition set in rc.set_decomp(...). For resource_decomp() to know if there is a custom_decomp, we will need to pass that in somehow.

This leaves us with the following options:

  1. (Current) We have one Config class that holds the decomposition configs and the error/precision configs
  • Benefits: Only one class needed to manipulate and pass into resource_decomp()
  • Cons: The Config class contains information that is often unneeded by the resource_decomp() e.g. error information not relevant to a certain operator.
  1. We have two config classes: one that holds the decomposition configs, and one that holds the error/precision configs. The error/precision configs will be operator specific. The function signature will be something like: resource_decomp(decomp_config, some_kwarg, ...)
  • Benefits: resource_decomp() does not take in unneeded error information (still takes in potentially unneeded decomposition information). Relevant error information is provided via kwargs.
  • Cons: we now have two Config classes: decomp_config which holds the configs for the decompositions, which can still hold unneeded information and error_config which is just a dictionary with some pre-defined items. error_config is only relevant when we call estimate on some circuit.
  1. Make resource_decomp() and others private functions: this allows us to do whatever we want with those functions and pass in only relevant information. Users are expected to call only estimate to get the resources.

@austingmhuang
Copy link
Contributor Author

Discussed offline. Conclusion is we will go with @astralcai's suggestions and rework the architecture essentially. The change in behaviour for resource_decomp is no issue.

Copy link
Contributor

@ddhawan11 ddhawan11 left a comment

Choose a reason for hiding this comment

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

Looks good to me @austingmhuang

Copy link
Contributor

@andrijapau andrijapau left a comment

Choose a reason for hiding this comment

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

LGTM, thank you for addressing @astralcai 's concerns so quickly. ❤️

I think this PR has improved on the initial implementation a lot!

Copy link
Contributor

@soranjh soranjh left a comment

Choose a reason for hiding this comment

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

Thanks @austingmhuang . Please check the docs and also the arg names before merging.

Copy link
Contributor

@AntonNI8 AntonNI8 left a comment

Choose a reason for hiding this comment

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

👁️

Copy link
Contributor

@AntonNI8 AntonNI8 left a comment

Choose a reason for hiding this comment

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

@austingmhuang austingmhuang added this pull request to the merge queue Sep 11, 2025
Merged via the queue into master with commit da1ced0 Sep 11, 2025
52 checks passed
@austingmhuang austingmhuang deleted the resource_config_class branch September 11, 2025 21:49
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.

8 participants