File: iterator.c

package info (click to toggle)
ga 5.9.2-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 18,472 kB
  • sloc: ansic: 192,963; fortran: 53,761; f90: 11,218; cpp: 5,784; makefile: 2,248; sh: 1,945; python: 1,734; perl: 534; csh: 134; asm: 106
file content (194 lines) | stat: -rw-r--r-- 5,315 bytes parent folder | download | duplicates (7)
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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
#if HAVE_CONFIG_H
#   include "config.h"
#endif

/** @file iterator.h
 *  @author Sriram Krishnamoorthy
 *  @brief Stride iterator.
 *  An iterator for the stride descriptor to reuse common traversal
 *  functionality. More functionality related to the strided
 *  descriptor reusable across files will be extracted here as well. 
 */
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

#include "iterator.h"

/**Create a stride iterator.
 * @param base_ptr IN Starting pointer for stride descriptor
 * @param stride_levels IN #stride levels
 * @param stride_arr IN the strides (arr of size[stride_levels])
 * @param seg_count IN #segments in each stride
 * level([stride_levels+1])  
 * @return Handle to stride iterator created
 */
void armci_stride_info_init(stride_info_t *sinfo,
			    void *base_ptr,
			    int stride_levels,
			    const int *stride_arr,
			    const int *seg_count) {
  int i;
  assert(sinfo!=NULL);
  assert(stride_levels>=0);
  assert(stride_levels<=ARMCI_MAX_STRIDE_LEVEL);
  for(i=0; i<stride_levels; i++) {
    if(i==0) 
      assert(stride_arr[0] >= seg_count[0]);
    else 
      assert(stride_arr[i] >= stride_arr[i-1]*seg_count[i]);
  }

  sinfo->base_ptr= base_ptr;
  sinfo->stride_levels = stride_levels;
  for(i=0; i<stride_levels; i++) {
    sinfo->stride_arr[i] = stride_arr[i];
  }
  for(i=0; i<stride_levels+1; i++) {
    sinfo->seg_count[i] = seg_count[i];
  }
  sinfo->size=1;
  for(i=1; i<stride_levels+1; i++) {
    sinfo->size *= sinfo->seg_count[i];
  }
  assert(sinfo->size>0);
  sinfo->pos=0;
  for(i=0; i<stride_levels+1; i++) {
    sinfo->itr[i] = 0;
  }
}

/**Destroy a stride iterator.
 * @param psitr IN/OUT Pointer to stride iterator
 * @return void
 */
void armci_stride_info_destroy(stride_info_t *sinfo) {
}

/**Size of the stride iterator. Defined as total #contiguous
 * segments in the stride iterator.
 * @param sitr IN Handle to stride iterator
 * @return Size of the stride iterator
 */
int armci_stride_info_size(stride_info_t *sinfo) {
  assert(sinfo!=NULL);
  return sinfo->size;
}

/**Position of the stride iterator. Between 0 and (size-1),
 * inclusive. Position is the index of the contiguous segment
 * currently traversed by the iterator.
 * @param sitr IN Handle to stride descriptor
 * @return Position of the iterator
 */
int armci_stride_info_pos(stride_info_t *sinfo) {
  assert(sinfo!=NULL);
  return sinfo->pos;
}

/**Move the iterator to the next position. Assumes position<=size.
 * @param sitr IN Handle to stride descriptor
 * @return void
 */
void armci_stride_info_next(stride_info_t *sinfo) {
  int i;
  assert(sinfo!=NULL);
  assert(sinfo->pos <sinfo->size);
  sinfo->pos += 1;
  if(sinfo->stride_levels>0) {
    sinfo->itr[0] += 1;
    for(i=0; i<sinfo->stride_levels-1 && sinfo->itr[i]==sinfo->seg_count[i+1]; i++) {
      sinfo->itr[i] = 0;
      sinfo->itr[i+1] += 1;
    }
    assert(sinfo->itr[i] <= sinfo->seg_count[i+1]);
  }
}

/**Get pointer to the contiguous segment currently being
 * traversed. This is the pointer to the user buffer.
 * @param sitr IN Handle to stride descriptor
 * @return pointer to current contiguous segment
 */
void *armci_stride_info_seg_ptr(stride_info_t *sinfo) {
  assert(sinfo!=NULL);
  return sinfo->base_ptr + armci_stride_info_seg_off(sinfo);
}

/**Get the size of the current segment.
 * @param sitr IN Handle to stride descriptor
 * @return Size of the current segment
 */
int armci_stride_info_seg_size(stride_info_t *sinfo) {
  assert(sinfo!=NULL);
  return sinfo->seg_count[0];
}


/**Get the offset of the current segment with respect to the start of
 * the first segment (a.k.a src_ptr)
 * @param sitr IN Handle to stride descriptor
 * @return Offset of the current segment
 */
int armci_stride_info_seg_off(stride_info_t *sinfo) {
  int i;
  int off;
  assert(sinfo!=NULL);
  
  off=0;
  for(i=0; i<sinfo->stride_levels; i++) {
    off += sinfo->itr[i] * sinfo->stride_arr[i];
  }
  return off;
}

/**Check if there are more segments to iterate over. (a.k.a
 * position<size).
 * @param sitr IN Handle to stride descriptor
 * @return Zero if current position is past the size of the
 * iterator. Non-zero otherwise. 
 */
int armci_stride_info_has_more(stride_info_t *sinfo) {
  assert(sinfo!=NULL);
  return sinfo->pos<sinfo->size;
}


void armci_write_strided(
        void *ptr, int stride_levels, int stride_arr[], int count[], char *buf)
{
  const int seg_size = count[0];
  int off;
  stride_info_t sitr;
  off=0;
  assert(count[0]>0);
  armci_stride_info_init(&sitr,ptr,stride_levels,stride_arr,count);
  while(armci_stride_info_has_more(&sitr)) {
    char *sptr = armci_stride_info_seg_ptr(&sitr);
    memcpy(&buf[off],sptr,seg_size);
    off += seg_size;
    armci_stride_info_next(&sitr);
  }
  armci_stride_info_destroy(&sitr);
}


void armci_read_strided(
        void *ptr, int stride_levels, int stride_arr[], int count[], char *buf)
{
  const int seg_size = count[0];
  int off;
  stride_info_t sitr;
  off=0;
  assert(count[0]>0);
  armci_stride_info_init(&sitr,ptr,stride_levels,stride_arr,count);
  while(armci_stride_info_has_more(&sitr)) {
    char *dptr = armci_stride_info_seg_ptr(&sitr);
    memcpy(dptr,&buf[off],seg_size);
    off += seg_size;
    armci_stride_info_next(&sitr);
  }
  armci_stride_info_destroy(&sitr);
}