From: Dan Bonachea (bonachea_at_cs_dot_berkeley_dot_edu)
Date: Thu Feb 03 2005 - 23:55:38 PST
At 02:48 PM 2/2/2005, Andrew A. Johnson wrote: >I have a quick UPC question involving shared arrays >and dynamic memory allocation. In the examples, to >create a sharred array of size "N", I can do: > > shared [N/THREADS] int array[N]; > >For example, if N is 9 and THREADS is 3 (i.e. 3 processors), >this would give me a 1D array with the layout > > array[0] -> affinity to 0 > array[1] -> affinity to 0 > array[2] -> affinity to 0 > array[3] -> affinity to 1 > array[4] -> affinity to 1 > array[5] -> affinity to 1 > array[6] -> affinity to 2 > array[7] -> affinity to 2 > array[8] -> affinity to 2 > >so it is basically a 1D array, split evenly >into chunks of THREADS processors. > >Ok, in most application codes (and the big >new code I'm contemplating use with UPC), N >is never known at compile time, and is a >user-input variable for the size of the data set >(i.e. the total length of this 1D array I want). > >My question is, How do I get this same data layout >when "N" is a variable only known at run time? > >I've been trying to use pointers and the upc >dynamic memory allocation functions, but having >trouble getting it to lay-out the data this way. > >I'm using the UPC compiler on the Cray X1, >if that helps... > >Thanks, Andrew > >-- >Andrew A. Johnson, Ph.D. >Army HPC Research Center / NetworkCS, Inc. >612.337.3415 ajohn_at_ahpcrc_dot_org > Hi Andrew - I'm copying your question to the upc-libs list, because we've had some relevant discussions there. You can allocate the data with this layout using a call such as: int my_block_elems = N/THREADS; // assuming THREADS divides N evenly int num_blocks = N/my_block_elems; shared [1] int *array = upc_all_alloc(num_blocks, my_block_elems*sizeof(int)); This will allocate the heap data blocks as you wish, however the real trouble is declaring a pointer which will conveniently access them using a non-compile time constant blocksize. The pointer above has blocksize 1, so (for THREADS==3) this gives: array[0] -> affinity to 0 array[1] -> affinity to 1 array[2] -> affinity to 2 array[3] -> affinity to 0 array[4] -> affinity to 1 array[5] -> affinity to 2 array[6] -> affinity to 0 array[7] -> affinity to 1 array[8] -> affinity to 2 UPC currently requires all pointer blocksizes to have a compile-time constant size, so there's no way convenient way to get the same effect for a non-constant block size. However, given the declaration above, you can get a pointer to the start of the ith block like this: int i; shared [] int *ith_block = (shared [] int *)&(array[i*my_block_elems]); and then access the elements of the block as ith_block[0], ith_block[1], etc There has been some discussion of macros, libraries or even language support to make this translation more convenient, but nothing standardized has yet emerged. Dan