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

gh-126599: Refactor the _PyOptimizer APIs #126853

Merged
merged 18 commits into from
Jan 16, 2025

Conversation

xuantengh
Copy link
Contributor

@xuantengh xuantengh commented Nov 15, 2024

Hi this is my draft to remove the _PyOptimizer_NewCounter and _PyOptimizer_NewUOpOptimizer APIs, where the related tests are removed or skipped.

For the most challenging _PyOptimizer_Optimize, I'm still trying to figure out how to achieve its functionality in generated interpreter. To remove the "artificial boundaries", should we just remove this API call and replace its code in the JUMP_BACKWARD, _EXIT_TRACE and _DYNAMIC_EXIT instruction cases?

@xuantengh
Copy link
Contributor Author

cc @brandtbucher @rruuaanng

@rruuaanng
Copy link
Contributor

For the most challenging _PyOptimizer_Optimize, I'm still trying to figure out how to achieve its functionality in generated interpreter. To remove the "artificial boundaries", should we just remove this API call and replace its code in the JUMP_BACKWARD, _EXIT_TRACE and _DYNAMIC_EXIT instruction cases?

Please do not open unfinished PR. (Alternatively, you can convert it to a draft PR.)

@xuantengh xuantengh marked this pull request as draft November 15, 2024 08:44
@Fidget-Spinner
Copy link
Member

Please do not open unfinished PR. (Alternatively, you can convert it to a draft PR.)

I disagree. Unfinished PRs are fine as long as they're for discussion. Also they help us lead contributors in the right direction before they put too much effort in.

@rruuaanng
Copy link
Contributor

Please do not open unfinished PR. (Alternatively, you can convert it to a draft PR.)

I disagree. Unfinished PRs are fine as long as they're for discussion. Also they help us lead contributors in the right direction before they put too much effort in.

I don't object to this kind of behavior, but it should be opened as a draft before it is completed, which will waste review resources.
We should not open it as a PR that can be officially reviewed.

Copy link
Member

@Fidget-Spinner Fidget-Spinner left a comment

Choose a reason for hiding this comment

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

Thanks for picking this up. I think there might be some confusion of what is the API and what isn't so let me try my best to explain:

  • The API in CPython refers to what people use externally.
  • pycore_* files in general cannot be accessed when including the C API, unless they are included directly.
  • PyAPI_FUNC exports the symbol on Windows and other platforms.

So the thing we need to do is:

  1. Make sure the API now lives in pycore_optimizer.h
  2. Remove PyAPI_FUNC, except for when the JIT compiler needs it (The JIT compiler needs symbols exported for Windows).

So the code in JUMP_BACKWARD and ENTER_EXECUTOR shouldn't change either. We need those code for optimizing the JIT!

Lib/test/test_capi/test_opt.py Outdated Show resolved Hide resolved
Lib/test/test_monitoring.py Show resolved Hide resolved
Modules/_testinternalcapi.c Outdated Show resolved Hide resolved
Modules/_testinternalcapi.c Outdated Show resolved Hide resolved
Python/pylifecycle.c Outdated Show resolved Hide resolved
Comment on lines 119 to 123
PyAPI_FUNC(PyObject *) _PyOptimizer_NewCounter(void);
PyAPI_FUNC(PyObject *) _PyOptimizer_NewUOpOptimizer(void);
Copy link
Member

Choose a reason for hiding this comment

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

In theory, the only change you need is to remove the PyAPI_FUNC. That will stop the optimizer from being exported as public API.

Copy link
Contributor

@rruuaanng rruuaanng Nov 15, 2024

Choose a reason for hiding this comment

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

