Re: UPC Dynamic Memory Data Layout Problem

From: Dan Bonachea (bonachea_at_cs_dot_berkeley_dot_edu)
Date: Thu Feb 03 2005 - 23:55:38 PST

  • Next message: bugzilla-daemon_at_mantis_dot_lbl_dot_gov: "[Bug 932] Constant indexing into array of structs crashes translator"
    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
    

  • Next message: bugzilla-daemon_at_mantis_dot_lbl_dot_gov: "[Bug 932] Constant indexing into array of structs crashes translator"