Search code examples
coding-stylevectorizationaccelerate-framework

coding with vectors using the Accelerate framework


I'm playing around with the Accelerate framework for the first time with the goal of implementing some vectorized code into an iOS application. I've never tried to do anything with respect to working with vectors in Objective C or C. Having some experience with MATLAB, I wonder if using Accelerate is indeed that much more of a pain. Suppose I'd want to calculate the following:

b = 4*(sin(a/2))^2 where a and b are vectors.

MATLAB code:

a = 1:4;
b = 4*(sin(a/2)).^2;

However, as I see it after some spitting through the documentation, things are quite different using Accelerate.

My C implementation:

float a[4]  = {1,2,3,4};                        //define a
int len     = 4;
float div   = 2;                                //define 2
float a2[len];                                  //define intermediate result 1
vDSP_vsdiv(a, 1, &div, a2, 1, len);             //divide
float sinResult[len];                           //define intermediate result 2
vvsinf(sinResult, a2, &len);                    //take sine
float sqResult[len];                            //square the result
vDSP_vsq(sinResult, 1, sqResult, 1, len);       //take square
float factor = 4;                               //multiply all this by four
float b[len];                                   //define answer vector
vDSP_vsmul(sqResult, 1, &factor, b, 1, len);    //multiply

//unset all variables I didn't actually need

Honestly, I don't know what's worst here: keeping track of all intermediate steps, trying to memorize how the arguments are passed in vDSP with respect to VecLib (quite different), or that it takes so much time doing something quite trivial.

I really hope I am missing something here and that most steps can be merged or shortened. Any recommendations on coding resources, good coding habits (learned the hard way or from a book), etc. would be very welcome! How do you all deal with multiple lines of vector calculations?


Solution

  • I guess you could write it that way, but it seems awfully complicated to me. I like this better (intel-specific, but can easily be abstracted for other architectures):

    #include <Accelerate/Accelerate.h>
    #include <immintrin.h>
    
    const __m128 a = {1,2,3,4};
    const __m128 sina2 = vsinf(a*_mm_set1_ps(0.5));
    const __m128 b = _mm_set1_ps(4)*sina2*sina2;
    

    Also, just to be pedantic, what you're doing here is not linear algebra. Linear algebra involves only linear operations (no squaring, no transcendental operations like sin).


    Edit: as you noted, the above won't quite work out of the box on iOS; the biggest issue is that there is no vsinf (vMathLib is not available in Accelerate on iOS). I don't have the SDK installed on my machine to test, but I believe that something like the following should work:

    #include <Accelerate/Accelerate.h>
    
    const vFloat a = {1, 2, 3, 4};
    const vFloat a2 = a*(vFloat){0.5,0.5,0.5,0.5};
    const int n = 4;
    vFloat sina2;
    vvsinf((float *)&sina2, (const float *)&a, &n);
    const vFloat b = sina2*sina2*(vFloat){4,4,4,4};
    

    Not quite as pretty as what is possible with vMathLib, but still fairly compact.

    In general, a lot of basic arithmetic operations on vectors just work; there's no need to use calls to any library, which is why Accelerate doesn't go out of its way to supply those operations cleanly. Instead, Accelerate usually tries to provide operations that aren't immediately available by other means.