If the header file isn't used elsewhere, we can remove it and keep the signature only in the source file.
(Sorry for the term mobile. I don't look it.)

Edit
I think. A small suggestion.

Copy link
Member

Choose a reason for hiding this comment

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

pycore_optimizer.h is used. Please don't remove it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

These 2 APIs are used for _testinternalcapi for testing. It seems like _testinternalcapi fails to be imported due to missing symbols after removing the PyAPI_FUNC.

Copy link
Member

Choose a reason for hiding this comment

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

You should likely mark them as extern if they are needed to be exported then.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

IIUC, the APIs used by _testinternalcapi need to be exported? It seems extern does not help here.

Copy link
Member

Choose a reason for hiding this comment

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

Oh, right, it seems that declaring them as extern is not sufficient. So we should probably keep PyAPI_FUNC. However, you should add a comment "// Export for '_testinternalcapi' shared extension.".

@picnixz
Copy link
Member

picnixz commented Nov 15, 2024

I don't object to this kind of behavior, but it should be opened as a draft before it is completed, which will waste review resources. We should not open it as a PR that can be officially reviewed.

The reason why we advised you to use draft PRs is that you are committing a lot before the code is fine to be reviewed. If a PR is in a state where it should be reviewed (for instance if the CI is green or if there is no code planned to be committed just after), then it's perfectly fine to keep it open.

@rruuaanng
Copy link
Contributor

I don't object to this kind of behavior, but it should be opened as a draft before it is completed, which will waste review resources. We should not open it as a PR that can be officially reviewed.

The reason why we advised you to use draft PRs is that you are committing a lot before the code is fine to be reviewed. If a PR is in a state where it should be reviewed (for instance if the CI is green or if there is no code planned to be committed just after), then it's perfectly fine to keep it open.

There seems to be a little misunderstanding. I think this comment implies that there is still unfinished work :(

@xuantengh
Copy link
Contributor Author

xuantengh commented Nov 15, 2024

Sorry, I'm still a little confused about the goal of this PR.

  1. Make sure the API now lives in pycore_optimizer.h

Does it mean we should define all JIT related APIs in this file?

  1. Remove PyAPI_FUNC, except for when the JIT compiler needs it (The JIT compiler needs symbols exported for Windows).

It seems that the currently exported APIs in pycore_optimizer.h are either used by testing or JIT, so we cannot make them private. Maybe we want to hide the optimizer related APIs for users, but it seems there is not so much we can do for it?

Reverted to bring the tests back.

@willingc
Copy link
Contributor

@xuantengh Thank you for your efforts on this PR. @Fidget-Spinner who has experience with this area of the code should be able to provide guidance as you move this PR forward.

@rruuaanng, Let's try to keep the comments positive and constructive. Please try to encourage other contributors instead of telling them what to do or not do. The goal for PRs are to build understanding during review and iterate to an optimal solution. The solution, as we have discussed before, must consider many factors including backward compatibility, maintainability, security, testing, complexity and code churn.

Sometimes a question lends much better results than telling someone what to do. For example, "Would you appreciate feedback on the PR so far?" instead of "Please do not open unfinished PR.". You can trust that the triagers and core developers are working toward creating a productive and healthy contributor experience for all. Please respect the importance of this goal.

@brandtbucher
Copy link
Member

Sorry this got derailed, @xuantengh. It's also a little trickier than I originally assumed.

Let's start over. For this PR, can you just remove the "counter" optimizer, and any tests that use it? I think that's a fairly self-contained task, and gives us a better idea of what difficulty remains in extracting the other two. I also don't think it will involve deleting any files.

@rruuaanng, I can handle the review from here. I'm not worried about my time spent working with the author to get things in a good state here.

@xuantengh
Copy link
Contributor Author

xuantengh commented Nov 23, 2024

can you just remove the "counter" optimizer, and any tests that use it?

Sure, I'll try it.

Update: the _PyOptimizer_NewCounter API and __PyCounterOptimizer_Type type are removed. I simply skip the tests rather than deleting them.

@xuantengh xuantengh force-pushed the remove-pyopt-api branch 2 times, most recently from b51de05 to 4c0e6c0 Compare November 23, 2024 15:56
@xuantengh xuantengh marked this pull request as ready for review January 1, 2025 02:58
@xuantengh
Copy link
Contributor Author

I'm sorry for forgetting to remove the "draft" label for this PR.

For this PR, can you just remove the "counter" optimizer, and any tests that use it?

Regarding this goal, I think it's ready for review.

Copy link
Member

@brandtbucher brandtbucher left a comment

Choose a reason for hiding this comment

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

Thanks for reworking this!

There's a bit more to do, though. Please also remove these:

  • _PyCounterOptimizerObject
  • counter_dealloc
  • _PyCounterExecutor_Type
  • counter_optimize
  • counter_get_counter
  • counter_optimizer_methods
  • Remove the check for "counting_executor" from add_executor_dependency (it isn't needed).

You'll also need to remove the _INTERNAL_INCREMENT_OPT_COUNTER bytecode instruction. It's defined in Python/bytecodes.c. Just remove it there, then run make regen-cases to update all of the generated files.

Let me know if you get stuck.

Include/internal/pycore_optimizer.h Outdated Show resolved Hide resolved
Lib/test/test_monitoring.py Outdated Show resolved Hide resolved
Lib/test/test_capi/test_opt.py Outdated Show resolved Hide resolved
Lib/test/test_capi/test_opt.py Outdated Show resolved Hide resolved
@bedevere-app
Copy link

bedevere-app bot commented Jan 7, 2025

A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated.

Once you have made the requested changes, please leave a comment on this pull request containing the phrase I have made the requested changes; please review again. I will then notify any core developers who have left a review that you're ready for them to take another look at this pull request.

@brandtbucher
Copy link
Member

@xuantengh, is this ready for review again? Happy to help if you're stuck, but I'd like to get this change in soon. :)

(Also, looks like you might need to merge in main and run make regen-all.)

@xuantengh
Copy link
Contributor Author

xuantengh commented Jan 14, 2025

I have made the requested changes; please review again.

Hi @brandtbucher, I've merged in main and rerun make regen-all. BTW, should I avoid pushing commits in the PR branch if it hasn't completed to avoid disturbing reviewers?

@bedevere-app
Copy link

bedevere-app bot commented Jan 14, 2025

Thanks for making the requested changes!

@brandtbucher: please review the changes made to this pull request.

@bedevere-app bedevere-app bot requested a review from brandtbucher January 14, 2025 01:37
@brandtbucher
Copy link
Member

Hi @brandtbucher, I've merged in main and rerun make regen-all. BTW, should I avoid pushing commits in the PR branch if it hasn't completed to avoid disturbing reviewers?

It's not a problem to push new commits periodically (just don't force-push, please... merge instead of rebasing). I just wasn't sure if it was were ready yet. :)

@brandtbucher
Copy link
Member

I'll try to finish reviewing this today, but I might not finish until tomorrow.

Copy link
Member

@brandtbucher brandtbucher left a comment

Choose a reason for hiding this comment

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

Looks great, thanks! I'm just going to push a couple of changes to address some warnings and clean up the diff.

@brandtbucher brandtbucher merged commit b44ff6d into python:main Jan 16, 2025
57 checks passed
@bedevere-bot
Copy link

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot aarch64 Fedora Stable LTO 3.x has failed when building commit b44ff6d.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/#/builders/336/builds/6169) and take a look at the build logs.
  4. Check if the failure is related to this commit (b44ff6d) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/#/builders/336/builds/6169

Summary of the results of the build (if available):

==

Click to see traceback logs
Traceback (most recent call last):
  File "/home/buildbot/buildarea/3.x.cstratak-fedora-stable-aarch64.lto/build/Lib/threading.py", line 1054, in _bootstrap_inner
    self.run()
    ~~~~~~~~^^
  File "/home/buildbot/buildarea/3.x.cstratak-fedora-stable-aarch64.lto/build/Lib/threading.py", line 996, in run
    self._target(*self._args, **self._kwargs)
    ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/buildbot/buildarea/3.x.cstratak-fedora-stable-aarch64.lto/build/Lib/test/test_interpreters/test_stress.py", line 30, in task
    interp = interpreters.create()
  File "/home/buildbot/buildarea/3.x.cstratak-fedora-stable-aarch64.lto/build/Lib/test/support/interpreters/__init__.py", line 76, in create
    id = _interpreters.create(reqrefs=True)
interpreters.InterpreterError: interpreter creation failed
k


Traceback (most recent call last):
  File "/home/buildbot/buildarea/3.x.cstratak-fedora-stable-aarch64.lto/build/Lib/threading.py", line 1054, in _bootstrap_inner
    self.run()
    ~~~~~~~~^^
  File "/home/buildbot/buildarea/3.x.cstratak-fedora-stable-aarch64.lto/build/Lib/threading.py", line 996, in run
    self._target(*self._args, **self._kwargs)
    ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/buildbot/buildarea/3.x.cstratak-fedora-stable-aarch64.lto/build/Lib/test/test_interpreters/test_stress.py", line 47, in run
    interp = interpreters.create()
  File "/home/buildbot/buildarea/3.x.cstratak-fedora-stable-aarch64.lto/build/Lib/test/support/interpreters/__init__.py", line 76, in create
    id = _interpreters.create(reqrefs=True)
interpreters.InterpreterError: interpreter creation failed
k

@xuantengh xuantengh deleted the remove-pyopt-api branch January 19, 2025 05:33
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.

7 participants