View mode: basic / threaded / horizontal-split · Log in · Help
January 28, 2007
Re: seeding the pot for 2.0 features [small vectors]
Chad J wrote:
> 
> The only computers I know of that lack float4 are smartphone and PDA 
> type devices running modern ARM processors.  Even some of the recent 
> ARM-XSCALE processors have MMX instructions, which doesn't give float4 
> but does give short4 and int2.  I'm also not sure about modern 
> supercomputers and the like, since I haven't worked with those.

Actually, newer ARM devices support the NEON/VFP instruction set 
extensions, which provides SIMD capabilities similar to SSE.  It is 
strange that most modern ISA's have better support for geometric vectors 
than higher level programming languages...


-Mik
January 28, 2007
Re: seeding the pot for 2.0 features [small vectors]
Mikola Lysenko wrote:
> Helix is not a bad project, but in order for a standard vector to be 
> useful it needs to come packaged with the compiler.  The temptation to 
> roll your own is too great otherwise.  Even putting it in the standard 
> library is not enough to prevent people from reinventing the wheel, as 
> we have seen by the numerous variations on C++'s std::list.  Ideally, 
> small vectors should be in the global namespace, right alongside complex 
> numbers and dynamic arrays.

Hmmm…  D’s complex types seem to be syntactic sugar over a construct 
much like C++’s complex template.  I’d think that a template library 
ought to come first, with incorporation into the language later.

> Effective vector code needs correct data alignment, instruction 
> scheduling and register use.  Each of these issues is most effectively 
> handled in the compiler/code gen stage, and therefore suggests that at 
> the very least the compiler implementation ought to be aware of the 
> vector type in some way.  By applying the "D Builtin Rationale," it is 
> easy to see that vectors meet all the required criteria.

As I understand it, D’s inline assembler would be the tool to use for 
this in a library implementation.  I don’t think the complex types use 
SIMD, so the vectors can be the only things using those registers.

> An optimal strategy would be to have the vector types builtin, with a 
> simple per-component multiplication defined, and a separate standard 
> math library for doing more complex operations.  Here is an example:
> 
> import std.vecmath;
> 
> float4 a = [1, 2, 3, 4];
> float4 b = [2, 3, 4, 5];
> float4 c = a * b;        //c = [2, 6, 12, 20]
> float  d = dot(a, b);        //Defined in std.vecmath

Considering that the primary vector types for physics or 3-D animation 
are 3-tuples (v ∊ ℝ³) and Hamiltonian quaternions (q ∊ ℍ or q ∊ ℝ⁴), and 
by extension with the complex types, how about a v prefix for 3-tuples 
and an h prefix for quaternions:
	vfloat v = [1, 2, 3];	// vfloat ≈ float3
	hreal q = [2, 3, 4, 5];	// hreal ≈ real4
and the additional operators needed to handle them “right”:
	vfloat a = [1, 2, 3];
	vfloat b = [2, 3, 4];
	vfloat p = a*b;	// element-wise product, [1*2, 2*3, 3*4]
	float d = a•b;	// dot product, [1*2 + 2*3 + 3*4]
	vfloat c = a×b	// cross product
Some notation for inverses (a postfix operator ⁻¹, perhaps) and notation 
for 3×3 and 4×4 matrices would be useful too, along with defining the 
dot and cross product for the complex numbers…

… or this can all go in a library until the interface and implementation 
are well defined and understood.

I’m only just learning the language and I’m watching it grow.

--Joel
January 29, 2007
Re: seeding the pot for 2.0 features [small vectors]
Chad J wrote:
> Bill Baxter wrote:
>> Mikola Lysenko wrote:
>>
>>> I'll bite.  Here are the two features I consider most important:
>>>
>>> 2. Low dimensional vectors as primitive types
>>>
>>> Specifically I would like to see the types int, real, float etc. 
>>> extended into 2-4 dimensional vectors.  ie. int2, real4, float3.
>>>
>>> This would be exceptionally useful in many applications which require 
>>> coordinate geometry.  Here is a very brief list:
>>>
>>> Scientific Programs
>>> Physics Simulation
>>> Computer Graphics
>>> Video Games
>>> User Interfaces
>>> Computational Geometry
>>> Robotics
>>> Fluid Simulation
>>
>>
>> It's still a tiny fraction of the number of applications that use, 
>> say, strings.  So the ubiquity argument for inclusion is pretty weak, 
>> I think.
>>
> 
> What applications don't use vector instructions?

