Intel IPP - free Community licence

Awesome, I didn't know that! Last time I came across IPP (many years ago) it was less easy to use.

Even Intel resellers didn't know it was free! I phoned an Intel reseller in th UK a couple of weeks ago and they said it was around £1K GBP plus 20% per year maintenance. Then someone here pointed out the community license!

It's super easy to to use. The Math Kernel Library is "free" too (so you can do other vectorised maths ops).

And yes the FFT stuff is fast. I've been using Apple's vDSP for years and IPP is about the same speed.

How does this work with Xcode and VS2015 ? Anyone tried that?

Cheers,

Rail

1 Like

Yes -- works fine with both! :)

Best,
Stian

Very fine with both

Thanks guys!

Rail

Hi,
IPPFIRSR kills all other FFTs for simple multiplication of a stream with a set impulse. The maths functions are super fast.
The hardest thing about IPP is setting it up.
As a novice, I think a simple tutorial or video tutorial on how to install IPP for mac and PC would be great. Eg step 1. install IPP step 2. open terminal and type… This would really help users.
The initializing of an FFTs is a little awkward, but simple to follow with an example.
I would love IPP as part of the JUCE math and FFT. I am on IPP v8. If someone could list out all the functions you want to replace or add, I am happy to give you the IPP equivalent. A hash define IPPS replacement of some elements of the JUCE code would be great. It would be better for trouble shooting to be able to turn the hash define IPP on and off. When IPPS crashes there is not much debugging info.
A real programmer can check my work, but could you give us a structure if you would like us to start writing some hash define replacements with
zero(memset),
add,
addproduct,
mul,
div,
mulc,
divc,
addc,
rms avarege,
fttforward ,
FIRSR(fft with a set impulse),
fttforward,
fttforwardCCS to magnitude with a hz to bin address system,
fftinverse,
windowing functions,
sampleup(add zeros),
sampledown,
dotproduct,
Min,
Max,
Threshold(change a value to a constant above or below a threshold),
set(like memset, but sets to a constant).
The list goes on. This would really boost JUCE.
Thanks
lpb

The hash define would also stop licencing problems. You would only turn IPP on if you downloaded and installed it yourself.
Someone with experience can give IPP replace for biquad and random noise. I have not used these yet.

It would be indeed really nice to have the FloatVectorOperations class choose the IPP routines if the IPP library is available… On OSX there won’t be a big performance leap because of vdsp but on windows it would make a difference.

Jules, if we supply you with the code (its boring boilerplate stuff) would that be something you would incorporate into JUCE?

Sure, if it’s straightforward to do that. Would need to make sure there’s no runtime overhead in choosing IPP, but if it could be selected at compile time, that’d be something we could probably use.

1 Like

I made some quick tests to benchmark the IPP routines vs the FloatVectorOperations by running this loop which contains some random vector operations.

The juce::FloatVectorOperations loop:

for (int i = 0; i < LOOP_LENGTH; i++)
{
    FloatVectorOperations::fill(d, initialisers[i], NUM_SAMPLES);
    FloatVectorOperations::multiply(d, multipliers[i], NUM_SAMPLES);
    FloatVectorOperations::add(d, 2.0f, NUM_SAMPLES);
    result[i] = FloatVectorOperations::findMaximum(d, NUM_SAMPLES);
}

The IPP loop:

for (int i = 0; i < LOOP_LENGTH; i++)
{
    ippsSet_32f(initialisers[i], d, NUM_SAMPLES);
    ippsMulC_32f_I(multipliers[i], d, NUM_SAMPLES);
    ippsAddC_32f_I(2.0f, d, NUM_SAMPLES);
    ippsMax_32f(d, NUM_SAMPLES, result+i);
}

