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

co_broadcast of derived types with allocatable components #73

Open
everythingfunctional opened this issue Mar 7, 2024 · 3 comments
Open

Comments

@everythingfunctional
Copy link
Member

The current implementation of co_broadcast does not support derived types with allocatable components. Not sure if we need a reworking of the API for co_broadcast or just an illustration of how a compiler would generate code to do it. See #72 for a test case demonstrating the issue.

@bonachea
Copy link
Member

bonachea commented Mar 7, 2024

I agree the F23 spec foolishly allows broadcasting an object with allocatable (and polymorphic!) sub-objects and specifically requires:

including (re)allocation of any allocatable potential subobject component, and setting the dynamic type of any polymorphic allocatable potential subobject component

Does any current compiler actually implement this semantic?

I don't see how we can implement this in PRIF without requiring the compiler to generate serialization/deserialization code for any co_broadcast argument with non-trivially-copyable type (or provide enough reflection support for us to generate them, which seems even less likely). The compiler would need to either provide us serialization callbacks, or generate code to perform the serialization/deserialization "manually" around a call to prif_co_broadcast with a trivially-copyable serialized representation. All of this seems atypical given that most other parallel features appear to have been crafted to avoid supporting such use cases.

On a related note, the language spec apparently fails to address how co_broadcast should handle any non-null POINTER components embedded in a derived-type argument, where any semantic other than "forbidden" or "nulls them out" probably also constitutes a Hard Problem.

This honestly seems like a language defect. IMO arguments with allocatable and pointer subobjects should simply be forbidden as arguments to co_broadcast, in the same way that co_reduce already prohibits them (for presumably similar reasons).

@everythingfunctional
Copy link
Member Author

Does any current compiler actually implement this semantic?

NAG supports it, but that may actually be it.

I don't expect this to be a trivial problem to solve, but I do have use cases where I want it to work. (de)serialization would certainly be one approach to making it work. If we think that's an avenue for compilers to exploit (and my guess is it probably is) I'd vote for that approach. I don't think that even necessarily needs a change to the API.

@bonachea
Copy link
Member

bonachea commented Mar 8, 2024

I think it's worth noting the "problem" here is wider than simply discontiguity and (de)serialization. When an input argument is permitted to contain allocatable and/or polymorphic subobjects, that means in general the non-root images cannot compute based on static information the size of the serialized representation they are receiving. IOW this becomes a variable-length broadcast, which might entail an additional wire-level broadcast of the length information (depending on the comm layer implementation) before the data can be broadcast.

It's also notable that the restrictions on the top-level object A itself seem designed to try and avoid this:

A shall have the same shape, type, and type parameter values, in corresponding references. It shall not be polymorphic

I don't understand the rationale behind prohibiting characteristics on the co_broadcast argument type that are then permitted for the argument's subobjects, thereby raising exactly the same implementation problems. Or to make the argument from a different direction, one can trivially circumvent the restrictions quoted above for A by packaging the asymmetric/polymorphic value inside a allocatable derived type component, which makes the original restrictions seem irrational/inconsistent.

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

No branches or pull requests

2 participants