Skip to content

Add cy_function and fused_function to the shared utility module#7556

Merged
da-woods merged 4 commits intocython:masterfrom
da-woods:shared-cyfunc-fusedfunc
Mar 9, 2026
Merged

Add cy_function and fused_function to the shared utility module#7556
da-woods merged 4 commits intocython:masterfrom
da-woods:shared-cyfunc-fusedfunc

Conversation

@da-woods
Copy link
Copy Markdown
Contributor

@da-woods da-woods commented Mar 8, 2026

Implementation notes:

  • The struct definitions are always available (even if the type is generated in the shared utility module). This is because we occasionally access into the struct directly and I see no reason to de-optimize that.
  • The __pyx_[Cython/Fused]Function_init functions, which are used to initialize/fetch the type object, differ depending on whether it is locally defined or defined in the shared module. This is done fairly crudely by just using different utility code because it didn't seem worth a complicated mechanism.
  • I had to define a new block to call the _init functions because they needed to be called after the shared module is imported.

Sizes:

Shared module before: 154440 bytes
Shared module with cyfunc: 172256 bytes (+17816 bytes)
Shared module with fusedfunc+cyfunc: 172704 bytes (+448 bytes from cyfunc, +18264 bytes from before)

So adding fusedfunc is a pretty negligable difference (which is good, because it's used relatively infrequently compared to cyfunc)

Module that uses CyFunc drops 17880 bytes
Module that uses CyFunc and fusedfunc drops 18328 bytes

(All sizes are stripped)


The other shared types are probably less obvious about whether to add, but could be handled in much the same way. My view is that they're infrequently used so you'd probably want to be able to configure whether they're included rather than always doing it. I'd like to keep this PR to just the function types.

@da-woods da-woods added the sharedlib Cython module for code sharing between multiple modules. label Mar 8, 2026
Comment on lines +19 to +21
//////////////////// CythonFunctionAlways.proto //////////////////////////
// This section always gets included whether we're using CythonFunction through
// shared utility code or not.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure this is the best bit of naming ever, but a better name wasn't leaping out at me

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe hint at the intention to keep it in the user modules?

  • CythonFunctionModuleCode
  • CythonFunctionPerModule
  • CythonFunctionNonShared
  • CythonFunctionInlineable

@matusvalo
Copy link
Copy Markdown
Contributor

matusvalo commented Mar 8, 2026

I tried to compile scikit-image with PR and without and this PR increases the resulting binary size (sum of all .so files) only few bytes bigger so +1 for me.

@da-woods
Copy link
Copy Markdown
Contributor Author

da-woods commented Mar 8, 2026

I tried to compile scikit-image with PR and without and this PR increases the resulting binary size (sum of all .so files) only few bytes bigger so +1 for me.

I guess that comment was really for #7557?

(This PR here is a big disappointment if it increases sizes)

Copy link
Copy Markdown
Contributor

@scoder scoder left a comment

Choose a reason for hiding this comment

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

Makes total sense.

Comment on lines +19 to +21
//////////////////// CythonFunctionAlways.proto //////////////////////////
// This section always gets included whether we're using CythonFunction through
// shared utility code or not.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe hint at the intention to keep it in the user modules?

  • CythonFunctionModuleCode
  • CythonFunctionPerModule
  • CythonFunctionNonShared
  • CythonFunctionInlineable

@da-woods da-woods enabled auto-merge (squash) March 9, 2026 18:53
@da-woods da-woods added this to the 3.3 milestone Mar 9, 2026
@matusvalo
Copy link
Copy Markdown
Contributor

I tried to compile scikit-image with PR and without and this PR increases the resulting binary size (sum of all .so files) only few bytes bigger so +1 for me.

I guess that comment was really for #7557?

(This PR here is a big disappointment if it increases sizes)

Yes correct. I am sorry. I had two tabs open and wrote in wrong one :-(. Lately, I am kind of messy in GH... :-(

@da-woods da-woods merged commit eee7a60 into cython:master Mar 9, 2026
93 checks passed
@da-woods da-woods deleted the shared-cyfunc-fusedfunc branch March 10, 2026 08:05
if (__Pyx_VerifyCachedType((PyObject*)tp,
__PYX_TYPE_MODULE_PREFIX "fused_cython_function",
__PYX_SHARED_SIZEOF(__pyx_FusedFunctionObject)) != 0) {
Py_DECREF(tp);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is this right? I think it needs to cast to a PyObject * (and also in __Pyx_Get_FusedFunction_Type)

This came up in astropy/astropy#19422

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

You're right (at least in the Limited API).

I'm a bit puzzled how astropy are getting here though because I don't think they're using the shared utility code feature.

I'll investigate and make sure that nothing else is going wrong

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm a bit puzzled how astropy are getting here though because I don't think they're using the shared utility code feature.

Actually __Pyx_Get_FusedFunction_Type is universal so that's fine.

Not sure why this doesn't break every limited API test on Cython though

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Does it matter that they are using CPython3.11?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

No - it's just that our Limited API testing is currently invisibly turned off by mistake.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Will be fixed in #7576

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

sharedlib Cython module for code sharing between multiple modules.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants