jsmeredith / EAVL

Extreme-scale Analysis and Visualization Library
http://ft.ornl.gov/eavl/
Other
19 stars 10 forks source link

need equivalent of counting iterator -- new eavlMap with index passed in to functor? #10

Open jsmeredith opened 10 years ago

jsmeredith commented 10 years ago

What if you wanted to write a functor that output its index in the array?
Or a more concrete example: suppose you wanted to fill an array of X coordinates for a grid where x[n] = 100*n + 10? This is trivially data-parallel, but we don't pass the index of the current item into our Map functors.

I think maybe the right thing is to add a new eavlMapOp variant that passes in the index as another value to the functor. (While it would be trivial to add this to the current eavlMapOp, I think that might be a bad idea because every existing functor, none of which use that index value, would now have to be changed to accept it. Not sure it's a performance problem, but pretty sure it's uglier.)

Some thought about whether it's more than just map ops that need this, though, and whether or not there's a more general solution? (a) sure, why wouldn't a topology map functor potentially want its index? (b) we could have all functors derive from a base class that lets you set the index, but wow that's a bad idea for various reasons. (c) here's what i want to explore: maybe we generally want an "iterator" concept, like an eavlArray, which is basically a functor which can be passed in instead of an array? e.g. in our kernel code, we shouldn't call INPUT[a], we should call INPUT->GetElement(a), which is trivially inlined for array types and calls a function for iterator types. This would be awesome, but we're back to a little more template messiness and so on. Another option is some simple version that is a placeholder that you insert in place of an array, and it does the same thing. Similar concept, but it lets your functor do the same thing instead of having to write a separate functor just for the iterator. (This last option is the best, but is some work.)

jsmeredith commented 10 years ago

Upon further review, I like (c). Here's what I'm thinking:

  1. a new concrete type of array (say, eavlImplicitArray : public eavlArray) which has exactly two values: an origin and a delta
  2. change eavlCollect to instead of calling indexable.array[indexable.index(i)], call a new method, indexable.getvalue(i) that does the same thing. As long as this is not virtual, we're fine performance-wise, just make it EAVL_HOSTDEVICE or whatever to inline it.
  3. make a specialization of eavlIndexable for this implicit array type that instead of returning array[index(i)] always returns array[0] + i*array[1].

That's about it. This may not be quite as simple as it sounds, though, because there could be some issues. E.g. it''d be great if eavlImplicitArray has only two data members, not a dynamically allocated host/device array, but the base class eavlArray has a lot of virtual functions like GetCUDAArray. So maybe there needs to be some change in the hierarchy. Alternatively, eavlImplicitArray is not part of the eavlArray hierarchy at all, but I think that might get a little messier.

Plus, I think this can be used to create true regular (not rectilinear) grids; since we won't need eavlCoordinateAxisRegular, we can collapse eavlCoordinateAxisField into the base eavlCoordinateAxis, and get rid of all the related dynamic casts.

ahernsean commented 10 years ago

Side question: How does Dax handle this?

-Sean

Sean Ahern Oak Ridge National Laboratory 865-408-8463

On 24 Jan 2014, at 10:43 AM, Jeremy Meredith notifications@github.com<mailto:notifications@github.com> wrote:

Upon further review, I like (c). Here's what I'm thinking:

  1. a new concrete type of array (say, eavlImplicitArray : public eavlArray) which has exactly two values: an origin and a delta
  2. change eavlCollect to instead of calling indexable.array[indexable.index(i)], call a new method, indexable.getvalue(i) that does the same thing. As long as this is not virtual, we're fine performance-wise, just make it EAVL_HOSTDEVICE or whatever to inline it.
  3. make a specialization of eavlIndexable for this implicit array type that instead of returning array[index(i)] always returns array[0] + i*array[1].

That's about it. This may not be quite as simple as it sounds, though, because there could be some issues. E.g. it''d be great if eavlImplicitArray has only two data members, not a dynamically allocated host/device array, but the base class eavlArray has a lot of virtual functions like GetCUDAArray. So maybe there needs to be some change in the hierarchy. Alternatively, eavlImplicitArray is not part of the eavlArray hierarchy at all, but I think that might get a little messier.

Plus, I think this can be used to create true regular (not rectilinear) grids; since we won't need eavlCoordinateAxisRegular, we can collapse eavlCoordinateAxisField into the base eavlCoordinateAxis, and get rid of all the related dynamic casts.

— Reply to this email directly or view it on GitHubhttps://github.com/jsmeredith/EAVL/issues/10#issuecomment-33233182.

robertmaynard commented 10 years ago

dax array handle class has the concept of container type which can be specialized to handle implicit arrays such as constant value, counting value, and so forth.

Currently dax provides the following 'fancy' array handles:

  1. CountingArrayHandle. Takes in an instance of T, and a count. T can be a primitive type like integer, or a user defined type that has the prefix,postfix, and equal operator, and is copyable.
  2. ConstantValueArrayHandle. Takes in an instance of T and a count. Returns the instance of T for all access between 0 and count.
  3. PermutationArrayHandle. Takes a user defined functor, an ArrayHandle and return type T, lazily applies functor on elements of the array handle. The length of the array is defined by the input ArrayHandle.
  4. ImplicitArrayHandle. Takes a user defined functor and return type T, lazily returns the result of the functor which must be type T. The functor must be a unary functor which is given the index in the array it represents.