Skip to content

Readability with "auto", "typedef", and "using"

Matt Norman edited this page Dec 10, 2021 · 1 revision

YAKL's C++ syntax can get a bit unwieldy, especially or those less familiar with C++ namespaces, templates, etc. To clean the code up a bit and make things more readable, it is helpful to use the C++ typedef and using statements. For instance:

#include "YAKL.h"
#include <iostream>

using yakl::Array;
using yakl::memDevice;
using yakl::styleFortran;
using yakl::fortran::Bounds;
using yakl::fortran::parallel_for;
using yakl::FSArray;
using yakl::SB;

// Allows us to switch the precision of the code easily
typedef float real;

// This allows us to add a suffix to force floating point literals to
// match the precision of "real", which is single precision in this case
// Thus 0.1_rp has single precision, even though default C++ precision
// is double.
YAKL_INLINE real constexpr operator"" _rp( long double x ) {
  return static_cast<real>(x);
}

typedef Array<real,1,memDevice,styleFortran> real1d;
typedef Array<real,2,memDevice,styleFortran> real2d;
typedef Array<real,3,memDevice,styleFortran> real3d;

int main() {
  int constexpr nx=1024;

  // real(rp) :: data(0:nx+1)
  real1d data("data",{0:nx+1});

  // real(rp) :: del2(nx)
  real1d del2("del2",nx);

  // do i = 1 , nx
  parallel_for( nx , YAKL_LAMBDA (int i) {
    // real(rp) :: stencil(-1:1)
    FSArray< SB<-1,1> > stencil;

    // do ii = -1 , 1
    for (int ii=-1; ii <= 1; ii++) {
      stencil(ii) = data(i+ii);
    }
    del2(i) = 0.5_rp * stencil(-1) - stencil(0) + 0.5_rp * stencil(1);
  });
  // This creates an Array<real,1,memHost,styleFortran> object
  // But with "auto", you can hide that ugliness
  auto del2_host = del2.createHostCopy();

  // write(*,*) del2
  for (int i=1; i <= nx; i++) {
    std::cout << del2_host(i) << " , ";
  }
  std::cout << std::endl;
}
Clone this wiki locally