MATLAB Answers


Thread Subject: Hessian calculated by fmincon within a parfor or spmd environment

Asked by Georgios
on 25 Jan 2012

Dear all,

My code works fine in serial mode, and I experiment with parfor and spmd to speed it up. The code runs the same sequence of function calls 7 times (corresponding to 7 independent models), and it uses containers (vectors and arrays) of different sizes at a time. Each model utilizes fmincon with the Hessian at the minimum returned. The problem within a parallel environment appears as soon as fmincon finds a minimum for the first time and attempts to calculate the Hessian for that model.

A relevant part of the main driver looks like this

% Attempt a parfor or spmd
spmd (7)
switch labindex
case 1
  lambda    = 0.0604;
  mu        = [0.0696 -0.0249 -0.0108]';
(code omitted)
  DNS1      = optimize_logL('DNS_unc',lambda,mu,state_par, ...
case 2
  lambda    = [0.06248 0.0531];
  mu        = [0.0723 -0.0294 -0.012 0.063]';
(code omitted)

where optimize_logL is the constructor of a user defined class.

Through the function optimize_logL and additional function calls therein, fmincon is invoked. The relevant part is the following

options = optimset('FinDiffType','forward', 'MaxFunEvals',50000, ...
                   'TolX',1e-7, 'TolFun',1e-7, 'MaxIter',10000, ...
                   'Algorithm','interior-point', 'Hessian','bfgs', ...
                   'Diagnostics','on', 'UseParallel','always');
[xopt,logLmax,exitflag,output,~,grad,hessian] = ...
    fmincon(@objective_fun_con,QML.param_vec,A,b,Aeq,beq,lb,ub, ...

with the objective function and non-linear constraint below

objective function

% redefine parameter containers
[lambda mu state_par state_cov meas_cov] = extract_parameters(QML,x);
% create and evolve a temporary model with stability checks off
model_temp = choose_model(QML,QML.model_name,lambda,mu, ...
% return the log-likelihood value
logL = model_temp.logL;

non-linear constraint

% redefine parameter containers
[~, ~, state_par] = extract_parameters(QML,x);
(comments omitted)
c = abs(eig(state_par))' - 0.9999999999999999;
ceq = [];

The containers lambda, mu, etc have different sizes per model. The temporary handle model_temp is created to initiate a series of calculations common to every model, and it should be destroyed at function exit.

The error message I get is

Error using spmd_feval (line 8)
Error detected on lab(s) 6
Caused by:
    Matrix dimensions must agree.
    Error stack:
    parfinitedifferences>(parfor body) at 158
    Sending a stop signal to all the labs ... stopped.

or if I use 'UseParallel','never'

Error using spmd_feval (line 8)
Error detected on lab(s) 6
Caused by:
    CAT arguments dimensions are not consistent.
    Error stack:
    formJacobian.m at 26
    barrier.m at 596
    fmincon.m at 841
    optimize_model.m at 59
    optimize_logL>optimize_logL.optimize_logL at 160
    Sending a stop signal to all the labs ... stopped.

I assume some of the model containers are mixed, while they are not supposed to do so. Since the evaluation of the Hessian follows the calculation of the function minimum as a part of fmincon, I cannot add a few diagnostic fprintf statements to see what is actually happening.

A few clarifications and things that I have tried:

1) I do not use global variables.

2) There is no file opening or I/O to a file involved, only some output to the screen.

3) I tried to add delete and clear statements in the objective function before it exits, without any positive result.

4) I tried a model_temp = []; before the function end but still no different result.

5) All the variables/containers that are passed in optimize_logL at the main driver are (re)defined for every case block of the switch statement.

6) There is no difference in the error messages between spmd and parfor.

7) Each of the 7 models is a user-defined class, and optimize_logL is a separate class. All 8 classes inherit a common superclass where the containers lambda, mu, etc are properties with protected access, and function in_sample_yield has public access.

Any suggestions to tackle this problem are welcome.




No products are associated with this question.

1 Answer

Answer by Jill Reese
on 19 Nov 2012

If you want to leverage the inherent parallelism in fmincon via the 'UseParallel' parameter then you shouldn't invoke the parfor or spmd language constructs directly. Instead, simply open a matlabpool and invoke your code

    lambda    = 0.0604;
    mu        = [0.0696 -0.0249 -0.0108]';
  (code omitted)
    DNS1      = optimize_logL('DNS_unc',lambda,mu,state_par, ...

When fmincon is called within your function with 'UseParallel' set to 'Always', then the finite difference derivative estimation will always be performed in parallel using the open pool of workers.


Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply today