Open skyreflectedinmirrors opened 7 years ago
cc @mattwala
min(i, ...)
is a reduction. So, technically, the iname it reduces over (i
) does not exist at its output. So this is all as designed. No bugs, just insufficient docs.
I think what @arghdos is saying is that min is also a builtin function in OpenCL which is defined by the function manglers in loopy, and that the "reduction" interpretation is masking the "function" interpretation.
Somewhat tangential: This issue also brings up the point that the syntax for reductions is a bit confusing, because the first parameter looks like a variable. Maybe it's time to consider another syntax for reductions (maybe min<i>(...)
)?
min<i>(...)
: I'm open to it, although we'd need to accept both types of syntax for a transition period.
I think what @arghdos is saying is that min is also a builtin function in OpenCL which is defined by the function manglers in loopy, and that the "reduction" interpretation is masking the "function" interpretation.
I see. numpy
's solution is to use min
and minimum
, so my thinking is that we would follow its lead.
@mattwala that's correct. Even using min(3, 4)
(i.e. no inames at all) results in the same error.
numpy.minimum
refers to an element-wise minimum of two arrays, which could be interpreted as the minimum of two arrays of size one (i.e. OpenCL
's min). numpy.min
is similar to the min
reduction currently implemented.
I might be inclined towards the min<i>(...)
syntax for clarity in all reductions
The uncomfortable decision beneath all this is what the function namespace in loopy should actually be.
I'm leaning towards the third with some measure of the first.
One somewhat explicit form of the first would be accepting min$tgt()
or min$cl()
as explicitly target-specific function calls as a start. I don't really want to change the (existing) meaning of min
. I'm OK exposing OpenCL's min
as minimum
following numpy
as a loopy-lang thing.
How do you guys feel about this proposal?
Well, FWIW I've switched to an adding a fmin
\ fmax
function mangler which works fine. I guess that would be an example of the first form - although, reasonably general as it should apply to all C-based targets. I agree that changing the current meaning min
would be a bad idea (breaking a whole bunch of current code).
I don't love the explicit min$cl()
as it breaks the ability to easily change between targets---unless min$tgt()
would be general, and adapt to whatever target is specified? but in that case it's not really the first case anymore is it?
I think the most sensible choice is to pick a (very) small number of simple math functions (min, max, abs, pow, exp, etc.) to implement in our own namespace. Honestly, the only functions that absolutely need to be done this way are min and max, although we may want to include more for the sake of consistency? It's fairly simple to add other functions that exist in the target via the mangler (although, I think at some point I'll try to add an example to the docs).
I'm fairly indifferent to the syntax used there, although I think that min$tgt()
might make more sense than maximum()
, simply because it explicitly tells you that something's going on in loopy more clearly differentiating the min
reduction from the min
target call
Yeah, I agree that min$cl()
doesn't make a lot of sense. I'm not loving minimum
vs min
either, but there's at least precedent for it (in numpy), and IMO numpy is at least a reasonable thing to align with name-wise.
I imagine with time we'll do a combination:
xyz$cl()
.minimum
et al. will be part of that set.This was a helpful discussion at least as a cautionary matter before I let even more CL semantics "leak" into loopy. :)
@inducer and I were discussing a related issue and think that dotted namespaces might be useful here. The context was that I wanted to use pymbolic's math functions (e.g., Lookup
s to math
) for differentiation but found that loopy doesn't know what to do with a Lookup
. Certainly smoothing this out would be nice regardless, but dotted namespaces are certainly unambiguous and pythonic - what do you all think?
Sorry about the many pull requests / issues today! Been playing around with reductions, and breaking things in all sorts of interesting ways :)
Here's a fun one:
Results in:
However,
works as expected (both are defined in the opencl function manglers).