File: decompose_block.c

package info (click to toggle)
adios 1.13.1-31
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 23,692 kB
  • sloc: ansic: 133,236; f90: 8,791; sh: 7,779; python: 7,648; xml: 3,793; makefile: 2,996; cpp: 2,340; java: 626; sed: 16; perl: 8
file content (91 lines) | stat: -rw-r--r-- 2,714 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
/* 
Decompose arrays in all dimensions (block), evenly among 
the processes. 

Does not care how small the blocks become, so small arrays
with many writers may suffer with this approach.

*/

#include "decompose.h"
#include "utils.h"

void decompose (int numproc, int rank, int ndim, uint64_t *dims, 
                int *np, // number of processes in each dimension
                /*OUT*/ uint64_t *count,
                /*OUT*/ uint64_t *start,
                /*OUT*/ uint64_t *writesize)
{
    int i;
    int pos[10]; // rank's position in each dimensions

    if (ndim == 0) {
        // scalars -> rank 0 writes them
        if (rank == 0) 
            *writesize = 1;
        else 
            *writesize = 0;
        return;
    }

    /* calculate this process' position in the n-dim space
        0 1 2
        3 4 5
        6 7 8

        for 1D: 
        posx = rank/1             ! 1st dim: 0, 1, 2...,rank-1 are in the same X position
    
        for 2D: 
        posx = mod(rank, npx)     ! 1st dim: 0, npx, 2npx... are in the same X position
        posy = rank/(npx)         ! 2nd dim: npx processes belong into one dim

        for 3D: 
        posx = mod(rank, npx)     ! 1st dim: 0, npx, 2npx... are in the same X position
        posy = mod(rank/npx, npy) ! 2nd dim: (0, npx-1) have the same dim (so divide with npx first)
        posz = rank/(npx*npy)     ! 3rd dim: npx*npy processes belong into one dim
    */
    int nps = 1;
    for (i=0; i<ndim-1; i++)
    {
        pos[i] = (rank / nps) % np[i];
        nps *= np[i];
    }
    pos[i] = rank / nps;

    char ints[256];
    ints_to_str(ndim, pos, ints);
    if (pos[ndim-1] >= np[ndim-1]) {
        print("rank %d: position in %d-D space = %s ---> Out of bound process\n", rank, ndim, ints);
    } else {
        //print("rank %d: position in %d-D space = %s\n", rank, ndim, ints);
    }

    /* Decompose each dimension according to the position */
    *writesize = 1;
    for (i=0; i<ndim; i++)
    {
        if (pos[ndim-1] >= np[ndim-1]) 
        {
            // this process gets nothing to read
            count[i] = 0;
            start[i] = 0;
        } 
        else 
        {
            count[i] = dims[i] / np[i];
            start[i] = count[i] * pos[i];
            if (pos[i] == np[i]-1) {
                // last one in the dimension may need to read more than the rest
                count[i] = dims[i] - count[i]*(np[i]-1);
            }
        }
        *writesize *= count[i];
    }
    int64s_to_str(ndim, count, ints);
    //print("rank %d: ldims   in %d-D space = %s\n", rank, ndim, ints);
    int64s_to_str(ndim, start, ints);
    //print("rank %d: offsets in %d-D space = %s\n", rank, ndim, ints);
}