-
Notifications
You must be signed in to change notification settings - Fork 426
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
Supported types in collections #15394
Comments
I would tentatively mark tuples of class C { var x: int = 0; }
proc main() {
var tup = (new borrowed C?(128), new borrowed C?(256));
writeln(tup);
return;
} It is only your specific version that does param folding on the class C { var x: int = 0; }
proc test(type T) {
var a = if isTuple(T) then 128 else (new T(1), new T(2));
writeln(a);
return;
}
proc main() {
type T = borrowed C?;
test(T);
return;
}
I'll go ahead and open an issue specifically for this bug. The upside is that for tuples at least, we only have to worry about |
This comment has been minimized.
This comment has been minimized.
Can confirm that the same bug exists for tuples of |
@ben-albrecht #15541 Adjusts all tests in |
This comment has been minimized.
This comment has been minimized.
… expression (#15541) Fix futures for tuples of classes, add future for param folding of if expression (#15541) Several futures filed for #15394 failed due to incorrect folding of a param if expression which resulted in a compiler error. This PR adjusts the tests filed for tuples in #15394 to sidestep the param if expression entirely. It does so by making use of a function overload with a where clause. All tests in `test/types/tuple/types` now pass. --- Thanks @ben-albrecht for signing off!
Nice @dlongnecke-cray! I took a quick look at the buggy case hoping it would have an easy explanation, but failed to come up with anything quickly other than new ways to make the compiler segfault. |
Quick update about the status of classes and
So once again, these futures fail due to something the test code does that actually has nothing to do with The code that fails boils down to this (I should mention that this is after you've removed the fancy var x: borrowed C?;
if false {
x = new borrowed C(128);
} else {
x = new borrowed C(256);
}
writeln(x);
This error makes a bit more sense if you were to imagine Anyhow, removing those allows the I'm working on writing a few more tests.
As for lists of I'm working on it. Realistically, I think it is a task that can be done in a single sprint (I'd even be so bold as to give it a "2"). |
The following is a bit subtle for the current table format, but: The first four rows of the var D = {1..1};
var a: [D] t = ...same initializer as it currently has...;
assert(a.size == 1);
D = {1..2};
assert(a.size == 2); then I get the execution-time error for those four cases because there's no obvious legal value to store in If we wanted to reflect this, we could split the With a quick look, the remaining problem in the array column would be the |
Following onto my previous comment, in the
I think assoc. arrays are pretty much in the same boat, but would want @dlongnecke-cray and/or @daviditen to confirm since they spent a lot of time with them in the past release cycle. |
I think that DavidL's completely correct that the row of A[1] = if isTuple(t) then (new t[0](1), new t[1](2))
else new t(1); imagine for a moment that it had been written like this: A[1] = if isTuple(t) { (new borrowed C?[0](1), new borrowed C?[1](2)) }
else { new borrowed C?(1); } The problem is that the var coll: myCollection(borrowed C?);
var myC = new C();
var b: C? = myC.borrow();
coll.addToCollection(b); to ensure that the object doesn't get reclaimed before the borrow of it or the collection leave scope. For example, this example shows that sparse of |
Thanks @bradcray, I plan to do the following:
|
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
PR is here #15575, but I have some more cleanup before it is ready for review. I'll want Michael to take a look at it regardless. |
@dlongnecke-cray || @daviditen - can you confirm non-nilable types are not expected to work for associative arrays (🔹 for first 5 rows of assoc array)? |
I agree that I'm not sure why they would be different from |
@daviditen - thanks. I'll update the assoc array column.
I'm not sure myself. It does seem like they ought to be consistent. @bradcray - do you have an opinion on it? |
This comment has been minimized.
This comment has been minimized.
I thought you and/or @dlongnecke-cray attempted this during this past release cycle and came back saying that it couldn't be done? (where I thought the challenge related to Meanwhile, what's up with |
This comment has been minimized.
This comment has been minimized.
I will take a look at A
I believe @daviditen had to add several different unconventional accessor methods to the map API in order to make things work. Simply implementing map of non-nilable using nilable was not enough. |
I do view them that way, but thought that the challenges with associative only (mostly?) came up with associative arrays, not associative domains. Oh wait, no that's probably not right since we store arrays of idxType in the associative domain. OK, so I can see how that would cause problems for the non-nilable types. But I'm not clear why all of the nilable cases wouldn't simply work. (And I'm surprised that |
The non-nilable cases fail with a variety of different errors, as you guessed. All the nilable cases fail because they were unable to resolve a call to |
It seems like even back since 1.19 we've only had a This is ostensibly why If we can hash a borrowed object, it seems reasonable to me to be able to hash any other kind of object. I was going to (naively) try adding overloads for other class flavors. For nilable objects, I would emit some form of a halt if a |
I agree with your analysis that this is why the nilable types fail. I'm still unclear why a non-nilable borrowed would pass because doesn't the associative domain that underlies the set allocate an array of Getting back to @daviditen's point above about "couldn't we do the same fake-out that we do for maps?", I think we could for default associative domains (and therefore sets) since they're sort of a standalone type. I think where things get tricky are when it's a domain, array pair (or worse, domain x arrays family) when it's harder because there are essentially 2 (n) things that you have to update simultaneously if you don't have a default value (and our current domain/array interfaces don't tend to have "update the domain and array(s) simultaneously" interfaces).
This sounds good to me.
It's not obvious to me that it should be incorrect to be able to hash a nil value into an associative domain of nilable... Can't we simply treat it as a 0x000000 value from the hash function's perspective? |
Brilliant! I was overthinking it. |
BTW I think that it's reasonable that it behaves that way, because 'new' defaults to meaning 'new owned'. |
I was thinking "Hey, you got your owned in my borrowed!?!" |
But doesn't that go against our recent "memory management flavors can't be stacked / won't simply be ignored" philosophy? And, if I literally replace class T { var x: int = 0; }
proc test(type t) {
var x = new borrowed T?(128);
compilerWarning(x.type:string);
return;
}
type t = borrowed T?;
test(t); |
Agk, Brad beat me to it. I can feel a "why don't we move this discussion to the issue", so I'll go make that real quick. It's clear that the decorator is there and then is being ignored, though... class C { var x: int = 0; }
proc test(type t) {
var x = new borrowed t(128);
compilerWarning(x.type:string);
return;
}
type T = borrowed C?;
test(T);
If the class didn't have a decorator attached to it I would expect an implicit |
Hi @ben-albrecht, here is the state of passing/failing tests for owned T = 🔷 Apologies for the lack of fancy formatting. |
Thanks @dlongnecke-cray! I think in addition to saying where we expect it to land, it's important to say a bit in the slides about what didn't work in 1.22 that arguably should have. |
Branch for set changes is here #15592. |
Branch supporting lists of tuples of non-nilable classes is here: #15618 |
Alright, it's merged. List is in the green! |
So in order to get associative domains of proc add(in i) where isOwnedClass(i.type) && isAssociativeDom(this) {
_value.dsiAdd(i);
} But get a compiler error deep in the bowels of Beyond that, I'm actually confused as to why associative domains of any non-nilable class (such as I'm investigating why associative domains of i.e. borrow are even working right now, but my gut feeling is that this just boils down to the default initialization problem all over again... I feel confident that I could get sets of |
Ah, I had no idea that the entire The problems with owned requiring |
I'm working on cleaning up the initialization issues in #15239 but I have more work to do before we can merge that PR. I don't personally think we should do more workarounds right now and instead I think we should move towards:
|
I agree that associative domains of non-nilable can't / shouldn't be expected to work, at least given the current implementation strategy and don't think that's worth pushing on.
This is what I'd expect us to need to do. Whether or not it's worth it, I'm less certain of. But I think the more we can say "our main high-level collection types support our default class flavor", the better (and, the more we can be consistent across those collection types, also the better). |
I don't want to tread on the toes of @mppf, so I'm going to delegate to him [w.r.t. to his array-coerce branch] and just focus on getting sets of all nilable class types to work first. I'm unsure about whether I should get sets of |
Just a heads up that |
Note that |
In offline discussions with @dlongnecke-cray @daviditen @mppf (and separately with @bradcray), we have concluded that |
…e-shared Support fixed sized arrays of tuples containing non-nilable classes (#16802) Add support for the last failing case in #15394, which is a fixed size array of `(shared C, shared C)`, a tuple containing non-nilable classes. ```chapel class C { var x = 0; } var arr = [new shared C(0), new shared C(1), new shared C(2)]; ``` The above code will call `chpl__buildArrayExpr()` to create the array literal that is used to initialize `arr`. The problem is that the original code would default-initialize the array literal and then assign the elements. The compiler would emit errors about default- initializing non-nilable class tuple elements. Adjust `chpl__buildArrayExpr()` to create an array with `initElts=false` to avoid default-initializing array elements. Then move the elements into place using a primitive. This sidesteps the compiler errors. The parser had to be adjusted to support a varargs formal with a forward pragma list: ```chapel proc chpl__buildArrayExpr(pragma "no auto destroy" in elems ...?k); ``` The parser adjustment is good, but the way the flags are propagated during `expandVarArgs()` is wonky. If others feel the inclination to slap pragmas on varargs formals, the implementation will probably have to be adjusted again. Add code to move-initialize the varargs tuple when the varargs formal has the `in` intent. The "no auto destroy" flag is propagated to all of the formals inserted when the varargs is expanded, so they can be moved into the tuple without worry. This avoids an extra copy caused by `chpl__init_tuple()` that seems to be otherwise unavoidable. Adjust `addLocalCopiesAndWritebacks()` to not add the flag FLAG_INSERT_AUTO_DESTROY to temporaries that have the NO_AUTO_DESTROY flag. This is due to a quirk of how varargs formals are expanded. Adjust `chpl__buildArrayRuntimeType()` to return an array initialized with `initElts=false`. This was required to prevent warnings about default-initialized `(shared C, shared C)` tuples, but does not affect the behavior of array runtime types in any noticeable way. Remove a compiler error embedded in `ReplicatedDist` that triggered due to array literals being initialized with `initElts=false`. The .good files of two tests using Replicated needed to be modified to accept new output, but other than that all tests seem to pass. Check the output of `array-initialization-patterns-dists.chpl` by hand to make sure the behavior of Replicated seems correct. Modify the test to have different .good files for Replicated depending on if `COMM=none` or not. TESTING: - [x] `ALL` on `linux64` when `COMM=none`, `LLVM=none` - [x] `ALL` on `linux64` when `COMM=gasnet`, `LLVM=none` Reviewed by @mppf. Thanks! Signed-off-by: David Longnecker <dlongnecke-cray@users.noreply.github.com>
Fixed size array of |
Is it reasonable to close this issue? If resized arrays of non-nilable are the only part left maybe that should be tracked in a separate issue? |
I think so. Closing now and opening a new issue for resized arrays of non-nilable (@dlongnecke-cray - let us know if you disagree). |
I have created a placeholder issue (#17720) with a subset of the table from this issue, with updates. @dlongnecke-cray will fill in additional details. |
This is an issue for tracking currently supported types in collections based on tests checked into the repository.
Master
✅ = currently works
❌ = currently does not work
🔹 = not expected to work
Changes since 1.22:
list(borrowed T)
andlist(borrowed T?)
are ✅ as of Use workaround to enable lifetime checking for lists of borrowed classes #15575set(borrowed *)
,set(unmanaged *)
, andset(shared T?)
are ✅ as of Addchpl__defaultHash
forborrowed object?
and adjust class tests for set #15592list((shared T, shared T))
is ✅ as of Implement "no init" for tuples to support lists of tuples of non-nilable classes #15618set((shared T?, shared T?))
is ✅ as of Addchpl__defaultHash
forborrowed object?
and adjust class tests for set #15592.map(?t, owned T)
, andmap(?t, borrowed *)
will be ✅ as of Enable maps of non-nilable owned and borrowed #15659(shared C, shared C)
as of Support fixed sized arrays of tuples containing non-nilable classes #168021.22
✅ = currently works
❌ = currently does not work
🔹 = not expected to work
Notes & Caveats
This table assumes a failing case should eventually work unless a reason for not supporting it has been identified. Not all failing cases have been thoroughly diagnosed yet, so there are likely some missing 🔹s in the table.
(shared T, shared T)
and(shared T?, shared T?)
were chosen to represent support for tuples in general to keep the size of this matrix manageable. Future work could explore the larger matrix of combinations including all managed types and possibly combinations of types as tuples."fixed-size array" really means "fixed-size, initialized array", since uninitialized arrays require a default value for their elements.
Tests
These results are based on the following tests:
test/arrays/types/
test/associative/types/
test/sparse/types/
test/types/tuple/types/
test/library/standard/List/types/
test/library/standard/Map/types/
test/library/standard/Set/types/
Error messages
See the corresponding
.bad
files in the above directories for current error messages. Also see this gist for all error messages as of 1.22 release.🔹 cases:
owned T
for map provides a good error message in 1.22The text was updated successfully, but these errors were encountered: