void Scheduler::run() { _running = true; AbstractTask* task; while (!cyclic() && (!empty() || waiting()) && !_throwing) { if (!empty()) { task = top()._task; *(task->_context) = std::get<0>((*(task->_context))(task)); } checkFutures(); } if (cyclic()) { throw Cycle(cycle()); } if (_throwing) { std::rethrow_exception(_throwing); } _running = false; }
void cyclic(value_t values[6][MAX_VALUES], int remaining[6], char chain[6][5], int clen) { if(clen == 6) { // make sure first and last complete the chain if(chain[0][0] != chain[5][2] || chain[0][1] != chain[5][3]) return; int numbers[6]; for(int i = 0; i < 6; i++) { sscanf(chain[i], "%i", &numbers[i]); } int sum = 0; for(int i = 0; i < 6; i++) { sum += numbers[i]; } printf("%i", sum); exit(0); } else { // recursively call cyclic until a full chain is created for(int i = 0; i < 6; i++) { if(remaining[i] == -1) continue; for(int j = 0; j < MAX_VALUES; j++) { if(values[i][j].n == -1) break; sprintf(chain[clen], "%i", values[i][j].v); if( chain[clen - 1][2] == chain[clen][0] && chain[clen - 1][3] == chain[clen][1]) { remaining[i] = -1; cyclic(values, remaining, chain, clen + 1); remaining[i] = i; } } } } }
int main(int argc, char* argv[]) { value_t values[6][MAX_VALUES]; for(int i = 0; i < 6; i++) { for(int j = 0; j < MAX_VALUES; j++) { values[i][j] = value_init(-1, -1); } } int (*types[6])(int n); types[0] = triangle; types[1] = square; types[2] = pentagonal; types[3] = hexagonal; types[4] = heptagonal; types[5] = octagonal; // generate a full list of each type between 1000 and 10,000 for(int i = 0; i < 6; i++) { int n = 1; int v = 0; int value_ptr = 0; do { v = (*types[i])(n); if(v >= 1000 && v < 10000) { values[i][value_ptr] = value_init(n, v); value_ptr++; } n++; } while(v < 10000); } // recursively generate chains of the numbers until the correct chain is found int remaining[6] = { -1 }; for(int i = 1; i < 6; i++) { remaining[i] = i; } for(int i = 0; i < MAX_VALUES; i++) { if(values[0][i].n == -1) break; char chain[6][5] = { { '\0' } }; sprintf(chain[0], "%i", values[0][i].v); cyclic(values, remaining, chain, 1); } return 0; }
/* Return a simhash value using a moving window */ hash_t operator()(const char* s, size_t length) { /* Simhash works by calculating the hashes of overlaping windows * of the input, and then for each bit of that hash, increments a * corresponding count. At the end, each of the counts is * transformed back into a bit by whether or not the count is * positive or negative */ // Counts int64_t v[64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; hash_t hash(0); // The hash we're trying to produce size_t j(0); // Counter size_t window(3); // How many tokens in rolling hash? const char* next(NULL); // Pointer to the char /after/ token const char* current(s); // String pointers /* Create a tokenizer, hash function, and cyclic */ Hash hasher; Tokenizer tokenizer; Cyclic<hash_t> cyclic(window); next = tokenizer(current); while (next != NULL) { if (next != current) { hash_t r = cyclic.push(hasher(current, next - current, 0)); /* Update the hash array. For each of the bits in the * output hash (whose bits are the union of a and b), * increment or decrement the corresponding count */ for (j = 63; j > 0; --j) { v[j] += (r & 1) ? 1 : -1; r = r >> 1; } v[j] += (r & 1) ? 1 : -1; } current = next + 1; next = tokenizer(current); }
/* Return a simhash value using a moving window */ hash_t operator()(char **tokens) { /* Simhash works by calculating the hashes of overlaping windows * of the input, and then for each bit of that hash, increments a * corresponding count. At the end, each of the counts is * transformed back into a bit by whether or not the count is * positive or negative */ // Counts int64_t v[64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; hash_t hash(0); // The hash we're trying to produce size_t j(0); // Counter size_t window(3); // How many tokens in rolling hash? char **tp; // For stepping through tokens /* Create a tokenizer, hash function, and cyclic */ Hash hasher; Cyclic<hash_t> cyclic(window); for (tp = tokens; *tp != NULL; tp++) { /* puts(*tp); /* debug */ hash_t r = cyclic.push(hasher(*tp, strlen(*tp), 0)); for (j = 63; j > 0; --j) { v[j] += (r & 1) ? 1 : -1; r = r >> 1; } v[j] += (r & 1) ? 1 : -1; } /* With counts appropriately tallied, create a 1 bit for each of * the counts that's positive. That result is the hash. */ for (j = 0; j < 64; ++j) { if (v[j] > 0) { hash = hash | (static_cast<hash_t>(1) << j); } } return hash; }
/* As above, but operate on a vector of unsigned 64-bit numbers, not strings. */ hash_t hash_fp(uint64_t *vec, int len) { // Counts int64_t v[64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; hash_t hash(0); // The hash we're trying to produce size_t j(0); // Counter size_t window(3); // How many tokens in rolling hash? int i; // For stepping through tokens /* Create a tokenizer, hash function, and cyclic */ Hash hasher; Cyclic<hash_t> cyclic(window); for (i = 0; i < len; i++) { hash_t r = cyclic.push(hasher(reinterpret_cast<char*>(vec+i), sizeof(uint64_t), 0)); for (j = 63; j > 0; --j) { v[j] += (r & 1) ? 1 : -1; r = r >> 1; } v[j] += (r & 1) ? 1 : -1; } /* With counts appropriately tallied, create a 1 bit for each of * the counts that's positive. That result is the hash. */ for (j = 0; j < 64; ++j) { if (v[j] > 0) { hash = hash | (static_cast<hash_t>(1) << j); } } return hash; }
void Cyclic_Agent::init(int argc, char** argv) { PatrolAgent::init(argc,argv); //robot's cyclic path: path = new int[8*dimension]; //get cyclic path: path_elements = cyclic(dimension, vertex_web, path); //Shift the cyclic path to start at the current vertex: shift_cyclic_path (current_vertex, path, path_elements); printf("\nFinal Path: "); for(int i=0; i<path_elements; i++){ if(i==path_elements-1){ printf("%i\n", path[i]); }else{ printf("%i, ", path[i]); } } printf("Number of elements = %i\n", path_elements); i_vertex=0; // if (path_elements>1) { i_vertex=1; next_vertex = path[i_vertex]; } }
int32_t ompi_datatype_create_darray(int size, int rank, int ndims, int const* gsize_array, int const* distrib_array, int const* darg_array, int const* psize_array, int order, const ompi_datatype_t* oldtype, ompi_datatype_t** newtype) { ompi_datatype_t *lastType; ptrdiff_t orig_extent, *st_offsets = NULL; int i, start_loop, end_loop, step; int *coords = NULL, rc = OMPI_SUCCESS; /* speedy corner case */ if (ndims < 1) { /* Don't just return MPI_DATATYPE_NULL as that can't be MPI_TYPE_FREE()ed, and that seems bad */ *newtype = ompi_datatype_create(0); ompi_datatype_add(*newtype, &ompi_mpi_datatype_null.dt, 0, 0, 0); return MPI_SUCCESS; } rc = ompi_datatype_type_extent(oldtype, &orig_extent); if (MPI_SUCCESS != rc) goto cleanup; /* calculate position in grid using row-major ordering */ { int tmp_rank = rank, procs = size; coords = (int *) malloc(ndims * sizeof(int)); for (i = 0 ; i < ndims ; i++) { procs = procs / psize_array[i]; coords[i] = tmp_rank / procs; tmp_rank = tmp_rank % procs; } } st_offsets = (ptrdiff_t *) malloc(ndims * sizeof(ptrdiff_t)); /* duplicate type to here to 1) deal with constness without casting and 2) eliminate need to for conditional destroy below. Lame, yes. But cleaner code all around. */ rc = ompi_datatype_duplicate(oldtype, &lastType); if (OMPI_SUCCESS != rc) goto cleanup; /* figure out ordering issues */ if (MPI_ORDER_C == order) { start_loop = ndims - 1 ; step = -1; end_loop = -1; } else { start_loop = 0 ; step = 1; end_loop = ndims; } /* Build up array */ for (i = start_loop; i != end_loop; i += step) { int nprocs, tmp_rank; switch(distrib_array[i]) { case MPI_DISTRIBUTE_BLOCK: rc = block(gsize_array, i, ndims, psize_array[i], coords[i], darg_array[i], order, orig_extent, lastType, newtype, st_offsets+i); break; case MPI_DISTRIBUTE_CYCLIC: rc = cyclic(gsize_array, i, ndims, psize_array[i], coords[i], darg_array[i], order, orig_extent, lastType, newtype, st_offsets+i); break; case MPI_DISTRIBUTE_NONE: /* treat it as a block distribution on 1 process */ if (order == MPI_ORDER_C) { nprocs = psize_array[i]; tmp_rank = coords[i]; } else { nprocs = 1; tmp_rank = 0; } rc = block(gsize_array, i, ndims, nprocs, tmp_rank, MPI_DISTRIBUTE_DFLT_DARG, order, orig_extent, lastType, newtype, st_offsets+i); break; default: rc = MPI_ERR_ARG; } ompi_datatype_destroy(&lastType); /* need to destroy the old type even in error condition, so don't check return code from above until after cleanup. */ if (MPI_SUCCESS != rc) goto cleanup; lastType = *newtype; } /* set displacement and UB correctly. Use struct instead of resized for same reason as subarray */ { ptrdiff_t displs[3], tmp_size; ompi_datatype_t *types[3]; int blength[3] = { 1, 1, 1}; displs[1] = st_offsets[start_loop]; tmp_size = 1; for (i = start_loop + step ; i != end_loop ; i += step) { tmp_size *= gsize_array[i - step]; displs[1] += tmp_size * st_offsets[i]; } displs[0] = 0; displs[1] *= orig_extent; displs[2] = orig_extent; for (i = 0 ; i < ndims ; i++) { displs[2] *= gsize_array[i]; } types[0] = MPI_LB; types[1] = lastType; types[2] = MPI_UB; rc = ompi_datatype_create_struct(3, blength, displs, types, newtype); ompi_datatype_destroy(&lastType); /* need to destroy the old type even in error condition, so don't check return code from above until after cleanup. */ if (MPI_SUCCESS != rc) goto cleanup; } cleanup: if (NULL != st_offsets) free(st_offsets); if (NULL != coords) free(coords); return OMPI_SUCCESS; }
/* returns 0 on success, 1 on error with errno set */ static int calc_lon(privpath_t *pp) { point_t *pt = pp->pt; int n = pp->len; int i, j, k, k1; int ct[4], dir; point_t constraint[2]; point_t cur; point_t off; int *pivk = NULL; /* pivk[n] */ int *nc = NULL; /* nc[n]: next corner */ point_t dk; /* direction of k-k1 */ int a, b, c, d; SAFE_MALLOC(pivk, n, int); SAFE_MALLOC(nc, n, int); /* initialize the nc data structure. Point from each point to the furthest future point to which it is connected by a vertical or horizontal segment. We take advantage of the fact that there is always a direction change at 0 (due to the path decomposition algorithm). But even if this were not so, there is no harm, as in practice, correctness does not depend on the word "furthest" above. */ k = 0; for (i=n-1; i>=0; i--) { if (pt[i].x != pt[k].x && pt[i].y != pt[k].y) { k = i+1; /* necessarily i<n-1 in this case */ } nc[i] = k; } SAFE_MALLOC(pp->lon, n, int); /* determine pivot points: for each i, let pivk[i] be the furthest k such that all j with i<j<k lie on a line connecting i,k. */ for (i=n-1; i>=0; i--) { ct[0] = ct[1] = ct[2] = ct[3] = 0; /* keep track of "directions" that have occurred */ dir = (3+3*(pt[mod(i+1,n)].x-pt[i].x)+(pt[mod(i+1,n)].y-pt[i].y))/2; ct[dir]++; constraint[0].x = 0; constraint[0].y = 0; constraint[1].x = 0; constraint[1].y = 0; /* find the next k such that no straight line from i to k */ k = nc[i]; k1 = i; while (1) { dir = (3+3*sign(pt[k].x-pt[k1].x)+sign(pt[k].y-pt[k1].y))/2; ct[dir]++; /* if all four "directions" have occurred, cut this path */ if (ct[0] && ct[1] && ct[2] && ct[3]) { pivk[i] = k1; goto foundk; } cur.x = pt[k].x - pt[i].x; cur.y = pt[k].y - pt[i].y; /* see if current constraint is violated */ if (xprod(constraint[0], cur) < 0 || xprod(constraint[1], cur) > 0) { goto constraint_viol; } /* else, update constraint */ if (abs(cur.x) <= 1 && abs(cur.y) <= 1) { /* no constraint */ } else { off.x = cur.x + ((cur.y>=0 && (cur.y>0 || cur.x<0)) ? 1 : -1); off.y = cur.y + ((cur.x<=0 && (cur.x<0 || cur.y<0)) ? 1 : -1); if (xprod(constraint[0], off) >= 0) { constraint[0] = off; } off.x = cur.x + ((cur.y<=0 && (cur.y<0 || cur.x<0)) ? 1 : -1); off.y = cur.y + ((cur.x>=0 && (cur.x>0 || cur.y<0)) ? 1 : -1); if (xprod(constraint[1], off) <= 0) { constraint[1] = off; } } k1 = k; k = nc[k1]; if (!cyclic(k,i,k1)) { break; } } constraint_viol: /* k1 was the last "corner" satisfying the current constraint, and k is the first one violating it. We now need to find the last point along k1..k which satisfied the constraint. */ dk.x = sign(pt[k].x-pt[k1].x); dk.y = sign(pt[k].y-pt[k1].y); cur.x = pt[k1].x - pt[i].x; cur.y = pt[k1].y - pt[i].y; /* find largest integer j such that xprod(constraint[0], cur+j*dk) >= 0 and xprod(constraint[1], cur+j*dk) <= 0. Use bilinearity of xprod. */ a = xprod(constraint[0], cur); b = xprod(constraint[0], dk); c = xprod(constraint[1], cur); d = xprod(constraint[1], dk); /* find largest integer j such that a+j*b>=0 and c+j*d<=0. This can be solved with integer arithmetic. */ j = INFTY; if (b<0) { j = floordiv(a,-b); } if (d>0) { j = min(j, floordiv(-c,d)); } pivk[i] = mod(k1+j,n); foundk: ; } /* for i */ /* clean up: for each i, let lon[i] be the largest k such that for all i' with i<=i'<k, i'<k<=pivk[i']. */ j=pivk[n-1]; pp->lon[n-1]=j; for (i=n-2; i>=0; i--) { if (cyclic(i+1,pivk[i],j)) { j=pivk[i]; } pp->lon[i]=j; } for (i=n-1; cyclic(mod(i+1,n),j,pp->lon[i]); i--) { pp->lon[i] = j; } free(pivk); free(nc); return 0; malloc_error: free(pivk); free(nc); return 1; }
int f_cyclic(ARG0) { if (mode >= 0) { sprintf(inv_out,cyclic(sec) ? "cyclic" : "not cyclic"); } return 0; }
int small_domain(unsigned char **sec, double lonW, double lonE, double latS, double latN, int *ix0, int *ix1, int *iy0, int *iy1) { int i, j, k, flag, x0, x1, y0, y1; int X0, X1, Y0, Y1, flag0; double e,w,n,s; double tmp; #ifdef DEBUG printf("\n>> small_domain: lon lat %f:%f %f:%f\n", lonW, lonE, latS, latN); #endif if (GDS_Scan_staggered(scan)) fatal_error("small_domain: does not work for staggered grids",""); if (lat == NULL || lon == NULL) { // no lat-lon information return full grid *ix0 = 1; *ix1 = nx; *iy0 = 1; *iy1 = ny; return 1; } if (lonE < lonW) lonE += 360.0; if (lonE-lonW > 360.0) fatal_error("small_domain: longitude range is greater than 360 degrees",""); if (lonW < 0.0) { lonW += 360.0; lonE += 360.0; } #ifdef DEBUG printf("\n>> small_domain: new lon lat %f:%f %f:%f\n", lonW, lonE, latS, latN); printf(">> small_domain: nx %d ny %d\n", nx, ny); #endif flag0 = 0; // initial point on grid X0 = 1; X1 = nx; Y0 = 1; Y1 = ny; #pragma omp parallel for private (i,j,k,flag,tmp,x0,x1,y0,y1,w,e,n,s) for (j = 1; j <= ny; j++) { x0 = x1 = y0 = y1 = w = e = s = n = -1; flag = 0; // initial point on latitude for (i = 1; i <= nx; i++) { k = (i-1) + (j-1)*nx; tmp = lon[k]; if (tmp < lonW) tmp += 360.0; if (tmp < lonW) tmp += 360.0; // tmp is lon > lon if ( (tmp <= lonE) && (lat[k] >= latS) && (lat[k] <= latN)) { // printf(">> small_domain: i %d j %d lon=%f lat=%f\n",i,j,tmp,lat[k]); if (flag == 0) { x0 = x1 = i; y0 = y1 = j; w = e = tmp; n = s = lat[k]; flag = 1; } if (lat[k] < s) { s = lat[k]; y0 = j; } if (lat[k] > n) { n = lat[k]; y1 = j; } if (tmp > e) { e = tmp; x1 = i; } if (tmp < w) { w = tmp; x0 = i; } } } #pragma omp critical if (flag) { // found points if (x1 < x0 && cyclic(sec)) x1 += nx; if (flag0 == 0) { X0 = x0; X1 = x1; Y0 = y0; Y1 = y1; flag0 = 1; } if (x0 < X0) X0 = x0; if (x1 > X1) X1 = x1; if (y0 < Y0) Y0 = y0; if (y1 > Y1) Y1 = y1; } } #ifdef DEBUG printf(">> small domain: flag0 %d flag %d\n", flag0, flag); #endif if (flag0 && X1 < X0) flag0 = 0; if (flag0 == 0) { *ix0 = 1; *ix1 = nx; *iy0 = 1; *iy1 = ny; return 1; } #ifdef DEBUG printf(">> small domain: ix %d:%d iy %d:%d\n", X0, X1, Y0, Y1); #endif *ix0 = X0; *ix1 = X1; *iy0 = Y0; *iy1 = Y1; return 0; }
int small_grib(unsigned char **sec, int mode, float *data, double *lon, double *lat, unsigned int ndata, int ix0, int ix1, int iy0, int iy1, FILE *out) { int can_subset, grid_template; int nx, ny, res, scan, new_nx, new_ny, i, j; unsigned int sec3_len, new_ndata, k, npnts; unsigned char *sec3, *new_sec[9]; double units; int basic_ang, sub_ang, cyclic_grid; float *new_data; get_nxny(sec, &nx, &ny, &npnts, &res, &scan); /* get nx, ny, and scan mode of grid */ grid_template = code_table_3_1(sec); // make a copy of the gds (sec3) sec3_len = GB2_Sec3_size(sec); sec3 = (unsigned char *) malloc(sec3_len); for (k = 0; k < sec3_len; k++) sec3[k] = sec[3][k]; // make a copy of the sec[] with new sec3 new_sec[0] = sec[0]; new_sec[1] = sec[1]; new_sec[2] = sec[2]; new_sec[3] = sec3; new_sec[4] = sec[4]; new_sec[5] = sec[5]; new_sec[6] = sec[6]; new_sec[7] = sec[7]; // new_sec[8] = sec[8]; not needed by writing routines can_subset = 1; if (lat == NULL || lon == NULL) can_subset = 0; new_nx = ix1-ix0+1; new_ny = iy1-iy0+1; if (new_nx <= 0) fatal_error("small_grib, new_nx is <= 0",""); if (new_ny <= 0) fatal_error("small_grib, new_ny is <= 0",""); new_ndata = new_nx * new_ny; cyclic_grid = 0; if (can_subset) { cyclic_grid = cyclic(sec); // lat-lon grid - no thinning if ((grid_template == 0 && sec3_len == 72) || (grid_template == 1 && sec3_len == 04)) { uint_char(new_nx,sec3+30); // nx uint_char(new_ny,sec3+34); // ny basic_ang = GDS_LatLon_basic_ang(sec3); sub_ang = GDS_LatLon_sub_ang(sec3); if (basic_ang != 0) { units = (double) basic_ang / (double) sub_ang; } else { units = 0.000001; } i = lat[ idx(ix0,iy0,nx,ny,cyclic_grid) ] / units; // lat1 int_char(i,sec3+46); i = lon[ idx(ix0,iy0,nx,ny,cyclic_grid) ] / units; // lon1 int_char(i,sec3+50); i = lat[ idx(ix1,iy1,nx,ny,cyclic_grid) ] / units; // lat2 int_char(i,sec3+55); i = lon[ idx(ix1,iy1,nx,ny,cyclic_grid) ] / units; // lon2 int_char(i,sec3+59); } else if ((grid_template == 40 && sec3_len == 72)) { // full Gaussian grid uint_char(new_nx,sec3+30); // nx uint_char(new_ny,sec3+34); // ny basic_ang = GDS_Gaussian_basic_ang(sec3); sub_ang = GDS_Gaussian_sub_ang(sec3); if (basic_ang != 0) { units = (double) basic_ang / (double) sub_ang; } else { units = 0.000001; } i = lat[ idx(ix0,iy0,nx,ny,cyclic_grid) ] / units; // lat1 int_char(i,sec3+46); i = lon[ idx(ix0,iy0,nx,ny,cyclic_grid) ] / units; // lon1 int_char(i,sec3+50); i = lat[ idx(ix1,iy1,nx,ny,cyclic_grid) ] / units; // lat2 int_char(i,sec3+55); i = lon[ idx(ix1,iy1,nx,ny,cyclic_grid) ] / units; // lon2 int_char(i,sec3+59); } // polar-stereo graphic, lambert conformal , no thinning else if ((grid_template == 20 && sec3_len == 65) || // polar stereographic (grid_template == 30 && sec3_len == 81)) { // lambert conformal uint_char(new_nx,sec3+30); // nx uint_char(new_ny,sec3+34); // ny i = (int) (lat[ idx(ix0,iy0,nx,ny,cyclic_grid) ] * 1000000.0); // lat1 int_char(i,sec3+38); i = (int) (lon[ idx(ix0,iy0,nx,ny,cyclic_grid) ] * 1000000.0); // lon1 int_char(i,sec3+42); } // mercator, no thinning else if (grid_template == 10 && sec3_len == 72) { // mercator uint_char(new_nx,sec3+30); // nx uint_char(new_ny,sec3+34); // ny units = 0.000001; i = lat[ idx(ix0,iy0,nx,ny,cyclic_grid) ] / units; // lat1 int_char(i,sec3+38); i = lon[ idx(ix0,iy0,nx,ny,cyclic_grid) ] / units; // lon1 int_char(i,sec3+42); i = lat[ idx(ix1,iy1,nx,ny,cyclic_grid) ] / units; // lat2 int_char(i,sec3+51); i = lon[ idx(ix1,iy1,nx,ny,cyclic_grid) ] / units; // lon2 int_char(i,sec3+55); } else { can_subset = 0; } } // copy data to a new array if (can_subset) { uint_char(new_ndata, sec3+6); new_data = (float *) malloc(new_ndata * sizeof(float)); #pragma omp parallel for private(i,j,k) for(j = iy0; j <= iy1; j++) { k = (j-iy0)*(ix1-ix0+1); for(i = ix0; i <= ix1; i++) { new_data[(i-ix0) + k ] = data[ idx(i,j,nx,ny,cyclic_grid) ]; } } } else { new_ndata = ndata; new_data = (float *) malloc(new_ndata * sizeof(float)); for (k = 0; k < ndata; k++) new_data[k] = data[k]; new_nx = nx; new_ny = ny; } set_order(new_sec, output_order); grib_wrt(new_sec, new_data, new_ndata, new_nx, new_ny, use_scale, dec_scale, bin_scale, wanted_bits, max_bits, grib_type, out); if (flush_mode) fflush(out); free(new_data); free(sec3); return 0; }
int MPI_Type_create_darray(int size, int rank, int ndims, int gsize_array[], int distrib_array[], int darg_array[], int psize_array[], int order, MPI_Datatype oldtype, MPI_Datatype *newtype) { ompi_datatype_t *lastType; ptrdiff_t orig_extent, *st_offsets = NULL; int i, start_loop, end_loop, step; int *coords = NULL, rc = OMPI_SUCCESS; if (MPI_PARAM_CHECK) { int prod_psize = 1; OMPI_ERR_INIT_FINALIZE(FUNC_NAME); if( (rank < 0) || (size < 0) || (rank >= size) ) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_ARG, FUNC_NAME); } else if( ndims < 0 ) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_COUNT, FUNC_NAME); } else if( (NULL == gsize_array) || (NULL == distrib_array) || (NULL == darg_array) || (NULL == psize_array)) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_ARG, FUNC_NAME); } else if (NULL == newtype) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_TYPE, FUNC_NAME); } else if( !(DT_FLAG_DATA & oldtype ->flags) ) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_TYPE, FUNC_NAME); } else if( (MPI_ORDER_C != order) && (MPI_ORDER_FORTRAN != order) ) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_ARG, FUNC_NAME); } for( i = 0; i < ndims; i++ ) { if( (MPI_DISTRIBUTE_BLOCK != distrib_array[i]) && (MPI_DISTRIBUTE_CYCLIC != distrib_array[i]) && (MPI_DISTRIBUTE_NONE != distrib_array[i]) ) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_ARG, FUNC_NAME); } else if( (gsize_array[i] < 1) || (psize_array[i] < 0) || ((darg_array[i] < 0) && (MPI_DISTRIBUTE_DFLT_DARG != darg_array[i]) ) ) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_ARG, FUNC_NAME); } else if( (MPI_DISTRIBUTE_DFLT_DARG != darg_array[i]) && (MPI_DISTRIBUTE_BLOCK == distrib_array[i]) && ((darg_array[i] * psize_array[i]) < gsize_array[i]) ) { return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_ARG, FUNC_NAME); } else if( 1 > psize_array[i] ) return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_ARG, FUNC_NAME); prod_psize *= psize_array[i]; } if( prod_psize != size ) return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_ARG, FUNC_NAME); } /* speedy corner case */ if (ndims < 1) { /* Don't just return MPI_DATATYPE_NULL as that can't be MPI_TYPE_FREE()ed, and that seems bad */ *newtype = ompi_ddt_create(0); ompi_ddt_add(*newtype, &ompi_mpi_datatype_null, 0, 0, 0); return MPI_SUCCESS; } rc = ompi_ddt_type_extent(oldtype, &orig_extent); if (MPI_SUCCESS != rc) goto cleanup; /* calculate position in grid using row-major ordering */ { int tmp_rank = rank, procs = size; coords = (int *) malloc(ndims * sizeof(int)); for (i = 0 ; i < ndims ; i++) { procs = procs / psize_array[i]; coords[i] = tmp_rank / procs; tmp_rank = tmp_rank % procs; } } st_offsets = (ptrdiff_t *) malloc(ndims * sizeof(ptrdiff_t)); /* duplicate type to here to 1) deal with constness without casting and 2) eliminate need to for conditional destroy below. Lame, yes. But cleaner code all around. */ rc = ompi_ddt_duplicate(oldtype, &lastType); if (OMPI_SUCCESS != rc) goto cleanup; /* figure out ordering issues */ if (MPI_ORDER_C == order) { start_loop = ndims - 1 ; step = -1; end_loop = -1; } else { start_loop = 0 ; step = 1; end_loop = ndims; } /* Build up array */ for (i = start_loop ; i != end_loop; i += step) { int nprocs, rank; switch(distrib_array[i]) { case MPI_DISTRIBUTE_BLOCK: rc = block(gsize_array, i, ndims, psize_array[i], coords[i], darg_array[i], order, orig_extent, lastType, newtype, st_offsets+i); break; case MPI_DISTRIBUTE_CYCLIC: rc = cyclic(gsize_array, i, ndims, psize_array[i], coords[i], darg_array[i], order, orig_extent, lastType, newtype, st_offsets+i); break; case MPI_DISTRIBUTE_NONE: /* treat it as a block distribution on 1 process */ if (order == MPI_ORDER_C) { nprocs = psize_array[i]; rank = coords[i]; } else { nprocs = 1; rank = 0; } rc = block(gsize_array, i, ndims, nprocs, rank, MPI_DISTRIBUTE_DFLT_DARG, order, orig_extent, lastType, newtype, st_offsets+i); break; default: rc = MPI_ERR_ARG; } ompi_ddt_destroy(&lastType); /* need to destroy the old type even in error condition, so don't check return code from above until after cleanup. */ if (MPI_SUCCESS != rc) goto cleanup; lastType = *newtype; } /* set displacement and UB correctly. Use struct instead of resized for same reason as subarray */ { ptrdiff_t displs[3]; ompi_datatype_t *types[3]; int tmp_size, blength[3] = { 1, 1, 1}; displs[1] = st_offsets[start_loop]; tmp_size = 1; for (i = start_loop + step ; i != end_loop ; i += step) { tmp_size *= gsize_array[i - step]; displs[1] += tmp_size * st_offsets[i]; } displs[0] = 0; displs[1] *= orig_extent; displs[2] = orig_extent; for (i = 0 ; i < ndims ; i++) { displs[2] *= gsize_array[i]; } types[0] = MPI_LB; types[1] = lastType; types[2] = MPI_UB; rc = ompi_ddt_create_struct(3, blength, displs, types, newtype); ompi_ddt_destroy(&lastType); /* need to destroy the old type even in error condition, so don't check return code from above until after cleanup. */ if (MPI_SUCCESS != rc) goto cleanup; } { int* a_i[8]; a_i[0] = &size; a_i[1] = &rank; a_i[2] = &ndims; a_i[3] = gsize_array; a_i[4] = distrib_array; a_i[5] = darg_array; a_i[6] = psize_array; a_i[7] = ℴ ompi_ddt_set_args( *newtype, 4 * ndims + 4, a_i, 0, NULL, 1, &oldtype, MPI_COMBINER_DARRAY ); } cleanup: if (NULL != st_offsets) free(st_offsets); if (NULL != coords) free(coords); OMPI_ERRHANDLER_RETURN(rc, MPI_COMM_WORLD, rc, FUNC_NAME); }
void Geometry::MoperatorGeneralBlochFill(Mat A, int b[3][2], int DimPeriod, double k[3], int ih){ int N[3]; for(int i=0; i<3; i++) N[i] = gN.x(i); double blochbc[3]; for(int i=0; i<3; i++) blochbc[i] = k[i]*N[i]*h[i]; int NC = 3, offset = ih*(Nxyzcr()+2); int ns, ne; double hh; int bc[3][2][3]; /* bc[x/y/z direction][lo/hi][Ex/Ey/Ez] */ dcomp val, magicnum, mucp[2], mulcp[2]; dcomp cidu_phase, cpidu_phase[2], cpidl_phase[2]; /* set up b ... */ for(int ic=0; ic<3; ic++) for(int j=0; j<2; j++) for(int k=0; k<3; k++) bc[ic][j][k] = b[ic][j]*( k==ic ? -1 :1); MatGetOwnershipRange(A, &ns, &ne); for (int itrue = ns; itrue < ne && itrue < 2*Nxyzc(); ++itrue) { Point p(itrue, Grid(N, Nc, 2)); p.project(3); int i = p.xyzcr(); int cp[2], icp[2], cidu, cpidu[2],cpidl[2], cid, cpid[2]; for(int j=0; j<2;j++){ cp[j] = (p.c()+1+j) % NC; icp[j] = i + (cp[j]-p.c() ) *Nxyz(); cpidu[j] = cyclic(p, 2-j, N); cpidl[j] = cyclic(p, 2-j, N); cpid[j] = cyclic(p, 2-j, N); cpidu_phase[j] = 1.0; cpidl_phase[j] = 1.0; } cidu = cyclic(p, 0, N); cid = cyclic(p, 0, N); cidu_phase = 1.0; for(int jr=0; jr<2; jr++) { /* column real/imag parts */ int jrd = (jr-p.r())*NC*Nxyz(); magicnum = (p.r()==jr)*1.0 + (p.r()<jr)*1.0*ComplexI - (p.r()>jr)*1.0* ComplexI; //===================================================================== Point prow(i, Grid(N,3,2)); prow.project(Nc); for(int ib=0; ib<2; ib++){ if(p.x(p.c()) == N[p.c()]-1){ int per = periodic(p.c(), DimPeriod ); cidu = per ? (1-N[p.c()])*cid : 0; cidu_phase = per? std::exp(ComplexI*blochbc[p.c()]) : bc[p.c()][1][cp[ib]]; } if(p.x(cp[ib]) == 0){ int per = periodic(cp[ib], DimPeriod ); cpidl[ib] = per ? (1-N[cp[ib]])*cpid[ib] : 0; cpidl_phase[ib] = per ? std::exp(-ComplexI*blochbc[cp[ib]]) : bc[cp[ib]][0][cp[ib]]; } mucp[1-ib] = pmlval(icp[1-ib], N, Npml, h, LowerPML, 1); mulcp[1-ib] = pmlval(icp[1-ib]-cpidl[ib], N, Npml, h, LowerPML, 1); double c[4]; hh = h[p.c()]*h[cp[ib]]; val = mucp[1-ib] * magicnum /hh; c[1] = val.real(); val *= cidu_phase; c[0] = -val.real(); val = cpidl_phase[ib] * mulcp[1-ib] * magicnum/hh; c[3] = -val.real(); val *= -cidu_phase; c[2] = -val.real(); int dcol[4]; dcol[0] = cidu; dcol[1] = 0; dcol[2] = cidu-cpidl[ib]; dcol[3] = -cpidl[ib]; for(int w=0;w<4;w++){ Point pcol(icp[ib] + jrd+dcol[w], Grid(N,3,2) ); pcol.project(Nc); if(pcol.c()!=-1) MatSetValue(A, prow.xyzcr()+offset, pcol.xyzcr()+offset, c[w], ADD_VALUES); } if(p.x(cp[ib]) == N[cp[ib]]-1){ int per = periodic(cp[ib], DimPeriod ); cpidu[ib] = per ? (1-N[cp[ib]])*cpid[ib] : 0; cpidu_phase[ib] = per? std::exp(ComplexI*blochbc[cp[ib]]) : bc[cp[ib]][1][p.c()]; } if(p.x(cp[ib]) == 0){ int per = periodic(cp[ib], DimPeriod ); cpidl[ib] = per ? (1-N[cp[ib]])*cpid[ib] : -cpidu[ib]; cpidl_phase[ib] = per? std::exp(-ComplexI*blochbc[cp[ib]]) : bc[cp[ib]][0][p.c()]; } hh = h[cp[ib]]*h[cp[ib]]; val = -(cpidu_phase[ib] * mucp[1-ib] * magicnum)/hh; c[0] = -val.real(); val = +( (mucp[1-ib] + mulcp[1-ib]) * magicnum)/hh;c[1] = -val.real(); val = -(cpidl_phase[ib] * mulcp[1-ib] * magicnum)/hh;c[2] = -val.real(); dcol[0] = cpidu[ib]; dcol[1] = 0; dcol[2] = -cpidl[ib]; for(int w=0;w<3;w++){ Point pcol(i + jrd+dcol[w], Grid(N,3,2) ); pcol.project(Nc); if(pcol.c()!=-1) MatSetValue(A, prow.xyzcr()+offset, pcol.xyzcr()+offset, c[w], ADD_VALUES); } } } } }