-
Notifications
You must be signed in to change notification settings - Fork 428
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
Allow 'c_ptrTo' be allowed for remote data? #26750
Comments
If we want to allow it, this patch will do it: diff --git a/compiler/passes/insertWideReferences.cpp b/compiler/passes/insertWideReferences.cpp
index e0119e3d08f..f031153e390 100644
--- a/compiler/passes/insertWideReferences.cpp
+++ b/compiler/passes/insertWideReferences.cpp
@@ -1475,6 +1475,9 @@ static void insertStringLiteralTemps()
static void narrowWideClassesThroughCalls()
{
+ const char* c_pointer_return = astr("c_pointer_return");
+ const char* c_pointer_return_const = astr("c_pointer_return_const");
+
//
// Turn calls to functions with local arguments (e.g. extern or export
// functions) involving wide classes
@@ -1531,7 +1534,11 @@ static void narrowWideClassesThroughCalls()
// Insert a local check because we cannot pass narrow references to
// remote data to external routines
- if (!fNoLocalChecks) {
+ if (!fNoLocalChecks &&
+ // but allow this for c_ptr_return/c_ptr_return_const
+ // as these are used for c_ptrTo
+ fn->name != c_pointer_return &&
+ fn->name != c_pointer_return_const) {
if (fn->hasFlag(FLAG_EXTERN))
stmt->insertBefore(new CallExpr(PRIM_LOCAL_CHECK, sym->copy(), buildCStringLiteral(astr("references to remote data cannot be passed to external routines like '", fn->name, "'"))));
else if (fn->hasFlag(FLAG_EXPORT)) |
This is really intriguing… I'm open to it and find the motivation motivating. This seems thematically somewhat related to:
though, somewhat ironically, my open-ness to this issue's proposal somewhat contradicts my thinking about #21220 and #26710 in which I was thinking that we should disallow c_ptr dereferences on locales other than the one on which the Some other approaches we could consider if this hesitation resonates, or others aren't as wild about loosening the current behavior:
|
The workaround that I'm aware of is ugly: define and use these instead of proc addrOf(const ref p): c_ptr(p.type) {
return __primitive("_wide_get_addr", p): c_ptr(p.type);
}
proc addrOfConst(const ref p): c_ptrConst(p.type) {
return __primitive("_wide_get_addr", p): c_ptrConst(void) : c_ptrConst(p.type);
} |
An additional tidbit, which might not matter, but might not be obvious, is that the reason that we are checking this at all today is that
Haven't re-read those issues but IMO it's OK if C pointers are low level and can cause core dump. They already are that way, so why should we be trying to protect people from them in this regard?
IMO the difference between these has nothing to do with whether or not it's reasonable to allow a remote pointer. So I think they should be the same in this regard.
Sounds plausible, if a bit wordy. Personally, I'm more inclined to stop checking for
I think we absolutely need a Chapel wide pointer type. I'm sure there is an issue about it. Today we use Note that it would only solve the motivating case in this issue if we also significantly changed the API for Also, I think it's theoretically possible that somebody would want to pass a C pointer to remote data to an |
Definitely not obvious to me, thanks for pointing that out.
On one hand, I completely agree with you. On the other hand, I feel like when users with a high-level, non-C/SPMD/HPC profile hit this type of issue, they are very confused and somewhat frustrated that we either didn't magically make their pointer work remotely, or protect them from it somehow. All that said, if we had the Chapel pointer type and encouraged most users to use that in most cases, and it provided the safety and/or transparency that such users wanted, I'd have no qualms about proceeding with this proposal. Which suggests to me that we probably should (especially since we don't have any plans to implement safety features around
👍 That was my thinking as well.
There's at least #8680 but I know we talked about it more recently when stabilizing the CTypes module, though I'm not finding an issue from that era. Anyway, I didn't mean to imply that I thought I was proposing something new if it came across that way.
I'd pick
I was imagining the Chapel pointer type would have the ability to query the
That's a good point. One trivial case might be if they wanted to use printf()s from Chapel to debug their remote C pointers. I'd be curious what @riftEmber , @e-kayrakli , and @jabraham17 think about this as people who've been involved in implementing the routines and the issues linked above. |
I like the proposal here. The linked issue, #22755, does not call what's proposed here as an option, but I think it can be a nice solution. |
I feel we shouldn't allow
I view allowing |
Thanks for taking a contrary position, Anna! Here's my rebuttal now that Michael has gotten me off of the initial fence I was sitting on:
They are for that, but I'd add "but not just for that" — they're also for representing C types in Chapel code. Since some Chapel routines (like, in this case, the Communication routines) require C types, there are cases where a user would want to use revcomp9.chpl is another example of an important program that uses C pointers, not for interoperability, but because they permit inherently unsafe things for which there's no alternative in Chapel today (and maybe there never will be since it effectively uses them for type punning, which I'd guess we may want to disallow for Chapel pointers). That said—as noted earlier—the Communication module is unstable and would definitely be more Chapeltastic if it accepted a native Chapel pointer type, once we have one. But since we're not there yet...
True, but there's arguably also not a C equivalent to taking a pointer to a Chapel array or string, yet we support those things. Basically, I think of config const iWantAnError = false;
var x: int;
var p = c_ptrTo(x);
on Locales[1] {
var p2 = p;
if iWantAnError then writeln(p2.deref());
}
writeln(p.deref()); which I can't do in C, but that doesn't imply to me that we shouldn't permit it.
I don't know if I'd go so far as to say it will make more sense (e.g., maybe I want to store a remote address as a field in my record and don't want to spend the two ints that a Chapel pointer would require), but I agree that it'd be preferable. And, going further, I'll say that I believe that once we have Chapel pointers, programs that use them over
This resonates with me because it's where I started, but I was pretty heavily convinced by Michael's argument that C is an inherently unsafe language, and its pointers one of the more unsafe aspects, so it doesn't feel to me like we should bear the burden of making them safer than they are—Chapel pointers should be the safe option. Also, since there are workarounds to this issue, like: var A = BlockDist.createArray({1..n}, real);
var p: c_ptr(int);
on Locales[1] {
var mylo = A.myLocalSubdomain.low;
p = c_ptrTo(MyBlockArr[mtlo]);
}
… do something with p … it's not as though a user can't take a pointer to a remote variable today, they just have to go to a lot more trouble to do it. Not only do today's workarounds involve more typing, but they will also likely be more expensive since we can often know where a remote variable or array element lives without communicating back to the remote locale. For example: var x: int;
on Locales[1] {
x + = 1; // we know x's address by virtue of it being passed into the active message implementing the on-clause
...c_ptrTo(x)… // so could compute this without communicating back to locale 0
}
I sort of agree with this, but sort of don't. I'd probably say that if we had a wide pointer type, we should avoid using So summarizing, my stance is:
|
True, I agree they're not just for C interop. I don't see the Communication routines using
I didn't think of Though technically a
I didn't think about wanting to use a narrow pointer to save space, that's a good point. I think it might be worth considering also introducing a Chapel narrow pointer type, but that's a separate conversation, and I wouldn't be that against leaving I guess having
The points I made about semantics and safety are sort of overlapping for me, but essentially I think we shouldn't add a new what I consider a new "class" of unsafety without requiring the user to do it explicitly. The example of getting a remote pointer today is explicitly going across locales so I don't have an issue with it on those grounds.
That is a good point and definitely a downside of not allowing I think where I'm landing on this is though I could live with |
Summary of Problem
Description:
When working with the Communication module (or other low level programming) one might wish to work with a
c_ptr
to memory on another locale. However, that is currently disallowed by a runtime check (so it is allowed with--fast
).Is this issue currently blocking your progress?
No
Steps to Reproduce
Source Code:
Compile command:
chpl bb.chpl
in a multilocale configExecution command:
./bb -nl 2
Associated Future Test(s):
TODO
Configuration Information
gasnet+quickstart
The text was updated successfully, but these errors were encountered: