Contributor's Guide

Coding Style {style} =================================

The following coding style should be followed in all MAGMA code. **Consistency is important, and clarity of code is paramount.** There are rare occasions to ignore a particular guideline, when following it would make the code less readable. The overriding goal is to make code easy-to-read and maintainable. This guide is based on the PLASMA coding style guide, though slightly different.

g++ -std=c++11 -Wall -pedantic -c magma.cpp gcc -std=c99 -Wall -pedantic -c magma.c

This can be done by setting CFLAGS and CXXFLAGS appropriately in make.inc. MAGMA code needs to be portable and work on Unix, MacOS, and Windows. Most MAGMA code is compiled as C++, but uses essentially C style conventions. For example, all externally visible functions are declared `extern "C"` and C-style malloc routines are used, instead of the C++ `new` operator.

There should be a space before and after boolean operators (`<, <=, >, >=, ==, !=`) and assignment operators (`=, +=, -=, *=, /=`), except when declaring a variable or initializing a loop variable. There should not be space between increment operators (`++, --`) and the variable. Space may be used around other operators (`+, -,` etc.) to aid readability.

Semi-colons are not preceded by a space. Inside for loop statement, semi-colons are followed by a space, e.g., for(i=0; i < n; ++i). Similarly, commas are not preceded by a space, and are followed by a space. Occasionally, additional spaces can be used after the comma to line up items on consecutive lines for better readability.

Even when the body of a block is only one line, it should be on a separate line from the control flow statement, and it is preferred to enclose it with curly braces to avoid errors when adding code (`goto fail; goto fail;`). Especially, loops and if statements containing more than one line of text should have curly braces, regardless of the number of C statements.

      void func( magma_int_t n, double *A, magma_int_t lda )
      {
          if (m <= 0 || n <= 0 || k <= 0) return;  // Avoid
          code_not_inside_if();

          if (m <= 0 || n <= 0 || k <= 0)          // Okay
              return;

          if (m <= 0 || n <= 0 || k <= 0) {        // Better
              return;
          }

          if (condition)      // Avoid single statement, multi-line if and loops!
              magma_zherk( uplo, trans, n, k,
                           alpha, dA(0,0), ldda,
                           beta,  dB(0,0), lddb );

          if (condition) {    // Better
              magma_zherk( uplo, trans, n, k,
                           alpha, dA(0,0), ldda,
                           beta,  dB(0,0), lddb );
          }

          if (condition)      // Avoid single block, multi-statement if and loops!
              for (i=0; i < n; ++i) {
                  A(i,i) = 0;
                  cnt += 1;
              }

          if (condition) {    // Avoid inconsistent indentation! Always use 4 spaces.
            for (i=0; i < n; ++i) {
                  A(i,i) = 0;
                   cnt += 1;
             }
          }

          if (condition) {    // Better
              for (i=0; i < n; ++i) {
                  A(i,i) = 0;
                  cnt += 1;
              }
          }

          if (condition) {    // Avoid excessive newlines

              norm = magma_dnrm2( n, dx(0), incx );

          }
      }
      // host pointers are the same for clBLAS, CUDA, and Xeon Phi.
      #define  A(i_,j_)  (A + (i_) + (j_)*lda)

      // for clBLAS, return cl_mem object and offset (2 values);
      // for others, return (pointer + offset) (1 value).
      #ifdef HAVE_clBLAS
          #define dA(i_,j_)  dA , (i_) + ((size_t) j_)*lda
      #else
          #define dA(i_,j_) (dA + (i_) + ((size_t) j_)*lda)
      #endif

      // for host pointers, A == A(0,0).
      blasf77_zherk( lapack_uplo_const(uplo), lapack_trans_const(trans), &n, &k,
                     &alpha, A,      &lda,
                     &beta,  B(i,j), &ldb );

      // for device pointers, use dA(0,0) instead of dA, to aid porting to OpenCL.
      magma_zherk( uplo, trans, n, k,
                   alpha, dA(0,0), ldda,
                   beta,  dB(i,j), lddb );

A _Purpose_ section gives an overall description of the routine.

An _Arguments_ section specifies each argument --- spelled and capitalized exactly as in the C code --- with its type, dimensions, description, and valid values (e.g., n >= 0).

Each function should be placed in a group using `@``ingroup`, which groups routines by the related driver routine (e.g., `zgetrf`, `zgetri`, `zgetf2` are all in one of the `magma_zgesv` groups), and whether it is a driver, computational, or auxiliary routine. There are also groups for BLAS and auxiliary routines. See `docs/doxygen-modules.h` for a list of groups (modules).

After compiling documentation (`cd docs ; make`), check `docs/output_err` for missing parameters or other issues.

      /*
          Divides matrix into ceil( m/BLK_X ) x ceil( n/BLK_Y ) blocks.
          Each block has BLK_X threads.
          Each thread loops across one row, updating BLK_Y entries.

          Code similar to zlaset.
      */
      static __device__ void
      zlacpy_device_full(
      magma_zherk(                           // Okay; preferred style for prototypes
          uplo, trans, n, k,
          alpha, dA(0,0), ldda,
          beta,  dB(i,j), lddb );

      magma_zherk( uplo, trans, n, k,        // Okay
                   alpha, dA(0,0), ldda,
                   beta,  dB(i,j), lddb );

      magma_zherk( uplo, trans, n, k,        // Avoid
          alpha, dA(0,0), ldda,
          beta,  dB(i,j), lddb );

For vim, sample ~/.vimrc file:

see http://stackoverflow.com/questions/19835905 set shiftwidth=4 set softtabstop=4 set expandtab set shiftround

For emacs, sample ~/.emacs file:

; see http://www.emacswiki.org/emacs/NoTabs ; see http://www.emacswiki.org/emacs/IndentingC (setq-default indent-tabs-mode nil) (setq c-default-style "k&r" c-basic-offset 4)

      printf( "Usage: %s\n"
              "  --flag1  description\n"
              "  --flag2  description\n"
              "  --flag3  description\n",
              argv[0] );

Naming Conventions {naming} =================================

Variables on the CPU should follow LAPACK names.

Variables on the GPU are similar but have "d" prepended. The corresponding leading dimension likewise has an added "d": `dA` and `ldda`, `dB` and `lddb`, etc.

Coding Practices {coding} =================================


Generated on 3 May 2015 for MAGMA by  doxygen 1.6.1