message: Add halo exchange reference implementation
diff: ///
  /// HALOEXCHANGE kernel reference implementation:
  ///
  -/// for (Index_type z = 0; z < num_z; ++z ) {
  -/// for (Index_type g = 0; g < num_g; ++g ) {
  -/// for (Index_type m = 0; z < num_m; ++m ) {
  -/// for (Index_type d = 0; d < num_d; ++d ) {
  -///
  -/// phi[m+ (g * num_m) + (z * num_m * num_g)] +=
  -/// ell[d+ (m * num_d)] * psi[d+ (g * num_d) + (z * num_d * num_g];
  -///
  -/// }
  +/// // pack message for each neighbor
  +/// for (Index_type l = 0; l < num_neighbors; ++l) {
  +/// Real_ptr buffer = buffers[l];
  +/// Int_ptr list = pack_index_lists[l];
  +/// Index_type len = pack_index_list_lengths[l];
  +/// // pack part of each variable
  +/// for (Index_type v = 0; v < num_vars; ++v) {
  +/// Real_ptr var = vars[v];
  +/// for (Index_type i = 0; i < len; i++) {
  +/// HALOEXCHANGE_PACK_BODY;
  /// }
  +/// buffer += len;
  /// }
  +/// // send message to neighbor
  /// }
  ///
  -/// The RAJA variants of this kernel use RAJA multi-dimensional data layouts
  -/// and views to do the same thing without explicit index calculations (see
  -/// the loop body definitions below).
  +/// // unpack messages for each neighbor
  +/// for (Index_type l = 0; l < num_neighbors; ++l) {
  +/// // receive message from neighbor
  +/// Real_ptr buffer = buffers[l];
  +/// Int_ptr list = unpack_index_lists[l];
  +/// Index_type len = unpack_index_list_lengths[l];
  +/// // unpack part of each variable
  +/// for (Index_type v = 0; v < num_vars; ++v) {
  +/// Real_ptr var = vars[v];
  +/// for (Index_type i = 0; i < len; i++) {
  +/// HALOEXCHANGE_UNPACK_BODY;
  +/// }
  +/// buffer += len;
  +/// }
  +/// }
  ///
  #ifndef RAJAPerf_Apps_HALOEXCHANGE_HPP
  