Unify shared variables and arrays

Issue #11 resolved
Amir Kamil created an issue

Shared variables and arrays both represent distributed data, and their similarities raise the possibility of unifying them into a single class template. With template specialization, we could unify other distributed types as well, such as shared locks. The following is a proposal to unify shared variables and arrays, leaving aside shared locks for the moment.

In order for this to work, the current semantic distinction between shared variables and arrays, that the former represent data while the latter metadata, needs to be resolved one way or another. More specifically, they should have the same restrictions on declaration, definition, construction, and destruction, as well as whether or not they can be used as function arguments or passed between ranks. One way to resolve this is to make shared variables act like global references, which shouldn't break existing code.

We introduce a shared class template to represent both shared variables and arrays. The generic template would represent a shared variable:

template<class T> class shared {
  ...
};

The following specialization would represent shared arrays:

template<class T> class shared<T[]> {
  ...
};

Then the following would declare a shared variable or array:

shared<int> a;        // a shared variable of type int
shared<int *> b;      // a shared variable of type int *
shared<int[]> c;      // a shared array of int elements
shared<int[3]> d;     // a shared variable of type int[3]
shared<int[][4]> e;   // a shared array of int[4] elements
shared<int[5][6]> f;  // a shared variable of type int[5][6]

I think we need to think about cases d and f. In the above scheme, we've only provided a specialization for incomplete array types. Complete array types default to the generic shared variable template. We could provide a specialization for complete array types as well:

template<class T, size_t N> class shared<T[N]> {
  ...
};

However, we would need to define what this means. Is this a shared array of size N that is distributed across all ranks, with distribution specified on construction? Or is it a coarray? If this specialization is provided, then d and f would mean the following:

shared<int[3]> d;     // a shared array or coarray of int with size 3
shared<int[5][6]> f;  // a shared array or coarray of int[6] with size 5

I don't think this scheme solves the intuitiveness issue with f above. It would be nice if we could specialize arbitrary-dimensional arrays, with something like the following:

template<class T, size_t... N> struct shared<T[N]...> {
  ...
};

Unfortunately, C++ specifies that parameter unpacks are comma-separated, so instead of expanding to shared<T[N1][N2]...[Nk]>, it expands to something like shared<T[N1], T[N2], ..., T[Nk]>. Given this restriction, it may be better just to keep the first scheme, where d and f are just shared variables.

Comments?

Comments (2)

  1. Log in to comment