I'm working on porting a distributed memory Samplesort from MPI+C to Chapel, and I've been unable to find an idiomatic/clean way to return the sorted data in a single distributed array.
The C Samplesort is called from within each MPI process, and is passed a portion of the global data to be sorted. This was pretty simple to do in Chapel - I created a Block-distributed array, and the owner of each subdomain reads the appropriate data from disk into its portion of the array.
The actual Samplesort can then run, with the data evenly distributed among each locale. The difficult part comes at the end of the sort; since the data are randomized, the Samplesort assigns an uneven (but roughly similar) range of elements to each Locale. That is, if I'm sorting N records on P nodes, each node starts with N/P records, but after shuffling some may end up with slightly more than N/P records.
In MPI+C, this isn't that hard to handle - I know how many elements each process will receive from all the other processes, so I can dynamically allocate enough memory on each node to receive all the records from the other processes. This is also easily doable in Chapel - each locale (with a bit of bookkeeping) can figure out how many records it's going to need to fetch from the other locales, so it can create a local array of the correct size. However, to make the API convenient and self-contained, I'd like to pass the Samplesort procedure the Block-distributed array and get back a reference to another Block-distributed array containing the sorted data.
To that end, I've been unable to find a good way to create a distributed array that assigns space to each locale to store the uneven number of elements that they end up with at the end of the sort. Is there a built-in idiomatic way to do this in Chapel?
The best alternative I've come up with is to populate a distributed array of references, one per locale, which point to the locale-specific arrays of unequal size. However, this seems like a bit of a hack in that you provide the Samplesort a single array and you receive an array of references to other arrays back.