Business applications?  I'm not sure what you mean exactly.  But the 
question is not so much does app xyz use vector instructions, but rather 
would the programmer of app xyz have benefited from having int2/3/4 or 
float2/3/4 type primitives.

> Also, I think it's more important to consider what /D applications/ will 
> be using SIMD instructions, rather than what applications in general do 
> or do not use coordinate geometry.  That's because a lot of those 
> applications may not even be written in D or have anything to do with D, 
> like the mass of stuff written in dynamic languages like perl, python, 
> ruby, etc.

Well judging from posts around here it seems like web programming folks 
and DB users make up a significant percentage of active D users.  But 
gamers and scientific folk are another significant group it seems.

> I have to wonder, has any language out there really given good support 
> for SIMD primitives, besides assembly?  I think D could stand a lot to 
> gain here.  That said, I don't mind if it's done in a library as long as 
> it looks polished and is not cumbersome.

Agreed.

--bb
January 29, 2007
Re: seeding the pot for 2.0 features [small vectors]
Mikola Lysenko wrote:
> Bill Baxter wrote:
>> Mikola Lysenko wrote:
>>> 2. Low dimensional vectors as primitive types

"Vectors are more common than complex, and complex is built-in".

This is a good argument.  Although, there seem to be a number of things 
out there that are more common, or least as-common as 'complex'.  For 
instance, there's a contingent here that wants to see decimal arithmetic 
supported in the core.  There was a strong push for regexp to be in the 
core for a while.


"Most CPUs today have *some* kind of SSE/Altivec type thing"

That may be, but I've heard that at least SSE is really not that suited 
to many calculations -- especially ones in graphics.  Something like you 
have to pack your data so that all the x components are together, and 
all y components together, and all z components together.  Rather than 
the way everyone normally stores these things as xyz, xyz.  Maybe 
Altivec, SSE2 and SSE3 fix that though.  At any rate I think maybe 
Intel's finally getting tired of being laughed at for their graphics 
performance so things are probably changing.


"Library vs Core"

I think there's really not much that you can ask from the core.  A small 
vector of 4 numbers can represent any number of things.  So I think your 
best hope for the core is to support some very basic operations on small 
vectors -- like component-wise +,-,*,/, and dot product -- to optimize 
those kind of expressions as best as possible, and leave everything else 
to libraries.  I guess that's pretty much how it works with HW shader 
languages.  Except they add swizzles to the set of primitive ops.


So what you're left with would be satisfied in large part by just having 
vector math work on small static arrays (and be optimized well).

     float[4] v = a*b + c*d;

you can even make aliases if you like.

     alias float[4] float4;

But your 3D graphics library will still need to be a library on top of that.

Good news is that I think vector math like the above is something that 
Walter is interested in adding to the language at some point.  Bad news 
is that noone knows when that will be.   I'd guess though that a 
kick-ass vector expression optimizer would be a long way off, judging by 
how hard it's been for C++ compilers to get SSE type optimizations 
implemented.


"Getting it in the standard library"

I agree, though, that lo-D math is common enough that it should be 
included in a standard library.  I wonder if the Tango developers would 
be willing to include a vector math class...or if they already have one 
in there.

I'd certainly like to be a contributor to that if so.

--bb
January 29, 2007
Re: seeding the pot for 2.0 features
Wolfgang Draxinger wrote:
> A quite cool feature was something similair to Python's
> __getattr__, __setattr__ special functions.
> 
> So if one writes
> 
> class foo
> {
>         ... // foo does not declare a function or member bar
> 
>         // special operators do not return anything
>         opGetAttr(out T val, char[] identifier);
>         opSetAttr(in T val, char[] identifier);
> };
I think this could be a great feature, but be better as a template, 
because compile-time variables can be accessed at runtime, but not vice 
versa. Also remember that properties can mimic member variables, so 
supporting member functions should be enough. For any arbitrary call like
   foo.bar(a, b, c);
the compiler would then follow the following law: if no member 'bar' is 
found that overloads satisfactorily, try rewriting it to
   foo.opFakeMember!("bar")(a, b, c);
and see if a satisfactory overload can be found.

This would allow more things, yet often keep the overhead restricted to 
compile time.  For instance, you could use this to generate 'swizzling' 
functions, as discussed in the 'small vector' thread above, or generate 
conversions to all possible color spaces (rgba, bgra, etc):

struct MyVector
{
   template opFakeMember(char[] ident)
   {
      static if (ident[0..7] == "swizzle" && ident.length == 11)
          alias swizzle!(ident[7..11]).swizzle opFakeMember;
   }

