Synchronize Multithreaded Access to FFTW Planning in Generated Standalone Code
This example shows how to generate standalone code (static library, dynamically linked library, or executable program) that synchronizes multithreaded access to the FFTW planning process.
The code generator produces FFTW library calls when all of these conditions are true:
Your MATLAB® code calls one of these functions:
fft
,fft2
,fftn
,ifft
,ifft2
, orifftn
.You generate standalone C/C++ code.
You have access to an FFTW library installation, version 3.2 or later.
You specify the FFTW library installation in an FFT library callback class that derives from
coder.fftw.StandaloneFFTW3Interface
.You specify the name of the callback class by using the Custom FFT library callback parameter or the code configuration property
CustomFFTCallback
.
If multiple threads call the FFTW library, then the generated code must prevent
concurrent access to the FFTW planning process. To synchronize access to FFTW planning,
in your FFT library callback class, implement the lock
and
unlock
methods. You must also provide C code that manages a lock
or mutex. Many libraries, such as OpenMP, pthreads, and the C++ standard library (C++ 11
and later) provide locks. This example shows how to implement the
lock
and unlock
methods and provide supporting
C code. To manage a lock, this example uses the OpenMP library.
Prerequisites
Before you start, for the basic workflow for generating FFTW library calls in standalone code, see Speed Up Fast Fourier Transforms in Generated Standalone Code by Using FFTW Library Calls.
You must have:
Access to an installed FFTW library.
A compiler that supports the OpenMP library. To use a different library, such as pthreads, modify the supporting C code accordingly.
Create a MATLAB Function
Write a MATLAB function mycustomfft
that calls a fast Fourier
transform function inside a parfor
loop:
function y = mycustomfft() %#codegen t = 0:1/50:10-1/50; x = sin(2*pi*15*t) + sin(2*pi*20*t); y = fft(x); parfor k = 1:100 y = y + ifft(x+k); end
Write Supporting C Code
Write C functions that initialize, set, and unset a lock. This example uses the OpenMP library to manage the lock. For a different library, modify the code accordingly.
Create a file
mylock.c
that contains this C code:#include "mylock.h" #include "omp.h" static omp_nest_lock_t lockVar; void mylock_initialize(void) { omp_init_nest_lock(&lockVar); } void mylock(void) { omp_set_nest_lock(&lockVar); } void myunlock(void) { omp_unset_nest_lock(&lockVar); }
Create a header file
mylock.h
that contains:#ifndef MYLOCK_H #define MYLOCK_H void mylock_initialize(void); void mylock(void); void myunlock(void); #endif
Write an FFT Library Callback Class
Write an FFT callback class myfftcb
that:
Specifies the FFTW library.
Implements
lock
andunlock
methods that call the supporting C code to control access to the FFTW planning.
Use this class as a template. Replace
fftwLocation
with the location of your FFTW library
installation.
classdef myfftcb < coder.fftw.StandaloneFFTW3Interface methods (Static) function th = getNumThreads coder.inline('always'); th = int32(coder.const(1)); end function lock() coder.cinclude('mylock.h', 'InAllSourceFiles', true); coder.inline('always'); coder.ceval('mylock'); end function unlock() coder.cinclude('mylock.h', 'InAllSourceFiles', true); coder.inline('always'); coder.ceval('myunlock'); end function updateBuildInfo(buildInfo, ctx) fftwLocation = '\usr\lib\fftw'; includePath = fullfile(fftwLocation, 'include'); buildInfo.addIncludePaths(includePath); libPath = fullfile(fftwLocation, 'lib'); %Double libName1 = 'libfftw3-3'; [~, libExt] = ctx.getStdLibInfo(); libName1 = [libName1 libExt]; addLinkObjects(buildInfo, libName1, libPath, 1000, true, true); %Single libName2 = 'libfftw3f-3'; [~, libExt] = ctx.getStdLibInfo(); libName2 = [libName2 libExt]; addLinkObjects(buildInfo, libName2, libPath, 1000, true, true); end end end
Generate a Dynamically Linked Library
You can instruct the code generator to produce a dynamically linked library by using a code configuration object or by using the Code Generation Settings dialog box.
Use a Code Configuration Object at the Command Line
Create a code generation configuration object for generation of a dynamically linked library.
cfg = coder.config('dll');
Configure code generation to use the FFT callback class
myfftcb
.cfg.CustomFFTCallback = 'myfftcb';
Include the supporting C code in the build.
cfg.CustomSource = 'mylock.c';
Generate a call to the lock initialization function in the initialization code.
cfg.CustomInitializer = 'mylock_initialize();';
Generate the library.
This example uses the OpenMP library. Therefore, thecodegen -config cfg mycustomfft -report
EnableOpenMP
configuration parameter must betrue
or you must manually pass the OpenMP flags to your compiler. By default, theEnableOpenMP
parameter istrue
.
Use the Code Generation Settings Dialog Box in the MATLAB Coder App
In the MATLAB Coder™ tab of the toolstrip, click Settings to open the Code Generation Settings dialog box.
To specify the FFT library callback class, set the Custom FFT library callback parameter to
myfftcb
.To specify the C code to include, set the Additional source files parameter to
mylock.c
.To specify generation of a call to
mylock_initialize
in the initialization code, set the Initialize function parameter tomylock_initialize();
.
See Also
coder.ceval
| coder.fftw.StandaloneFFTW3Interface