Synchronize Multithreaded Access to FFTW Planning in Generated Standalone Code - MATLAB & Simulink (original) (raw)

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:

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 andunlock 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 thelock 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:

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(2pi15t) + sin(2pi20t); 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.

#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);
}

#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:

Use this class as a template. ReplacefftwLocation 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

  1. Create a code generation configuration object for generation of a dynamically linked library.
    cfg = coder.config('dll');
  2. Configure code generation to use the FFT callback classmyfftcb.
    cfg.CustomFFTCallback = 'myfftcb';
  3. Include the supporting C code in the build.
    cfg.CustomSource = 'mylock.c';
  4. Generate a call to the lock initialization function in the initialization code.
    cfg.CustomInitializer = 'mylock_initialize();';
  5. Generate the library.
    codegen -config cfg mycustomfft -report
    This example uses the OpenMP library. Therefore, theEnableOpenMP configuration parameter must betrue or you must manually pass the OpenMP flags to your compiler. By default, the EnableOpenMP parameter is true.

Specify Configuration Parameters in the MATLAB Coder App

For the preceding example in the MATLAB Coder app, use these project settings:

See Also

coder.ceval | coder.fftw.StandaloneFFTW3Interface

External Websites