   MyVector swizzle(char[] order)()
   {
      // Do some more template meta-programming to generate a swizzle
   }
}

And, having it as a template doesn't exclude transmitting the identifier 
at runtime:

class MyDynamicPythonClass
{
   void* opFakeMember(char[] ident)()
   {
      return runPythonLookupToGetThisVariable(ident); // Run at runtime
   }

   void opFakeMember(char[] ident)(void* foo)
   {
       setPythonVariable(ident, foo); // Run at runtime
   }

   unittest
   {
      auto test = new MyDynamicPythonClass();
      test.bar = 5; // Property syntax allows variable mimicry;
      writeflln(test.boom);
   }
}

Cheers,

Reiner
January 29, 2007
Re: seeding the pot for 2.0 features
I think something like a 'super static' function could also be good 
(just to avoid using new keywords ;-) ). The idea would be that plain D 
code could be called by template functions, and the compiler would 
evaluate them at compile-time.

As I see it, there are only a few requirements for this (which are 
recursive across all functions called):

  1. the source code is available
  2. there's no assembly or C (or any external library) called
  3. the functions are pure (ie no static variables are read or 
changed, and the passed parameters are unchanged)

This would mean, for instance, that practically all of std.string would 
be accessible via templates, avoiding the much of the need for separate 
meta-programming libraries. You could then just call such functions 
straight from your template code:

import std.string;

template foo(char[] bar)
{
    static if (bar.splitlines()[0] == "cheese")
        pragma(msg, "You like cheese");
}


The compiler can check whether a function can be evaluated at 
compile-time, and you may wish to ensure that yours is, since you are 
writing it for template code. In that case, you annotate your function 
'super static' and the compiler will give you an error if it fails any 
of the three criteria.

Cheers,

Reiner
January 29, 2007
Re: seeding the pot for 2.0 features [small vectors]
Bill Baxter wrote:
> Mikola Lysenko wrote:
> 
>> Bill Baxter wrote:
>>
>>> Mikola Lysenko wrote:
>>>
>>>> 2. Low dimensional vectors as primitive types
> 
> 
> "Vectors are more common than complex, and complex is built-in".
> 
> This is a good argument.  Although, there seem to be a number of things 
> out there that are more common, or least as-common as 'complex'.  For 
> instance, there's a contingent here that wants to see decimal arithmetic 
> supported in the core.  There was a strong push for regexp to be in the 
> core for a while.
> 
> 
> "Most CPUs today have *some* kind of SSE/Altivec type thing"
> 
> That may be, but I've heard that at least SSE is really not that suited 
> to many calculations -- especially ones in graphics.  Something like you 
> have to pack your data so that all the x components are together, and 
> all y components together, and all z components together.  Rather than 
> the way everyone normally stores these things as xyz, xyz.  Maybe 
> Altivec, SSE2 and SSE3 fix that though.  At any rate I think maybe 
> Intel's finally getting tired of being laughed at for their graphics 
> performance so things are probably changing.
> 
> 
> "Library vs Core"
> 
> I think there's really not much that you can ask from the core.  A small 
> vector of 4 numbers can represent any number of things.  So I think your 
> best hope for the core is to support some very basic operations on small 
> vectors -- like component-wise +,-,*,/, and dot product -- to optimize 
> those kind of expressions as best as possible, and leave everything else 
> to libraries.  I guess that's pretty much how it works with HW shader 
> languages.  Except they add swizzles to the set of primitive ops.
> 
> 
> So what you're left with would be satisfied in large part by just having 
> vector math work on small static arrays (and be optimized well).
> 
>      float[4] v = a*b + c*d;
> 
> you can even make aliases if you like.
> 
>      alias float[4] float4;
> 
> But your 3D graphics library will still need to be a library on top of 
> that.

Yeah I mentioned static arrays earlier, but I realized that they can be 
a bit of a pain in the ass to work with.  This probably means that 
static arrays should be fixed, then they could be useful vectors. 
Consider trying to return a float4 from a function.  You can't return a 
float[4].  I remember talk on this ng about how static arrays were this 
kinda sucky inbetween-value-and-reference-type sort of thing.  I'd hope 
that at least gets fixed before static arrays are used for lo-D vectors.

