[1022] | 1 | /********************************************************************* |
---|
| 2 | * Copyright 1993, UCAR/Unidata |
---|
| 3 | * See netcdf/COPYRIGHT file for copying and redistribution conditions. |
---|
| 4 | * $Header: /upc/share/CVS/netcdf-3/libncdap3/dapodom.c,v 1.12 2010/05/27 21:34:08 dmh Exp $ |
---|
| 5 | *********************************************************************/ |
---|
| 6 | |
---|
| 7 | #include "ncdap3.h" |
---|
| 8 | #include "dapodom.h" |
---|
| 9 | |
---|
| 10 | /**********************************************/ |
---|
| 11 | /* Define methods for a dimension dapodometer*/ |
---|
| 12 | |
---|
| 13 | Dapodometer* |
---|
| 14 | newdapodometer(DCEslice* slices, unsigned int first, unsigned int rank) |
---|
| 15 | { |
---|
| 16 | int i; |
---|
| 17 | Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer)); |
---|
| 18 | MEMCHECK(odom,NULL); |
---|
| 19 | if(rank == 0) { |
---|
| 20 | return newdapodometer1(1); |
---|
| 21 | } |
---|
| 22 | odom->rank = rank; |
---|
| 23 | ASSERT(odom->rank <= NC_MAX_VAR_DIMS); |
---|
| 24 | for(i=0;i<odom->rank;i++) { |
---|
| 25 | DCEslice* slice = slices+(first+i); |
---|
| 26 | odom->slices[i] = *slice; |
---|
| 27 | odom->index[i] = odom->slices[i].first; |
---|
| 28 | } |
---|
| 29 | return odom; |
---|
| 30 | } |
---|
| 31 | |
---|
| 32 | Dapodometer* |
---|
| 33 | newsimpledapodometer(DCEsegment* segment, unsigned int rank) |
---|
| 34 | { |
---|
| 35 | int i; |
---|
| 36 | Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer)); |
---|
| 37 | MEMCHECK(odom,NULL); |
---|
| 38 | if(rank == 0) { |
---|
| 39 | return newdapodometer1(1); |
---|
| 40 | } |
---|
| 41 | odom->rank = rank; |
---|
| 42 | assert(odom->rank <= NC_MAX_VAR_DIMS); |
---|
| 43 | assert(segment->slicesdefined && segment->slicesdeclized); |
---|
| 44 | for(i=0;i<odom->rank;i++) { |
---|
| 45 | DCEslice* odslice = &odom->slices[i]; |
---|
| 46 | DCEslice* segslice = &segment->slices[i]; |
---|
| 47 | odslice->first = 0; |
---|
| 48 | odslice->stride = 1; |
---|
| 49 | odslice->declsize = segslice->count; |
---|
| 50 | odslice->length = odslice->declsize; |
---|
| 51 | odslice->stop = odslice->declsize; |
---|
| 52 | odslice->count = odslice->declsize; |
---|
| 53 | odom->index[i] = 0; |
---|
| 54 | } |
---|
| 55 | return odom; |
---|
| 56 | } |
---|
| 57 | |
---|
| 58 | Dapodometer* |
---|
| 59 | newdapodometer1(unsigned int count) |
---|
| 60 | { |
---|
| 61 | Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer)); |
---|
| 62 | MEMCHECK(odom,NULL); |
---|
| 63 | odom->rank = 1; |
---|
| 64 | odom->slices[0].first = 0; |
---|
| 65 | odom->slices[0].length = count; |
---|
| 66 | odom->slices[0].stride = 1; |
---|
| 67 | odom->slices[0].stop = count; |
---|
| 68 | odom->slices[0].declsize = count; |
---|
| 69 | odom->slices[0].count = count; |
---|
| 70 | odom->index[0] = 0; |
---|
| 71 | return odom; |
---|
| 72 | } |
---|
| 73 | |
---|
| 74 | void |
---|
| 75 | freedapodometer(Dapodometer* odom) |
---|
| 76 | { |
---|
| 77 | if(odom) free(odom); |
---|
| 78 | } |
---|
| 79 | |
---|
| 80 | char* |
---|
| 81 | dapodometerprint(Dapodometer* odom) |
---|
| 82 | { |
---|
| 83 | int i; |
---|
| 84 | static char line[1024]; |
---|
| 85 | char tmp[64]; |
---|
| 86 | line[0] = '\0'; |
---|
| 87 | if(odom->rank == 0) { |
---|
| 88 | strcat(line,"[]"); |
---|
| 89 | } else for(i=0;i<odom->rank;i++) { |
---|
| 90 | sprintf(tmp,"[%lu/%lu:%lu:%lu]", |
---|
| 91 | (unsigned long)odom->index[i], |
---|
| 92 | (unsigned long)odom->slices[i].first, |
---|
| 93 | (unsigned long)odom->slices[i].stride, |
---|
| 94 | (unsigned long)odom->slices[i].length); |
---|
| 95 | strcat(line,tmp); |
---|
| 96 | } |
---|
| 97 | return line; |
---|
| 98 | } |
---|
| 99 | |
---|
| 100 | int |
---|
| 101 | dapodometermore(Dapodometer* odom) |
---|
| 102 | { |
---|
| 103 | return (odom->index[0] < odom->slices[0].stop); |
---|
| 104 | } |
---|
| 105 | |
---|
| 106 | void |
---|
| 107 | dapodometerreset(Dapodometer* odom) |
---|
| 108 | { |
---|
| 109 | int rank = odom->rank; |
---|
| 110 | while(rank-- > 0) {odom->index[rank] = odom->slices[rank].first;} |
---|
| 111 | } |
---|
| 112 | |
---|
| 113 | /* Convert current dapodometer settings to a single integer count*/ |
---|
| 114 | size_t |
---|
| 115 | dapodometercount(Dapodometer* odom) |
---|
| 116 | { |
---|
| 117 | int i; |
---|
| 118 | size_t offset = 0; |
---|
| 119 | for(i=0;i<odom->rank;i++) { |
---|
| 120 | offset *= odom->slices[i].declsize; |
---|
| 121 | offset += odom->index[i]; |
---|
| 122 | } |
---|
| 123 | return offset; |
---|
| 124 | } |
---|
| 125 | |
---|
| 126 | /* |
---|
| 127 | Given a dapodometer, compute the total |
---|
| 128 | number of elements in its space |
---|
| 129 | as determined by declsize; start at |
---|
| 130 | offset wheel |
---|
| 131 | */ |
---|
| 132 | |
---|
| 133 | size_t |
---|
| 134 | dapodometerspace(Dapodometer* odom, unsigned int wheel) |
---|
| 135 | { |
---|
| 136 | unsigned int i,rank = odom->rank; |
---|
| 137 | size_t count = 1; |
---|
| 138 | DCEslice* slice; |
---|
| 139 | ASSERT((wheel < rank)); |
---|
| 140 | slice = odom->slices+wheel; |
---|
| 141 | for(i=wheel;i<rank;i++,slice++) { |
---|
| 142 | count *= slice->declsize; |
---|
| 143 | } |
---|
| 144 | return count; |
---|
| 145 | } |
---|
| 146 | |
---|
| 147 | /* |
---|
| 148 | Compute the number of elements |
---|
| 149 | that will be returned as the odometer |
---|
| 150 | is incremented to its stop point. |
---|
| 151 | */ |
---|
| 152 | |
---|
| 153 | size_t |
---|
| 154 | dapodometerpoints(Dapodometer* odom) |
---|
| 155 | { |
---|
| 156 | unsigned int i,rank = odom->rank; |
---|
| 157 | size_t count = 1; |
---|
| 158 | DCEslice* slice = odom->slices; |
---|
| 159 | for(i=0;i<rank;i++,slice++) { |
---|
| 160 | size_t slicecount = (slice->length/slice->stride); |
---|
| 161 | count *= slicecount; |
---|
| 162 | } |
---|
| 163 | return count; |
---|
| 164 | } |
---|
| 165 | |
---|
| 166 | int |
---|
| 167 | dapodometerincr(Dapodometer* odom) |
---|
| 168 | { |
---|
| 169 | return dapodometerincrith(odom,-1); |
---|
| 170 | } |
---|
| 171 | |
---|
| 172 | int |
---|
| 173 | dapodometerincrith(Dapodometer* odom, int wheel) |
---|
| 174 | { |
---|
| 175 | int i; /* do not make unsigned */ |
---|
| 176 | DCEslice* slice; |
---|
| 177 | if(odom->rank == 0) return 0; |
---|
| 178 | if(wheel < 0) wheel = (odom->rank - 1); |
---|
| 179 | for(slice=odom->slices+(wheel),i=wheel;i>=0;i--,slice--) { |
---|
| 180 | odom->index[i] += slice->stride; |
---|
| 181 | if(odom->index[i] < slice->stop) break; |
---|
| 182 | if(i == 0) return 0; /* leave the 0th entry if it overflows*/ |
---|
| 183 | odom->index[i] = slice->first; /* reset this position*/ |
---|
| 184 | } |
---|
| 185 | return 1; |
---|
| 186 | } |
---|
| 187 | |
---|
| 188 | /**************************************************/ |
---|
| 189 | int |
---|
| 190 | dapodometervarmcount(Dapodometer* odom, const ptrdiff_t* steps, const size_t* declsizes) |
---|
| 191 | { |
---|
| 192 | int i; |
---|
| 193 | size_t offset = 0; |
---|
| 194 | for(i=0;i<odom->rank;i++) { |
---|
| 195 | size_t tmp; |
---|
| 196 | tmp = odom->index[i]; |
---|
| 197 | tmp = tmp - odom->slices[i].first; |
---|
| 198 | tmp = tmp / odom->slices[i].stride; |
---|
| 199 | tmp = tmp * steps[i]; |
---|
| 200 | offset += tmp; |
---|
| 201 | } |
---|
| 202 | return offset; |
---|
| 203 | } |
---|
| 204 | |
---|
| 205 | |
---|
| 206 | /* Return the current set of indices */ |
---|
| 207 | size_t* |
---|
| 208 | dapodometerindices(Dapodometer* odom) |
---|
| 209 | { |
---|
| 210 | if(odom == NULL) return NULL; |
---|
| 211 | return odom->index; |
---|
| 212 | } |
---|
| 213 | |
---|
| 214 | Dapodometer* |
---|
| 215 | newdapodometer2(const size_t* start, const size_t* count, const ptrdiff_t* stride, |
---|
| 216 | unsigned int first, unsigned int rank) |
---|
| 217 | { |
---|
| 218 | int i; |
---|
| 219 | Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer)); |
---|
| 220 | MEMCHECK(odom,NULL); |
---|
| 221 | odom->rank = rank; |
---|
| 222 | assert(odom->rank <= NC_MAX_VAR_DIMS); |
---|
| 223 | for(i=0;i<odom->rank;i++) { |
---|
| 224 | odom->slices[i].first = start[first+i]; |
---|
| 225 | odom->slices[i].stride = (size_t)stride[first+i]; |
---|
| 226 | odom->slices[i].length = count[first+i] * stride[first+i]; |
---|
| 227 | odom->slices[i].stop = (odom->slices[i].first+odom->slices[i].length); |
---|
| 228 | odom->slices[i].declsize = odom->slices[i].stop; |
---|
| 229 | odom->slices[i].count = (odom->slices[i].length /odom->slices[i].stride); |
---|
| 230 | odom->index[i] = odom->slices[i].first; |
---|
| 231 | } |
---|
| 232 | return odom; |
---|
| 233 | } |
---|
| 234 | |
---|
| 235 | Dapodometer* |
---|
| 236 | newdapodometer3(int rank, size_t* dimsizes) |
---|
| 237 | { |
---|
| 238 | int i; |
---|
| 239 | Dapodometer* odom = (Dapodometer*)calloc(1,sizeof(Dapodometer)); |
---|
| 240 | MEMCHECK(odom,NULL); |
---|
| 241 | odom->rank = rank; |
---|
| 242 | for(i=0;i<rank;i++) { |
---|
| 243 | odom->slices[i].first = 0; |
---|
| 244 | odom->slices[i].length = dimsizes[i]; |
---|
| 245 | odom->slices[i].stride = 1; |
---|
| 246 | odom->slices[i].stop = dimsizes[i]; |
---|
| 247 | odom->slices[i].declsize = dimsizes[i]; |
---|
| 248 | odom->slices[i].count = (odom->slices[i].length / odom->slices[i].stride); |
---|
| 249 | odom->index[i] = 0; |
---|
| 250 | } |
---|
| 251 | return odom; |
---|
| 252 | } |
---|