You see that it looks pretty much the same (the only semantic difference would be not having the result as return value because every IPP operation returns a IppResult object.

initialiers, multipliers and result are float arrays allocated on the stack (the result will be logged to make sure the compiler doesn’t optimize this away).

d is the data buffer. I made tests with NUM_SAMPLES = 88200 and LOOP_LENGTH = 2049. I also made tests using unaligned (?) data allocated from an AudioSampleBuffer as well as using specially aligned data from the IPP allocator.

My machine is a Macbook Pro i7 2,3GHz 2012 running Win7 under Bootcamp (OSX is not interesting, because this is not supposed to be a vdsp / IPP shootout). Testing was done with x64 (of course Release build)

Results

Unaligned Data IPP: 134 ms
Aligned Data IPP: 98ms

Unaligned Data JUCE: 130ms
Aligned Data JUCE: 130ms

So using IPP allocated data with the IPP routines yields a perfomance gain of about 25% (it may be higher for more complex operations than multiply and add). If the operation is used on a unaligned data buffer, IPP performs a little bit slower (while the JUCE operations don’t seem to care about the allocation type).

Conclusion:

To really benefit from IPP, we really need to make sure that the data is IPP allocated. Using the IPP routines on AudioSampleBuffer data is only useful if it allocating it elsewhere and using AudioBuffer::setDataToReferTo.

I assume the code could go along side the non IPP/AMD alternative using #if HAS_IPP. Here are some code that can be replaced. 32s is an int.
———————————————————
Type findMinimum (const Type* data, int numValues)
could be

ippsMin_32s(data, numValues, &result);
ippsMin_32f(data, numValues, &result);
ippsMin_64f(data, numValues, &result);

———————————————————
findMaximum (const Type* values, int numValues)
or for peaks there is a MaxAbs(or i.e. MaxAbs[{8.0,-15.0,3.0}]=15.0
could have

ippsMax_32s(data, numValues, &result);
ippsMax_32f(data, numValues, &result);
ippsMax_64f(data, numValues, &result);
———————————————————
findMinAndMax (const Type* values, int numValues, Type& lowest, Type& highest)
is
ippsMinMax_32f(const Ipp32f* pSrc, int len, Ipp32f* pMin, Ipp32f* pMax);
———————————————————
There are a whole lot of threshold functions that are very different to JUCE threshold tests. Anyone got any thoughts? I love the IPP threshold functions.
———————————————————

For anyone happy to contribute some other obvious useful non FFT functions are below. It would be great to have non IPP/AMD alternatives.

ippsNorm_L2_32f(const Ipp32f* pSrc, int len, Ipp32f* pNorm);
is the function is a RMS of the source over the length passed to the norm
———————————————————
ippsDotProd_32f(const Ipp32f* pSrc1, const Ipp32f* pSrc2, int len, Ipp32f* pDp);
is the dot product of src1 and src2 over the length passed to pDp
———————————————————

ippsSampleUp_32f (const Ipp32f* pSrc, int srcLen, Ipp32f* pDst, int* pDstLen, int factor, int* pPhase);
factor-1 is the number of zeros inserted
pPhase is the address that the pSrc starts on, i.e. 0 is the start, like in an array.
———————————————————
ippsSampleDown_32f (const Ipp32f* pSrc, int srcLen, Ipp32f* pDst, int* pDstLen, int factor, int* pPhase);
factor-1 is the number of samples removed
pPhase is the start address that the pSrc keeps, i.e. 0 is the start, like in an array.
———————————————————
I can provide a FFTforwardCCSToMagnitudeDb where the input is pSrc, an input length and an array of bin(hz) values. It would return an array of dB outputs for each hz values. I thought the input could be the bin values, but defined as HzValueRequired[index]= HzToBin(inputHz); The db could be a flag. The Hz conversion would be better in the constructor unless needed elsewhere.

The FFT FIRSR is easy, but it would be better if the constructor was hidden and appeared to only use impulse and impulse size. We could hide the spec, etc. I think the only function inputs should be block stream and block stream size. I can provide working code for FIRSR, but not in this neat format.

FFT, iFFT, PolarToCart and CartToPolar are easy, but yet again it would be good to hide the spec, etc.
Thanks

It looks like the Intel Math Kernel Library also has a community edition.

https://software.intel.com/en-us/intel-mkl

Anyone want to give me a code structure. I am no programmer, but with a template for a guide, I can list out the IPP functions as a start. Maybe then people can offer AMD alternatives.
Cheers
Lach

These libraries should work on AMD as well

Cool.
That changes everything.
Thanks

Probably not the best Unix, but here is how I installed IPP on the Mac for Xcode. Would have preferred a more professional answer, but to keep the forum being helpful.
In Terminal become a super user by typing
sudo su
then in Terminal enable root user by typing
dsenableroot

Now install IPP as a root user(IPP can be downloaded from the net).

Return to terminal and setup IPP by typing
. /opt/intel/bin/compilervars.sh -arch intel64 -platform mac

In your Projucer project XCode settings

Add the extra linker flags

-L$(home)/opt/intel/compilers_and_libraries_2017.0.102/mac/ipp/lib
-lippcore
-L$(home)/opt/intel/compilers_and_libraries_2017.0.102/mac/ipp/lib
-lipps
-L$(home)/opt/intel/compilers_and_libraries_2017.0.102/mac/ipp/lib
-lippvm
(You can add extra IPP libraries if you want)

In the Projucer debug and release settings add

Header search paths
$(home)/opt/intel/compilers_and_libraries_2017.0.102/mac/ipp/include

Extra library search paths
$(home)/opt/intel/compilers_and_libraries_2017.0.102/mac/ipp/lib

Now
#include “ipp.h”;
in your project and try IPP for yourself.

additionally
If you want to run the IPP setup app(look at the get_started doc), you with need to setup Xcode by adding the following
in the
Target
in
Build Settings
in
Search paths

in
Header search paths
type
$(home)/opt/intel/compilers_and_libraries_2017.0.102/mac/ipp/include

and also
in the
Target
in
Build Settings
in
Search paths

in
Extra library search paths
type
$(home)/opt/intel/compilers_and_libraries_2017.0.102/mac/ipp/lib

Now
in the
Target build phase
drag from
$(home)/opt/intel/compilers_and_libraries_2017.0.102/mac/ipp/lib
to the
Link with binary libraries
the following
libippcore.a
libipps.a
libippvm.a
(you can add extra IPP libraries here)

and that is it.

I am transitioning to Projucer, constructing a new GUI and rebuilding my class system(months of work) and I have only tested the new IPP9 with ippsZero, but I am sure it is ok. I will test on my signal processing soon.

Enjoy and I am no expert so feel free to correct any of the above(in fact could someone proof read it). I will not be offended. I installed IPP a while ago and I hope I remembered all the steps.

Thanks
Lach

This is way too complicated. Just install IPP using the installer from the DMG and add

  1. These lines into the Extra Linker Flags box (important, don’t add it to “External libraries to link” box, it won’t compile and spit out error messages like crazy):

     /opt/intel/ipp/lib/libippi.a  /opt/intel/ipp/lib/libipps.a /opt/intel/ipp/lib/libippvm.a /opt/intel/ipp/lib/libippcore.a
    
  2. this line into the header search paths:

     /opt/intel/ipp/include
    
  3. And this into the “Extra library search paths”:

     /opt/intel/ipp/lib
    

Then #include <ipp.h> the header in your code and start using it. No need to become superuser or modify anything in Xcode (at least for me)…

4 Likes

Cool thanks.
That is easier looking.

anybody willing to share a version compatible with OSX 10.10? Unfortunately the download I got requires 10.11 or higher.

1 Like