Accelerate simd library isn't complete for C++/ObjC/ObjC++

When you use the simd classes like float3/matrix3x3 on Swift they are great. I can write and run code like this from existing math routines that are readily found on the web.
Code Block
let value = m[0][0] * v[0]

When you try to do this in C++/ObjC, the code becomes this. This is not code readily found on the web, and is a big pain to convert.

Code Block
float value = m.columns[0][0] * v[0];

Can the float3x3 and other wrappers to simd_float3x3 provide an operator[] to the column and other operations like splatting since v[0] above pulls the data out of simd registers.

We currently have to derive off the matrix classes, but it seems like functionality that should be provided in the C/C++ simd classes. A vector math library should promote better code readability than this. We seem to not be able to derive off the vector types which is an issue below.

I also have code based on classes that takes 3 elements that suddenly has to convert to this less readble form.

Code Block
float3 v(x,y,z) -> float3 v(simd_make_float3(x,y,z))

And then there's this code that should fill all values like init repeating in Swift. This is error prone in converting existing simd code to Accelerate simd. So then we try to wrap the float3, can't derive off them, and then lose all swizzling support, operators, etc. Then have to roll our own ops on that struct that holds a float3. What's the recommended way to make this more C++ like without more compiler support

Code Block
float3 v = {3} -> 3,0,0 < wasn't expecting that
float3 v(3) < doesn't compile
v = {3,0,0} is completely different syntax, and doesn't line up with MSL and most simd libraries
struct myfloat3 : float3 < doesn't work
struct myfloat3
{
float3 v; <- works, but loses swizzles, operators, etc
explicit myfloat3(float value)
myfloat3(float x, float y, float z)
...
}


I think for now, we'll just offer some simpler functional ctors. Seems like for ObjC bridging and all that these typedefs can't be derived from. It just means our vector ops can't use any member functions, they all have to be functional constructs.

We can derive and provide members on the matrix types since those are struct { float3 }. This includes the operator[] and a non-initializing ctor. All the float3x3/4x4 ctors init the columns in the void ctor which is safer, but often unnecessary work that simd_float3x3/4x4 don't do.

float3 float3m( float a ) { return {a,a,a}; }

float3 v = float3m(3.0f); <- { 3, 3, 3 } <- using function and discouraging
float3 v = { 3.0f }; <- { 3, 0, 0 } <- avoid, this is most dangerous construct of this library, doesn't match MSL or most vecmath libs

v = normalize(v); <-v.normalize() can't use members
v = float3_zero <- float3::zero can't use class constants


Also noticing many of the oft-used routines like matrix transpose only have SIMD paths for SSE. Do the Neon paths on these go to scalar or simd ops?

Code Block
static simd_float2x2 SIMD_CFUNC simd_transpose(simd_float2x2 __x) {
#if defined __SSE__ <- why no Neon path?
  simd_float4 __x0, __x1;
  __x0.xy = __x.columns[0];
  __x1.xy = __x.columns[1];
  simd_float4 __r01 = _mm_unpacklo_ps(__x0, __x1);
  return simd_matrix(__r01.lo, __r01.hi);
#else
  return simd_matrix((simd_float2){__x.columns[0][0], __x.columns[1][0]},
                (simd_float2){__x.columns[0][1], __x.columns[1][1]});
#endif
}


Also there are two abs ops that are a part of AVX512 that are used under __AVX2__ flag.

Code Block
static inline SIMD_CFUNC simd_long2 simd_abs(simd_long2 x) {
#if defined __arm64__
 return vabsq_s64(x);
#elif defined __SSE4_1__ <- should be __AVX512F__
 return (simd_long2) _mm_abs_epi64((__m128i)x);
#else
 simd_long2 mask = x >> 63; return (x ^ mask) - mask;
#endif
}
static inline SIMD_CFUNC simd_long4 simd_abs(simd_long4 x) {
#if defined __AVX2__ <- should be __AVX512F__
 return _mm256_abs_epi64(x);
#else
 return simd_make_long4(simd_abs(x.lo), simd_abs(x.hi));
#endif
}


It is generally better to report bugs via feedback assistant, since that way they more reliably end up in front of the right person. In this case, I went ahead and reported the AVX-512 use issue for you.

Note that you can initialize a vector with repeating values by assigning a scalar; there's no need for a fancier C++ ctor. This works in C and Obj-C as well:

float3 v = 3;

That said, you shouldn't have to do this very often, because you can use scalar values in arithmetic with vectors directly:

float3 w = 3 + v; // adds 3 to each vector lane

Also note that there are a number of C++ enhancements for <simd/simd.h> in the SDK this year. Be sure to check out the SIMD portion of https://developer.apple.com/videos/play/wwdc2021/10233/ on Friday.

Accelerate simd library isn't complete for C++/ObjC/ObjC++
 
 
Q