C++ Multi-Dimensional Arrays For Computational Physics and Applied Mathematics - Pramod Gupta - CppCon 2015
C++ Multi-Dimensional Arrays For Computational Physics and Applied Mathematics - Pramod Gupta - CppCon 2015
Pramod Gupta
Research Scientist
Department of Astronomy
University of Washington
Multi-Dimensional Arrays
and Standard C++
Multi-dimensional arrays in Physics
● Temperature field
double Temperature[Lx][Ly][Lz];
int i, j, s;
s=0;
for(i=0;i<n;i++){
for(j=0;j<m;j++){
s=s+b[i][j];
}
}
return s;
}
//Valid C99.
//Valid C++.
//Correct if and only if m=3.
//Sum all elements of 2D array.
int sum(int n, int m, int b[][3]){
int i, j, s;
s=0;
for(i=0;i<n;i++){
for(j=0;j<m;j++){
s=s+b[i][j];
}
}
return s;
}
C Variable Length Arrays
● C variable length arrays (VLA) are not allowed
by a compiler for C++ even though the same
compiler supports them for C.
● gcc, clang, icc compilers support VLA for .c
files but not for identical .cpp files.
● C variable length arrays are more
general than needed for passing
multi-dimensional arrays to functions.
//Valid C99.
//Not valid C++.
. . . . . .
}
Argument against VLA
● Lots of features
Algebra
Armadillo
arrays)
Eigen
● http://blitz.sourceforge.net/
● Lots of features
● N-dimensional arrays
● http://www.boost.org/doc/libs/1_58_0/libs/m
ulti_array/doc/index.html
● Inspired by Blitz++
● Lots of features
● Complicated syntax
#include "boost/multi_array.hpp"
#include <cassert>
//example from Boost web-site
int main () {
// Create a 3D array that is 3 x 4 x 2
typedef boost::multi_array<double, 3>
array_type;
typedef array_type::index index;
array_type A(boost::extents[3][4][2]);
}
Drawbacks of Existing Libraries
#include “ orca_array.hpp”
using namespace orca_array;
//defining 2D array
array2d<double> b(10,8);
//using 2D array
b.at(3,4)=3.14;
#define ARRAY_BOUNDS_CHECK 1
column-major vs row-major
#define FORTRAN_ORDER 1
First index changes fastest
#define FORTRAN_ORDER 0
Last index changes fastest (C order)
#include "orca_array.hpp"
//example for orca_array
using namespace orca_array;
int main () {
// Create a 3D array that is 3 x 4 x 2
array3d<double> A(3,4,2);
}
Performance
● Correct answer to every performance questions
is “It Depends”.
● It depends on the CPU, cache size, memory,
disk, compiler, compiler options, type of
problem, size of problem, algorithm etc.
● Actually running the code (many times) is the
only reliable way of estimating performance.
orca_array Performance
● For code accessing array elements on LHS and RHS
of assignment operator, orca_array performance is
within few percent of native array performance.
● g++/gcc -O3, clang/clang++ -O3, icpc/icc -O3
● Number of elements in array must be large enough
and/or number of array computations must be large
enough.
● For small arrays with small number of computations,
orca_array is slower than native arrays possibly due to
overhead for dynamic allocation of memory and
compiler optimization for native arrays. However,
performance is very good in absolute terms.
template <class array_element_type>
class array2d{
private:
//number of rows
int size1;
//number of columns
int size2;
array_element_type * internal_array;
private:
//prohibit copy constructor
array2d( array2d &);
}//end of constructor
//destructor
public:
~array2d(){
delete [] internal_array;
}
public:
#if ARRAY_BOUNDS_CHECK == 1
#endif
// at() (continued)
#if FORTRAN_ORDER == 1
//fortran convention
//first index changes fastest
return internal_array[x2*size1 + x1];
#else
//C convention
//last index changes fastest
return internal_array[x1*size2 + x2];
#endif
}
//For array7d the at() function
//contains below code. F1.. F7 and
// C1..C7 are related to sizes of
// array dimensions size1, ...size7
#if FORTRAN_ORDER == 1
//fortran convention
//first index changes fastest
return internal_array[x7*F7 + x6*F6 +
x5*F5 + x4*F4 + x3*F3 + x2*F2 +x1*F1];
#else
//C convention
//last index changes fastest
return internal_array[x1*C1 + x2*C2 +
x3*C3 + x4*C4 + x5*C5 + x6*C6 + x7*C7];
#endif
Conclusions
● orca_array library for multi-dimensional arrays
is convenient to use and convenient to include
with scientific applications.
● User “manual” is a few lines only.
● It has compile times option for array bounds
checking and for C-order or Fortran-order
access.
● It has good performance.
● orca_array repository on github
Questions?