Differences between revisions 1 and 2
Revision 1 as of 2010-05-31 11:06:55
Size: 3820
Comment:
Revision 2 as of 2010-05-31 12:20:49
Size: 4069
Comment:
Deletions are marked like this. Additions are marked like this.
Line 4: Line 4:
 * '''Printing''': Making Matlab output mirror output produced by a standard C program is not a straightforward task. Creating wrapper functions, or at least wrapper functions similar to those I created (see attached), do not produce the expected output. However, it is both simple and effective to replace calls to {{{printf}}} with calls to {{{mexPrintf}}}. Though this does not produce output at the same rate as that of a standalone C program (as Matlab writes everything to a buffer and only periodically writes the buffer to screen), it does produce the correct output. '''NB''': I tried using {{{mexEvalString("drawnow;");}}} and {{{mexEvalString("pause(.001);");}}} to flush the buffer with little success and, in fact, they seem to change the output that is actually written to screen. Thus, unless it is desirable within the standalone program to redirect stderr to a different location than stdout, it is better to use {{{printf}}} as opposed to {{{fprintf}}} (though, admittedly, printing to {{{stderr}}} can aid in debugging code as it prints immediately as opposed to {{{stdout}}})).  * '''Printing''': Making Matlab output mirror output produced by a standard C program is not a straightforward task. Creating wrapper functions, or at least wrapper functions similar to those I created (see [[attachment:print_wrappers.c|attached]]), do not produce the expected output. However, it is both simple and effective to replace calls to {{{printf}}} with calls to {{{mexPrintf}}}. Though this does not produce output at the same rate as that of a standalone C program (as Matlab writes everything to a buffer and only periodically writes the buffer to screen), it does produce the correct output. '''NB''': I tried using {{{mexEvalString("drawnow;");}}} and {{{mexEvalString("pause(.001);");}}} to flush the buffer with little success and, in fact, they seem to change the output that is actually written to screen. Thus, unless it is desirable within the standalone program to redirect stderr to a different location than stdout, it is better to use {{{printf}}} as opposed to {{{fprintf}}} (though, admittedly, printing to {{{stderr}}} can aid in debugging code as it prints immediately as opposed to {{{stdout}}})).
Line 8: Line 8:
 * '''ANSI C''': The ANSI C (90) standard should be followed when creating code for mex on Linux as gcc takes the {{{-ansi}}} flag. The greatest implication of this is that C++-style comments of the form '{{{//...}}}' are not accepted and must be replaced with C-style comments of the form '{{{/*...*/}}}'. An awk script has been written that performs this transformation and is attached.  * '''ANSI C''': The ANSI C (90) standard should be followed when creating code for mex on Linux as gcc takes the {{{-ansi}}} flag. The greatest implication of this is that C++-style comments of the form '{{{//...}}}' are not accepted and must be replaced with C-style comments of the form '{{{/*...*/}}}'. An awk script has been written that performs this transformation and is attached ([[attachment:replace_comments.sh|file 1]], [[attachment:rep_comm.sh|file 2]]).
Line 33: Line 33:
 * The Dynare coding standard mandates the use of spaces in lieu of tabs.
 * There should not be any trailing whitespace at the end of a line.
 * The character that indicates an end of line should conform to the Unix standard.
 * The Dynare coding standard mandates the use of spaces in lieu of tabs (see attached [[attachment:replace_tabs_w_spaces.sh|shell script]]).
 * There should not be any trailing whitespace at the end of a line (see attached [[attachment:remove_trailing_whitespace.sh|shell script]]).
 * The character that indicates an end of line should conform to the Unix standard (see attached [[attachment:change_ending.sh|shell script]]).
Line 37: Line 37:
 * Shell scripts are attached that perform the above changes.

This page describes the various changes made to the SWZ code (written in C) to make it work with Matlab mex. Further, it documents changes made to make the code consistent with the Dynare standards.

Basic changes: printing, error messages, exiting and ANSI C

  • Printing: Making Matlab output mirror output produced by a standard C program is not a straightforward task. Creating wrapper functions, or at least wrapper functions similar to those I created (see attached), do not produce the expected output. However, it is both simple and effective to replace calls to printf with calls to mexPrintf. Though this does not produce output at the same rate as that of a standalone C program (as Matlab writes everything to a buffer and only periodically writes the buffer to screen), it does produce the correct output. NB: I tried using mexEvalString("drawnow;"); and mexEvalString("pause(.001);"); to flush the buffer with little success and, in fact, they seem to change the output that is actually written to screen. Thus, unless it is desirable within the standalone program to redirect stderr to a different location than stdout, it is better to use printf as opposed to fprintf (though, admittedly, printing to stderr can aid in debugging code as it prints immediately as opposed to stdout)).

  • Exit: To exit a program, replace all calls to exit() with calls to mexErrMsgTxt();. If there is a print statement before the call to exit(), the two can be combined into one call to mexErrMsgTxt(msg);

  • ANSI C: The ANSI C (90) standard should be followed when creating code for mex on Linux as gcc takes the -ansi flag. The greatest implication of this is that C++-style comments of the form '//...' are not accepted and must be replaced with C-style comments of the form '/*...*/'. An awk script has been written that performs this transformation and is attached (file 1, file 2).

Changes to BLAS and LAPACK functions for 64-bit compatibility

  • Any BLAS or LAPACK functions that are used within the code should be declared in the dynblas.h and dynlapack.h header files located in <<dynare_root>>/mex/sources/, following the declaration style within that file. Needless to say, these header files must be included in the .c files that make calls to BLAS/LAPACK functions and other header files that declare such functions must be removed.

  • Calls to these functions must be modified within the code in the following manner. If the original code reads:
    int nrows, ncols, errflag...;
    int *pivot_p=NULL;
    ...
    dgetrf_(&nrows, &ncols, LU, &nrows, pivot_p, &errflag);
    The modified code must read:
    int nrows, ncols, errflag...;
    lapack_int nrows2, ncols2, errflag2...;
    lapack_int *pivot_p=NULL;
    ...
    nrows2 = nrows;
    ncols2 = ncols;
    errflag2 = errflag;
    dgetrf_(&nrows2, &ncols2, LU, &nrows2, pivot_p, &errflag2);
    errflag = errflag2;

    Care must be taken when making these changes as a slight error can potentially lead to inexplicable errors when the code runs. Specifically, knowing the size of inputs and copying them over is an easy place to make a mistake. Further, care must be taken to reassign all output variables of these functions immediately after the call is made (e.g., errflag2 above).

Tabs, Trailing Whitespace, and Line Return characters

  • The Dynare coding standard mandates the use of spaces in lieu of tabs (see attached shell script).

  • There should not be any trailing whitespace at the end of a line (see attached shell script).

  • The character that indicates an end of line should conform to the Unix standard (see attached shell script).

  • See CodingStandards for a more in-depth explanation of these matters.

DynareWiki: ModifyingSWZ (last edited 2010-07-06 15:04:09 by HoutanBastani)