Thread Links Date Links
Thread Prev Thread Next Thread Index Date Prev Date Next Date Index

Re: Motion P1788/M0008.01_Exception_Handling



John Pryce wrote:
> Marco, Juergen, Nate, P1788 members
>
> I find the flagspace idea definitely interesting. I have some further
> questions about the "decoration" approach:
>
> Nate Hayes wrote:
>> Note that if yy is a 100 element vector, it is normal in vector
>> operations
> that evaluating
>    yy <= 0
> requires 100 component-wise evaluations of yy. In this regard, the
>    fact that isValid( yy )
> requires 100 component-wise examinations of yy elements does not seem
> to
> me poor design; it is just status-quo for vector operations. Along
> these lines,
> I think your example breaks the syntactic model one would generally
> expect
> from a vector library. ...
> -----
>
> Not really. The vectorisation I described happens along a dimension
>   orthogonal to xx and yy, the one indexed p=1..P. It just happens
> that xx and yy are vectors in my (notional) function yy=ff(xx). But
> it might have been, using Matlab syntax...

I understand all this. Since xx and yy are orthoganal, FLAG is just the
alias for isValid( yy ), which is the component-wise examination of all
yy(1), yy(2), ... yy(n) elements of yy. This is why it does break the normal
syntactic model, because at the most basic level the user must write:

    if ( FLAG.isValid ) {
        ...
    }

in their code instead of

    if ( isValid( yy ) ) {
        ...
    }

which would be normal syntax.




> [yy1,yy2] =
> ff(xx1,xx2,alpha)
> say, where the xx's and yy's are interval scalars and alpha is a real
> scalar. For definiteness suppose the body of ff says (*)
>   uu = xx1.^alpha + xx2.^alpha;
>   yy1 = xx1./uu;
>   yy2 = xx2./uu;
> Again I have used Matlab notation, with ./ meaning element-wise
> division, etc. Addition is automatically element-wise.
>
> My points are
> 1. The vectorisation replicates this over each "SIMD thread" p = 1 to
>  P. However this is done by the library. The user writes the code (*)
>  and the effect is
>   for p=1:P
>      uu(p) = xx1(p)^alpha(p) + xx2(p)^alpha(p);
>      yy1(p) = xx1(p)/uu(p);
>      yy2(p) = xx2(p)/uu(p);
>   end
>
> I could have merged xx1, xx2 into a vector of length 2, in which case
> the code for (*), in Matlab notation, would change to (**)
>   uu = xx(1,:).^alpha + xx(2,:).^alpha;
>   yy1 = xx(1,:)./uu;
>   yy2 = xx(2,:)./uu;
> (assuming the SIMD-dimension of xx is chosen to be the second
> dimension). One could do the same to yy1, yy2.
>
> 2. Each SIMD thread needs its own flag(s). As in my previous, I speak
> of one flag per thread that plays the role of "possiblyUndefined".
> These form an array indexed over p=1:P, that I call FLAG.
>
> Any line of the code above could set some elements of FLAG, depending
> on the inputs.
>
> 3. It is inherent in my view of things that FLAG does not belong to
> any one of the six "actors" xx1, xx2, alpha, uu, yy1, yy2; nor to any
> one expression or assignment statement. Instead, each element FLAG(p)
> belongs to the p-th thread.
>
> 4. The library is not written by the user. Somehow, there must be a
>    way to tell the library, as part of the definition of the
> vectorised ff, that as code (*) is executed, if "possiblyUndefined"
> occurs in any of the 3 lines of (*), for a specific p value, then
> FLAG(p) must be set.

I understand all these points, too. Since in this particular SIMD
computation all elements are orthogonal, there is just one FLAG.

However, this is also why in the lager scheme a FLAG model breaks natural 
syntax as well as a truly object-oriented design.


>
> Nate Hayes wrote:
>> However, an object-oriented design might be able to salvage the
>> model by introducing the notion of a "decorated interval vector",
>> e.g.,
>    class DecoratedIntervalVector< N > {
>        public:
>    Interval inv[N];
>    Decoration dec;
>    };
>    DecoratedIntervalVector< n > yy[P];
> Now the compiler has something to possibly work with to make the FLAG
> model more natural in its vector-like syntax. -----
>
> Nate, I do not see how your "DecoratedIntervalVector" class comes
> anywhere close to meeting this spec. For my example above, it seems
> one needs to write a new "DecoratedPairOfIntervals" class that holds
> yy1, yy2, and a decoration.

This is a DecoratedIntervalVector!


> That is, you need to write a new class,
> for each pattern of output parameters that occurs in vectorised
> functions in the user program.


No.




>
> And, if YY is the instance of this class that forms the actual output
> argument to the vectorised function, you need a way to tell the
> library "Use the vector formed by the fields YY(p).dec, p=1:P, as the
> FLAG vector when calling my function ff".

This is *precisely* what I mentioned in my last e-mail, that if v.dec is
aliased to some decoration representing the local flagspace this result is
obtained.

> Doubtless possible, but neither easy nor neat.

I believe Juergen, Marco and Stefan show it is possible, easy and neat by
using flagspace. Combining flagspace and DecoratedIntervalVector should in
principle allow the natural vector syntax to be used, too.


>
> On the other hand, the flagspace approach seems closer to offering
> what I am asking for. Of course things are usually easier when one
> allows oneself a language extension! I also have some questions about
> the approach, of which more later.

I think an important point is being lost in this discussion: by now, we have
considered at least half-dozen implementation strategies for cases where
FLAG might provide some benefit. They all have some advantages and
disadvantages; but we also haven't even begun to consider the
implementations that would actually be *harmed* by requiring the FLAG
approach. In my view, this shows how important it is to give implementors
the widest lattitude possible by keeping the abstraction decoupled from the
implementation.

Motion 8 only provides the abstraction. It specifically mentions, for
example, that decorated intervals have no concrecte representation format.
This means implementors are free to implement decorated intervals in a
literal sense or a conceptual sense. As long as the semantics are the same,
it doesn't matter what is the implementation mechanism. For example, FLAG,
if it exists, is always equivalent to isValid( yy ). So all that is
necessary in 1788 is to standardize what isValid( yy ) should be. Anything
more than this represents a tight-coupling of 1788 to some particular
implementation.

Nate Hayes