-
Notifications
You must be signed in to change notification settings - Fork 63
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
Core type system #697
Core type system #697
Conversation
@manopapad @jjwilke @bryevdv this PR is fairly big, so I thought it'd be helpful to have more than one pair of eyes on the code. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great improvement
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. A couple nits. Main question is on Store lifetimes related to reference_wrapper and std::unique_ptr
examples/hello/editable-install.sh
Outdated
@@ -1,5 +1,5 @@ | |||
legate_root=`python -c 'import legate.install_info as i; from pathlib import Path; print(Path(i.libpath).parent.resolve())'` | |||
echo "Using Legate at $legate_root" | |||
cmake -S . -B build -D legate_core_ROOT=$legate_root | |||
cmake --build build | |||
cmake --build build -j 8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would call --parallel
instead of -j 8
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -220,7 +220,7 @@ void StoreMapping::populate_layout_constraints( | |||
{ | |||
StoreMapping mapping{}; | |||
mapping.policy = InstanceMappingPolicy::default_policy(target, exact); | |||
mapping.stores.push_back(store); | |||
mapping.stores.emplace_back(store); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm a bit uncomfortable with the change here. Store has changed from a lightweight, copyable handle to a move-only class. The reference_wrapper stuff here has potential lifetime issues. I'm sure the current implementation is correct, but I don't love creating a vector of references that returns from a function.
Can these type objects just be statics? They are going to get reused quite a bit, yeah? Would it be better to move from unique_ptr<Type>
to Type*
where Type is an object with static lifetime?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note that we don't want to pass around pointers in the distributed setting, so Type*
needs to be deserialized somehow in the mapper. We can certainly make a singleton type object for each distinct type, but then we need a centralized registry of Type*
objects for the deserializer (so it can recover a Type*
from its serialized form) , which would then introduce synchronization between the control code registering types and every deserialization attempt. I don't actually want to introduce this. Though I don't like how it's set up, I feel it's reasonable because store mappings cannot exist without stores nor can they outlive them.
Legion::Runtime::perform_registration_callback( | ||
detail::invoke_legate_registration_callback<CALLBACK>, true /*global*/); | ||
auto runtime = Runtime::get_runtime(); | ||
if (runtime->is_in_callback()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would cause multiple callbacks to get invoked recursively? Also - can we guarantee that perform_registration_callback
will actually invoke the callback? Doesn't it sometimes defer the callback?
If Legion defers the callback until later, it might invoke the callback when runtime->is_in_callback
is false?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Callbacks don't get deferred with Legion::Runtime::perform_registration_callback
; it's add_registration_callback
that defers them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
) except+ | ||
|
||
|
||
cdef Dtype from_ptr(Type* ty): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it be possible to use forwarding references here, similar to https://github.com/cython/cython/blob/master/tests/run/cpp_forwarding_ref.pyx, to avoid having to release()
then reset()
the unique_ptr
s?
def serialize(self, buf) -> None: | ||
buf.pack_32bit_int(self.code) | ||
buf.pack_32bit_int(self.uid) | ||
buf.pack_32bit_int(self.num_elements()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically buf.pack_32bit_uint
, but I doubt it matters.
buf.pack_32bit_int(self.code) | ||
num_fields = self.num_fields() | ||
buf.pack_32bit_int(self.uid) | ||
buf.pack_32bit_int(num_fields) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly technically buf.pack_32bit_uint
@@ -49,11 +49,10 @@ class Scalar { | |||
* @brief Creates a shared `Scalar` with an existing allocation. The caller is responsible | |||
* for passing in a sufficiently big allocation. | |||
* | |||
* @param tuple If true, the allocation contains a tuple of scalars. | |||
* @param code Type code of the scalar(s) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update argument doc
*/ | ||
bool is_tuple() const { return tuple_; } | ||
const Type* type() const { return type_.get(); } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could probably return a const Type&
here, like Store.type()
does, to avoid exposing the pointer.
refactored in nv-legate/legate#697
This PR adds a common type system to Legate core. The type system supports primitive types, fixed size array types, and struct types. Struct types can optionally be aligned, which is often what the C++ counterpart expects. As a part of the refactoring, the ugly handling of tuples in
legate::Scalar
has been improved with the new fixed-size array type so everything is under the same type system.