> 
> Good news is that I think vector math like the above is something that 
> Walter is interested in adding to the language at some point.  Bad news 
> is that noone knows when that will be.   I'd guess though that a 
> kick-ass vector expression optimizer would be a long way off, judging by 
> how hard it's been for C++ compilers to get SSE type optimizations 
> implemented.
> 
> 
> "Getting it in the standard library"
> 
> I agree, though, that lo-D math is common enough that it should be 
> included in a standard library.  I wonder if the Tango developers would 
> be willing to include a vector math class...or if they already have one 
> in there.
> 
> I'd certainly like to be a contributor to that if so.
> 
> --bb
January 29, 2007
Re: seeding the pot for 2.0 features [small vectors]
Chad J wrote:
> Bill Baxter wrote:
>> Mikola Lysenko wrote:
>>
>>> Bill Baxter wrote:
>>>
>>>> Mikola Lysenko wrote:
>>>>
>>>>> 2. Low dimensional vectors as primitive types
>[...]

>>
>>      float[4] v = a*b + c*d;
>>
>> you can even make aliases if you like.
>>
>>      alias float[4] float4;
>>
>> But your 3D graphics library will still need to be a library on top of 
>> that.
> 
> Yeah I mentioned static arrays earlier, but I realized that they can be 
> a bit of a pain in the ass to work with.  This probably means that 
> static arrays should be fixed, then they could be useful vectors. 

Agreed.  So basically the D 2.0 wish list item becomes to make float[4] 
act more like a plain-old-data value type, give it simple math 
operations, optimize the heck out of it, and make it possible to alias 
it to float4 for convenience.

And maybe add the .xyzw accessors and swizzles too. :-)

I suspect the "optimize the heck out of it" step will be a long time 
coming though.  Probably more like D 3.0.

--bb
January 29, 2007
Re: seeding the pot for 2.0 features [small vectors]
Bill Baxter wrote:
> Chad J wrote:
> 
>> Bill Baxter wrote:
>>
>>> Mikola Lysenko wrote:
>>>
>>>> Bill Baxter wrote:
>>>>
>>>>> Mikola Lysenko wrote:
>>>>>
>>>>>> 2. Low dimensional vectors as primitive types
>>
>> [...]
> 
> 
>>>
>>>      float[4] v = a*b + c*d;
>>>
>>> you can even make aliases if you like.
>>>
>>>      alias float[4] float4;
>>>
>>> But your 3D graphics library will still need to be a library on top 
>>> of that.
>>
>>
>> Yeah I mentioned static arrays earlier, but I realized that they can 
>> be a bit of a pain in the ass to work with.  This probably means that 
>> static arrays should be fixed, then they could be useful vectors. 
> 
> 
> Agreed.  So basically the D 2.0 wish list item becomes to make float[4] 
> act more like a plain-old-data value type, give it simple math 
> operations, optimize the heck out of it, and make it possible to alias 
> it to float4 for convenience.
> 
> And maybe add the .xyzw accessors and swizzles too. :-)
> 
> I suspect the "optimize the heck out of it" step will be a long time 
> coming though.  Probably more like D 3.0.
> 
> --bb

*sigh* but I want my uber vector operations NOW! :)
January 29, 2007
Re: seeding the pot for 2.0 features
Reiner Pope wrote:
> I think something like a 'super static' function could also be good 
> (just to avoid using new keywords ;-) ). The idea would be that plain D 
> code could be called by template functions, and the compiler would 
> evaluate them at compile-time.
> 
> As I see it, there are only a few requirements for this (which are 
> recursive across all functions called):
> 
>   1. the source code is available
>   2. there's no assembly or C (or any external library) called
>   3. the functions are pure (ie no static variables are read or changed, 
> and the passed parameters are unchanged)
> 
> This would mean, for instance, that practically all of std.string would 
> be accessible via templates, avoiding the much of the need for separate 
> meta-programming libraries. You could then just call such functions 
> straight from your template code:
> 
> import std.string;
> 
> template foo(char[] bar)
> {
>     static if (bar.splitlines()[0] == "cheese")
>         pragma(msg, "You like cheese");
> }
> 
> 
> The compiler can check whether a function can be evaluated at 
> compile-time, and you may wish to ensure that yours is, since you are 
> writing it for template code. In that case, you annotate your function 
> 'super static' and the compiler will give you an error if it fails any 
> of the three criteria.
> 
> Cheers,
> 
> Reiner
Alternatively, if this is too hard to implement (since I think it 
effectively means writing a D interpreter within the compiler -- for the 
references only, since almost anything with value semantics already 
needs to be const-foldable for templates) another option could be the 
(slightly less cool) approach that Nemerle takes: precompile the library 
to a .dll file, and direct the compiler to that when it runs.
1 2 3 4 5
Top | Discussion index | About this forum | D home