Core containers

Axom Core contains the Array and StackArray classes. Among other things, these data containers facilitate porting code that uses std::vector to the GPU.

Here’s an example showing how to use Array instead of std::vector.

  // Here is an Array of ints with length three.
  axom::Array<int> a(3);
  std::cout << "Length of a = " << a.size() << std::endl;
  a[0] = 2;
  a[1] = 5;
  a[2] = 11;

  // An Array increases in size if a value is appended.
  std::cout << "After appending a value, a's length = " << a.size() << std::endl;

  // You can also insert a value in the middle of the Array.
  // Here we insert value 6 at position 2 and value 1 and position 4.
  showArray(a, "a");
  a.insert(6, 2);
  a.insert(1, 4);
  std::cout << "After inserting two values, ";
  showArray(a, "a");

Applications commonly store tuples of data in a flat array or a std::vector. The Array class formalizes tuple storage, as shown in the next example.

  // Here is an Array of ints, containing two triples.
  axom::Array<int> b(2, 3);
  // Set tuple 0 to (1, 4, 2).
  b(0, 0) = 1;
  b(0, 1) = 4;
  b(0, 2) = 2;
  // Set tuple 1 to one tuple, (8, 0, -1).
  // The first argument to set() is the buffer to copy into the Array, the
  // second is the number of tuples in the buffer, and the third argument
  // is the first tuple to fill from the buffer.
  int ival[3] = {8, 0, -1};
  b.set(ival, 1, 1);

  showTupleArray(b, "b");

  // Now, insert two tuples, (0, -1, 1), (1, -1, 0), into the Array, directly
  // after tuple 0.
  int jval[6] = {0, -1, 1, 1, -1, 0};
  b.insert(jval, 2, 1);

  showTupleArray(b, "b");

The Array class can use an external memory buffer, with the restriction that operations that would cause the buffer to resize are not permitted.

  // The internal buffer maintained by an Array is accessible.
  int* pa = a.getData();
  // An Array can be constructed with a pointer to an external buffer.
  // Here's an Array interpreting the memory pointed to by pa as three 2-tuples.
  axom::Array<int> c(pa, 3, 2);

  showTupleArray(c, "c");

  // Since c is an alias to a's internal memory, changes affect both Arrays.
  a(0, 0) = 1;
  c(1, 1) = 9;

  std::cout << "Arrays a and c use the same memory, a's internal buffer."
            << std::endl;
  showArray(a, "a");
  showTupleArray(c, "c");

Similar to std::vector, when using an internal array the Array class can reserve memory in anticipation of future growth as well as shrink to just the memory currently in use.

The StackArray class is a work-around for a limitation in the nvcc compiler, which can’t capture arrays on the stack in device lambdas. More details are in the API documentation and in the tests.