Comparing Fortran and VFI-Toolkit for a finite-horizon life-cycle model with endogenous labor
Short summary: the VFI toolkit run times are not bad compared to Fortran. Value function iteration and distribution are about half an order of magnitude slower compared to Fortran. The calculation of age-dependent model statistics is the real bottleneck: too slow, especially considering that I set simoptions.whichstats to skip gini, lorenz and quintiles.
I have been working on a small replication exercise comparing a Fortran
implementation and a MATLAB/VFI-Toolkit implementation of the same
finite-horizon life-cycle model with endogenous labor supply.
The model has assets a, an exogenous Markov productivity shock \eta, age
j, and a permanent productivity type \theta. The household chooses
next-period assets a' and labor l. Labor is endogenous, but conditional on
a' it has a closed-form solution, so in the VFI-Toolkit implementation I do
not declare labor as a separate d decision grid. Instead the return function
uses the action-state inputs (a',a,\eta) and computes labor internally:
for working ages, and l=0 in retirement.
The replication code is here:
The Fortran code is in codes_fortran/. The MATLAB/VFI-Toolkit code is in
codes_matlab/. The model description and timing table are in tex_pdf/.
Runtime comparison
The table below reports the current runtime decomposition. The Fortran code is
compiled with Intel oneAPI ifx using /O2. The MATLAB code uses the
VFI-Toolkit finite-horizon routines with the toolkit’s GPU path when available.
| Step | Fortran (s) | MATLAB/VFI-Toolkit (s) | MATLAB/Fortran |
|---|---|---|---|
solve_household / VFI |
0.182225 | 0.896763 | 4.92x |
| Distribution | 0.013436 | 0.077600 | 5.78x |
| Aggregation / model moments | 0.001490 | 2.965766 | 1,990.45x |
| Total | 0.197152 | 3.940129 | 19.99x |
Overall, the toolkit implementation is about 20 times slower than the Fortran
implementation in this test. However, most of the total difference comes from
the calculation of model moments, not from the value-function iteration itself.
The VFI step is slower by about half an order of magnitude:
The distribution step is similar:
By contrast, the model-moment step is slower by more than three orders of
magnitude:
In levels, the aggregation/model-moment step accounts for about 79 percent of
the total MATLAB-minus-Fortran runtime gap in this run.
Issue with age-conditional standard deviations
One discrepancy I ran into concerns standard deviations conditional on age when
using permanent types. The toolkit output for grouped age profiles gave means
that looked fine, but the grouped standard deviations conditional on age did
not match the statistic I needed for the comparison with Fortran.
In particular, I wanted the standard deviation of an object x conditional on
age j, pooling across permanent types \theta_i. What worked was to use the
toolkit’s per-type age statistics and then combine them manually using the law
of total variance:
Then
This manual grouped-standard-deviation calculation is implemented in
codes_matlab/f_model_moments.m. It uses the toolkit-generated per-type means
and standard deviations, gathers the age statistics once, and then constructs
the grouped standard deviation outside the toolkit profile object.
I am posting this partly to document the comparison, and partly to ask whether
there is a better toolkit-native way to request this exact age-conditional,
permanent-type-pooled standard deviation.