Beispiel #1
0
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;
}
Beispiel #2
0
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;
                }
            }
        }
    }
}
Beispiel #3
0
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;
}
Beispiel #4
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);
            }
Beispiel #5
0
        /* 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;
        }
Beispiel #6
0
        /* 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;
}
Beispiel #9
0
/* 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;
}
Beispiel #10
0
int f_cyclic(ARG0) {
    if (mode >= 0) {
	sprintf(inv_out,cyclic(sec) ? "cyclic" : "not cyclic");
    }
    return 0;
}
Beispiel #11
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;
}
Beispiel #12
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;
}
Beispiel #13
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] = &order;

        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);
}
Beispiel #14
0
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);
	}

}


    }
  }
}