Array promotion of scalar functions

From the spec ... "Arrays may be passed to a scalar function argument whose type matches the array’s element type. This results in a promotion of the scalar function as defined in Promotion.

It would be good at that point to have an example.

Looking for an example, one might click on Promotion, at which point you are instantly dropped a discussion of rules where what I was looking for was an example. Eventually, you do find an example but I found my head was spinning from all those rules. A simple example within the spec where it was talking about arrays would be really useful. If I knew enough I would write it.
I know I tried to get that working years ago on some overloaded routine I had but I failed. I was very pleasantly surprised when a recent routine I wrote worked with it. So I am not sure I know enough to write the (say) two examples within the Array spec. Just a thought.

1 Like

Hi Damian —

I'd suggest filing an issue for this, as it sounds straightforward and that's the best way to turn a suggestion into a potential action item.

As some background here, when we originally did the spec, a portion of the team was opposed to putting examples into it, considering a spec to be more of a legal, rather than friendly, document, and that may be why there is a lack of examples in this specific section. That's not an excuse, though, as we obviously do have a lot of examples in the spec, and nobody recently has expressed hesitancy to adding more. Just some historical context for why we may be in this position currently.

In the meantime, there's a much friendlier and more example-driven description of promotion in the (long-stalled) user's guide here, and that may check the box for people looking for this sort of thing today: Promotion: implicit data parallelism — Chapel Documentation 2.3

-Brad

I have just one thing to add real quick. A common reason that promotion does not work when one might want it to is if the function you are calling is fully generic. For example if you want to promote over an array, the function can't accept an array, otherwise it'll just pass the array.

here is an example, where passing an array to all of these except g3 will lead to promotion:

proc f(arg: int) {
  compilerWarning("f with " + arg.type:string);
  return 2*arg;
}
proc fr(arg: real) {
  compilerWarning("fr with " + arg.type:string);
  return 2*arg;
}


proc g1(arg: int(?w)) {
  compilerWarning("g1 with " + arg.type:string);
  return 2*arg;
}
proc g2(arg: integral) {
  compilerWarning("g2 with " + arg.type:string);
  return 2*arg;
}
proc g3(arg) {
  compilerWarning("g3 with " + arg.type:string);
  return 2*arg; // when called as g3(Array), this is a promoted call
}

config const n = 10;
var A: [1..n] int = 1..n;

var B = f(A); // promotion
writeln(B);

var C = fr(A); // promotion including implicit conversion
writeln(C);

var D = g1(A); // promotion
writeln(D);

var E = g2(A); // promotion
writeln(E);

var F = g3(A); // passes the array to g3, and promotion occurs within
writeln(F);

compilation output (ideally it wouldn't print the duplicate lines, let's ignore those here):

aa.chpl:1: In module 'aa':
aa.chpl:27: warning: f with int(64)
aa.chpl:27: warning: f with int(64)
aa.chpl:30: warning: fr with real(64)
aa.chpl:30: warning: fr with real(64)
aa.chpl:33: warning: g1 with int(64)
aa.chpl:33: warning: g1 with int(64)
aa.chpl:36: warning: g2 with int(64)
aa.chpl:36: warning: g2 with int(64)
aa.chpl:39: warning: g3 with [domain(1,int(64),one)] int(64)

runtime output:

2 4 6 8 10 12 14 16 18 20
2.0 4.0 6.0 8.0 10.0 12.0 14.0 16.0 18.0 20.0
2 4 6 8 10 12 14 16 18 20
2 4 6 8 10 12 14 16 18 20
2 4 6 8 10 12 14 16 18 20
1 Like

Brad. Thanks for the pointer to the user guide. I will likely find what I want there.

Michael, your words show why most of my routines never work this way. I generally always write them as generic so they work for real(32) as well as they work for real(64).

Thanks for all the information.

1 Like