CPLErr SDEDataset::ComputeRasterInfo() {
    long nSDEErr;
    SE_RASTERINFO raster;
    
    nSDEErr = SE_rasterinfo_create(&raster);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasterinfo_create" );
        return CE_Fatal;
    }
    
    long nRasterColumnId = 0;

    nSDEErr = SE_rascolinfo_get_id( hRasterColumn, 
                                    &nRasterColumnId);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rascolinfo_get_id" );
        return CE_Fatal;
    }        

    nSDEErr = SE_raster_get_info_by_id( hConnection, 
                                        nRasterColumnId, 
                                        1, 
                                        raster);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rascolinfo_get_id" );
        return CE_Fatal;
    }
    nSDEErr = SE_raster_get_bands(  hConnection, 
                                    raster, 
                                    &paohSDERasterBands, 
                                    (long*)&nBands);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_raster_get_bands" );
        return CE_Fatal;
    }
    
    SE_RASBANDINFO band;
    
    // grab our other stuff from the first band and hope for the best
    band = paohSDERasterBands[0];
    
    
    nSDEErr = SE_rasbandinfo_get_band_size( band, 
                                            (long*)&nRasterXSize, 
                                            (long*)&nRasterYSize);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasbandinfo_get_band_size" );
        return CE_Fatal;
    }
    
    SE_ENVELOPE extent;
    nSDEErr = SE_rasbandinfo_get_extent(band, &extent);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasbandinfo_get_extent" );
        return CE_Fatal;
    }
    dfMinX = extent.minx;
    dfMinY = extent.miny;
    dfMaxX = extent.maxx;
    dfMaxY = extent.maxy;

    CPLDebug("SDERASTER", "minx: %.5f, miny: %.5f, maxx: %.5f, maxy: %.5f", dfMinX, dfMinY, dfMaxX, dfMaxY);

    // x0 roughly corresponds to dfMinX
    // y0 roughly corresponds to dfMaxY
    // They can be different than the extent parameters because 
    // SDE uses offsets.  The following info is from Duarte Carreira 
    // in relation to bug #2063 http://trac.osgeo.org/gdal/ticket/2063 :

    // Depending on how the data was loaded, the pixel width 
    // or pixel height may include a pixel offset from the nearest
    // tile boundary. An offset will be indicated by aplus sign 
    // "+" followed by a value. The value indicates the number 
    // of pixels the nearest tile boundary is to the left of
    // the image for the x dimension or the number of
    // pixels the nearest tile boundary is above the image for 
    // the y dimension. The offset information is only useful 
    // for advanced application developers who need to know 
    // where the image begins in relation to the underlying tile structure

    LFLOAT x0, y0; 
    nSDEErr = SE_rasbandinfo_get_tile_origin(band, &x0, &y0);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasbandinfo_get_tile_origin" );
        return CE_Fatal;
    }
    CPLDebug("SDERASTER", "Tile origin: %.5f, %.5f", x0, y0);

    // we also need to adjust dfMaxX and dfMinY otherwise the cell size will change
    dfMaxX = (x0-dfMinX) + dfMaxX;
    dfMinY = (y0-dfMaxY) + dfMinY;

    // adjust the bbox based on the tile origin.
    dfMinX = MIN(x0, dfMinX);
    dfMaxY = MAX(y0, dfMaxY);

    nSDEErr = SE_rasterattr_create(&hAttributes, false);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_rasterattr_create" );
        return CE_Fatal;
    }
    
    // Grab the pointer for our member variable

    nSDEErr = SE_stream_create(hConnection, &hStream);
    if( nSDEErr != SE_SUCCESS )
    {
        IssueSDEError( nSDEErr, "SE_stream_create" );
        return CE_Fatal;
    }

    
    for (int i=0; i < nBands; i++) {
        SetBand( i+1, new SDERasterBand( this, i+1, -1, &(paohSDERasterBands[i]) ));
    }

    GDALRasterBand* b = GetRasterBand(1);
    
    eDataType = b->GetRasterDataType();
    
    SE_rasterinfo_free(raster);

    return CE_None;
}
Beispiel #2
0
initial_setup (j_decompress_ptr cinfo)
/* Called once, when first SOS marker is reached */
{
    int ci;
    jpeg_component_info *compptr;

    /* Make sure image isn't bigger than I can handle */
    if ((long) cinfo->image_height > (long) JPEG_MAX_DIMENSION ||
            (long) cinfo->image_width > (long) JPEG_MAX_DIMENSION)
        ERREXIT1(cinfo, JERR_IMAGE_TOO_BIG, (unsigned int) JPEG_MAX_DIMENSION);

    if (cinfo->process == JPROC_LOSSLESS) {
        /* If precision > compiled-in value, we must downscale */
        if (cinfo->data_precision > BITS_IN_JSAMPLE)
            WARNMS2(cinfo, JWRN_MUST_DOWNSCALE,
                    cinfo->data_precision, BITS_IN_JSAMPLE);
    }
    else {  /* Lossy processes */
        /* For now, precision must match compiled-in value... */
        if (cinfo->data_precision != BITS_IN_JSAMPLE)
            ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);
    }

    /* Check that number of components won't exceed internal array sizes */
    if (cinfo->num_components > MAX_COMPONENTS)
        ERREXIT2(cinfo, JERR_COMPONENT_COUNT, cinfo->num_components,
                 MAX_COMPONENTS);

    /* Compute maximum sampling factors; check factor validity */
    cinfo->max_h_samp_factor = 1;
    cinfo->max_v_samp_factor = 1;
    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
            ci++, compptr++) {
        if (compptr->h_samp_factor<=0 || compptr->h_samp_factor>MAX_SAMP_FACTOR ||
                compptr->v_samp_factor<=0 || compptr->v_samp_factor>MAX_SAMP_FACTOR)
            ERREXIT(cinfo, JERR_BAD_SAMPLING);
        cinfo->max_h_samp_factor = MAX(cinfo->max_h_samp_factor,
                                       compptr->h_samp_factor);
        cinfo->max_v_samp_factor = MAX(cinfo->max_v_samp_factor,
                                       compptr->v_samp_factor);
    }

    /* We initialize codec_data_unit and min_codec_data_unit to data_unit.
     * In the full decompressor, this will be overridden by jdmaster.c;
     * but in the transcoder, jdmaster.c is not used, so we must do it here.
     */
    cinfo->min_codec_data_unit = cinfo->data_unit;

    /* Compute dimensions of components */
    for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
            ci++, compptr++) {
        compptr->codec_data_unit = cinfo->data_unit;
        /* Size in data units */
        compptr->width_in_data_units = (JDIMENSION)
                                       jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
                                               (long) (cinfo->max_h_samp_factor * cinfo->data_unit));
        compptr->height_in_data_units = (JDIMENSION)
                                        jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
                                                (long) (cinfo->max_v_samp_factor * cinfo->data_unit));
        /* downsampled_width and downsampled_height will also be overridden by
         * jdmaster.c if we are doing full decompression.  The transcoder library
         * doesn't use these values, but the calling application might.
         */
        /* Size in samples */
        compptr->downsampled_width = (JDIMENSION)
                                     jdiv_round_up((long) cinfo->image_width * (long) compptr->h_samp_factor,
                                             (long) cinfo->max_h_samp_factor);
        compptr->downsampled_height = (JDIMENSION)
                                      jdiv_round_up((long) cinfo->image_height * (long) compptr->v_samp_factor,
                                              (long) cinfo->max_v_samp_factor);
        /* Mark component needed, until color conversion says otherwise */
        compptr->component_needed = TRUE;
        /* Mark no quantization table yet saved for component */
        compptr->quant_table = NULL;
    }

    /* Compute number of fully interleaved MCU rows. */
    cinfo->total_iMCU_rows = (JDIMENSION)
                             jdiv_round_up((long) cinfo->image_height,
                                           (long) (cinfo->max_v_samp_factor*cinfo->data_unit));

    /* Decide whether file contains multiple scans */
    if (cinfo->comps_in_scan < cinfo->num_components ||
            cinfo->process == JPROC_PROGRESSIVE)
        cinfo->inputctl->has_multiple_scans = TRUE;
    else
        cinfo->inputctl->has_multiple_scans = FALSE;
}
// host stub function
void ops_par_loop_update_halo_kernel2_zvel_plus_4_left(char const *name, ops_block block, int dim, int* range,
 ops_arg arg0, ops_arg arg1, ops_arg arg2) {
  ops_arg args[3] = { arg0, arg1, arg2};


  ops_timing_realloc(81,"update_halo_kernel2_zvel_plus_4_left");
  OPS_kernels[81].count++;

  //compute locally allocated range for the sub-block
  int start[3];
  int end[3];
  #ifdef OPS_MPI
  sub_block_list sb = OPS_sub_block_list[block->index];
  if (!sb->owned) return;
  for ( int n=0; n<3; n++ ){
    start[n] = sb->decomp_disp[n];end[n] = sb->decomp_disp[n]+sb->decomp_size[n];
    if (start[n] >= range[2*n]) {
      start[n] = 0;
    }
    else {
      start[n] = range[2*n] - start[n];
    }
    if (sb->id_m[n]==MPI_PROC_NULL && range[2*n] < 0) start[n] = range[2*n];
    if (end[n] >= range[2*n+1]) {
      end[n] = range[2*n+1] - sb->decomp_disp[n];
    }
    else {
      end[n] = sb->decomp_size[n];
    }
    if (sb->id_p[n]==MPI_PROC_NULL && (range[2*n+1] > sb->decomp_disp[n]+sb->decomp_size[n]))
      end[n] += (range[2*n+1]-sb->decomp_disp[n]-sb->decomp_size[n]);
  }
  #else //OPS_MPI
  for ( int n=0; n<3; n++ ){
    start[n] = range[2*n];end[n] = range[2*n+1];
  }
  #endif //OPS_MPI

  int x_size = MAX(0,end[0]-start[0]);
  int y_size = MAX(0,end[1]-start[1]);
  int z_size = MAX(0,end[2]-start[2]);


  int xdim0 = args[0].dat->size[0]*args[0].dat->dim;
  int ydim0 = args[0].dat->size[1];
  int xdim1 = args[1].dat->size[0]*args[1].dat->dim;
  int ydim1 = args[1].dat->size[1];

  //build opencl kernel if not already built

  buildOpenCLKernels_update_halo_kernel2_zvel_plus_4_left(
  xdim0,ydim0,xdim1,ydim1);

  //Timing
  double t1,t2,c1,c2;
  ops_timers_core(&c2,&t2);

  //set up OpenCL thread blocks
  size_t globalWorkSize[3] = {((x_size-1)/OPS_block_size_x+ 1)*OPS_block_size_x, ((y_size-1)/OPS_block_size_y + 1)*OPS_block_size_y, MAX(1,end[2]-start[2])};
  size_t localWorkSize[3] =  {OPS_block_size_x,OPS_block_size_y,1};


  int *arg2h = (int *)arg2.data;

  int consts_bytes = 0;

  consts_bytes += ROUND_UP(NUM_FIELDS*sizeof(int));

  reallocConstArrays(consts_bytes);

  consts_bytes = 0;
  arg2.data = OPS_consts_h + consts_bytes;
  arg2.data_d = OPS_consts_d + consts_bytes;
  for (int d=0; d<NUM_FIELDS; d++) ((int *)arg2.data)[d] = arg2h[d];
  consts_bytes += ROUND_UP(NUM_FIELDS*sizeof(int));
  mvConstArraysToDevice(consts_bytes);
  int dat0 = args[0].dat->elem_size;
  int dat1 = args[1].dat->elem_size;

  //set up initial pointers
  int d_m[OPS_MAX_DIM];
  #ifdef OPS_MPI
  for (int d = 0; d < dim; d++) d_m[d] = args[0].dat->d_m[d] + OPS_sub_dat_list[args[0].dat->index]->d_im[d];
  #else //OPS_MPI
  for (int d = 0; d < dim; d++) d_m[d] = args[0].dat->d_m[d];
  #endif //OPS_MPI
  int base0 = 1 * 
  (start[0] * args[0].stencil->stride[0] - args[0].dat->base[0] - d_m[0]);
  base0 = base0 + args[0].dat->size[0] *
  (start[1] * args[0].stencil->stride[1] - args[0].dat->base[1] - d_m[1]);
  base0 = base0 + args[0].dat->size[0] *  args[0].dat->size[1] *
  (start[2] * args[0].stencil->stride[2] - args[0].dat->base[2] - d_m[2]);

  #ifdef OPS_MPI
  for (int d = 0; d < dim; d++) d_m[d] = args[1].dat->d_m[d] + OPS_sub_dat_list[args[1].dat->index]->d_im[d];
  #else //OPS_MPI
  for (int d = 0; d < dim; d++) d_m[d] = args[1].dat->d_m[d];
  #endif //OPS_MPI
  int base1 = 1 * 
  (start[0] * args[1].stencil->stride[0] - args[1].dat->base[0] - d_m[0]);
  base1 = base1 + args[1].dat->size[0] *
  (start[1] * args[1].stencil->stride[1] - args[1].dat->base[1] - d_m[1]);
  base1 = base1 + args[1].dat->size[0] *  args[1].dat->size[1] *
  (start[2] * args[1].stencil->stride[2] - args[1].dat->base[2] - d_m[2]);


  ops_H_D_exchanges_device(args, 3);
  ops_halo_exchanges(args,3,range);
  ops_H_D_exchanges_device(args, 3);

  ops_timers_core(&c1,&t1);
  OPS_kernels[81].mpi_time += t1-t2;


  clSafeCall( clSetKernelArg(OPS_opencl_core.kernel[81], 0, sizeof(cl_mem), (void*) &arg0.data_d ));
  clSafeCall( clSetKernelArg(OPS_opencl_core.kernel[81], 1, sizeof(cl_mem), (void*) &arg1.data_d ));
  clSafeCall( clSetKernelArg(OPS_opencl_core.kernel[81], 2, sizeof(cl_mem), (void*) &arg2.data_d ));
  clSafeCall( clSetKernelArg(OPS_opencl_core.kernel[81], 3, sizeof(cl_int), (void*) &base0 ));
  clSafeCall( clSetKernelArg(OPS_opencl_core.kernel[81], 4, sizeof(cl_int), (void*) &base1 ));
  clSafeCall( clSetKernelArg(OPS_opencl_core.kernel[81], 5, sizeof(cl_int), (void*) &x_size ));
  clSafeCall( clSetKernelArg(OPS_opencl_core.kernel[81], 6, sizeof(cl_int), (void*) &y_size ));
  clSafeCall( clSetKernelArg(OPS_opencl_core.kernel[81], 7, sizeof(cl_int), (void*) &z_size ));

  //call/enque opencl kernel wrapper function
  clSafeCall( clEnqueueNDRangeKernel(OPS_opencl_core.command_queue, OPS_opencl_core.kernel[81], 3, NULL, globalWorkSize, localWorkSize, 0, NULL, NULL) );
  if (OPS_diags>1) {
    clSafeCall( clFinish(OPS_opencl_core.command_queue) );
  }

  ops_set_dirtybit_device(args, 3);
  ops_set_halo_dirtybit3(&args[0],range);
  ops_set_halo_dirtybit3(&args[1],range);

  //Update kernel record
  ops_timers_core(&c2,&t2);
  OPS_kernels[81].time += t2-t1;
  OPS_kernels[81].transfer += ops_compute_transfer(dim, range, &arg0);
  OPS_kernels[81].transfer += ops_compute_transfer(dim, range, &arg1);
}
Beispiel #4
0
lapack_int LAPACKE_cgelsd( int matrix_order, lapack_int m, lapack_int n,
                           lapack_int nrhs, lapack_complex_float* a,
                           lapack_int lda, lapack_complex_float* b,
                           lapack_int ldb, float* s, float rcond,
                           lapack_int* rank )
{
    lapack_int info = 0;
    lapack_int lwork = -1;
    /* Additional scalars declarations for work arrays */
    lapack_int liwork;
    lapack_int lrwork;
    lapack_int* iwork = NULL;
    float* rwork = NULL;
    lapack_complex_float* work = NULL;
    lapack_int iwork_query;
    float rwork_query;
    lapack_complex_float work_query;
    if( matrix_order != LAPACK_COL_MAJOR && matrix_order != LAPACK_ROW_MAJOR ) {
        LAPACKE_xerbla( "LAPACKE_cgelsd", -1 );
        return -1;
    }
#ifndef LAPACK_DISABLE_NAN_CHECK
    /* Optionally check input matrices for NaNs */
    if( LAPACKE_cge_nancheck( matrix_order, m, n, a, lda ) ) {
        return -5;
    }
    if( LAPACKE_cge_nancheck( matrix_order, MAX(m,n), nrhs, b, ldb ) ) {
        return -7;
    }
    if( LAPACKE_s_nancheck( 1, &rcond, 1 ) ) {
        return -10;
    }
#endif
    /* Query optimal working array(s) size */
    info = LAPACKE_cgelsd_work( matrix_order, m, n, nrhs, a, lda, b, ldb, s,
                                rcond, rank, &work_query, lwork, &rwork_query,
                                &iwork_query );
    if( info != 0 ) {
        goto exit_level_0;
    }
    liwork = (lapack_int)iwork_query;
    lrwork = (lapack_int)rwork_query;
    lwork = LAPACK_C2INT( work_query );
    /* Allocate memory for work arrays */
    iwork = (lapack_int*)LAPACKE_malloc( sizeof(lapack_int) * liwork );
    if( iwork == NULL ) {
        info = LAPACK_WORK_MEMORY_ERROR;
        goto exit_level_0;
    }
    rwork = (float*)LAPACKE_malloc( sizeof(float) * lrwork );
    if( rwork == NULL ) {
        info = LAPACK_WORK_MEMORY_ERROR;
        goto exit_level_1;
    }
    work = (lapack_complex_float*)
        LAPACKE_malloc( sizeof(lapack_complex_float) * lwork );
    if( work == NULL ) {
        info = LAPACK_WORK_MEMORY_ERROR;
        goto exit_level_2;
    }
    /* Call middle-level interface */
    info = LAPACKE_cgelsd_work( matrix_order, m, n, nrhs, a, lda, b, ldb, s,
                                rcond, rank, work, lwork, rwork, iwork );
    /* Release memory and exit */
    LAPACKE_free( work );
exit_level_2:
    LAPACKE_free( rwork );
exit_level_1:
    LAPACKE_free( iwork );
exit_level_0:
    if( info == LAPACK_WORK_MEMORY_ERROR ) {
        LAPACKE_xerbla( "LAPACKE_cgelsd", info );
    }
    return info;
}
Beispiel #5
0
static int jiveL_initSDL(lua_State *L) {
	const SDL_VideoInfo *video_info;
	JiveSurface *srf, *splash, *icon;
	Uint16 splash_w, splash_h;

	/* logging */
	log_ui_draw = LOG_CATEGORY_GET("jivelite.ui.draw");
	log_ui = LOG_CATEGORY_GET("jivelite.ui");

	/* linux fbcon does not need a mouse */
	SDL_putenv("SDL_NOMOUSE=1");

	/* allow the screensaver */
	SDL_putenv("SDL_VIDEO_ALLOW_SCREENSAVER=1");

	/* initialise SDL */
	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
		LOG_ERROR(log_ui_draw, "SDL_Init(V|T|A): %s\n", SDL_GetError());
		SDL_Quit();
		exit(-1);
	}

	/* report video info */
	if ((video_info = SDL_GetVideoInfo())) {
		LOG_INFO(log_ui_draw, "%d,%d %d bits/pixel %d bytes/pixel [R<<%d G<<%d B<<%d]", video_info->current_w, video_info->current_h, video_info->vfmt->BitsPerPixel, video_info->vfmt->BytesPerPixel, video_info->vfmt->Rshift, video_info->vfmt->Gshift, video_info->vfmt->Bshift);
		LOG_INFO(log_ui_draw, "Hardware acceleration %s available", video_info->hw_available?"is":"is not");
		LOG_INFO(log_ui_draw, "Window manager %s available", video_info->wm_available?"is":"is not");
	}

	/* Register callback for additional events (used for multimedia keys)*/
	SDL_EventState(SDL_SYSWMEVENT,SDL_ENABLE);
	SDL_SetEventFilter(filter_events);

	platform_init(L);

	/* open window */
	SDL_WM_SetCaption("JiveLite Alpha", "JiveLite Alpha");
	SDL_ShowCursor(SDL_DISABLE);
	SDL_EnableKeyRepeat (100, 100);
	SDL_EnableUNICODE(1);

	/* load the icon */
	icon = jive_surface_load_image("jive/app.png");
	if (icon) {
		jive_surface_set_wm_icon(icon);
		jive_surface_free(icon);
	}

	screen_w = video_info->current_w;
	screen_h = video_info->current_h;

	screen_bpp = video_info->vfmt->BitsPerPixel;

	splash = jive_surface_load_image("jive/splash.png");
	if (splash) {
		jive_surface_get_size(splash, &splash_w, &splash_h);
		if (video_info->wm_available) {
			screen_w = splash_w;
			screen_h = splash_h;
		}
	}

	srf = jive_surface_set_video_mode(screen_w, screen_h, screen_bpp, video_info->wm_available ? false : true);
	if (!srf) {
		SDL_Quit();
		exit(-1);
	}

	if (splash) {
		jive_surface_blit(splash, srf, MAX(0, (screen_w - splash_w) / 2), MAX(0, (screen_h - splash_h) / 2));
		jive_surface_flip(srf);
	}

	lua_getfield(L, 1, "screen");
	if (lua_isnil(L, -1)) {
		LOG_ERROR(log_ui_draw, "no screen table");

		SDL_Quit();
		exit(-1);
	}

	/* store screen surface */
	JiveSurface **p = (JiveSurface **)lua_newuserdata(L, sizeof(JiveSurface *));
	*p = jive_surface_ref(srf);
	luaL_getmetatable(L, "JiveSurface");
	lua_setmetatable(L, -2);

	lua_setfield(L, -2, "surface");

	lua_getfield(L, -1, "bounds");
	lua_pushinteger(L, screen_w);
	lua_rawseti(L, -2, 3);
	lua_pushinteger(L, screen_h);
	lua_rawseti(L, -2, 4);
	lua_pop(L, 2);

	/* background image */
	jive_background = jive_tile_fill_color(0x000000FF);

	/* jive.ui.style = {} */
	lua_getglobal(L, "jive");
	lua_getfield(L, -1, "ui");
	lua_newtable(L);
	lua_setfield(L, -2, "style");
	lua_pop(L, 2);

	return 0;
}
// host stub function
void ops_par_loop_initialise_chunk_kernel_xx(char const *name, ops_block block,
                                             int dim, int *range, ops_arg arg0,
                                             ops_arg arg1) {

  // Timing
  double t1, t2, c1, c2;
  ops_arg args[2] = {arg0, arg1};

#ifdef CHECKPOINTING
  if (!ops_checkpointing_before(args, 2, range, 0))
    return;
#endif

  if (OPS_diags > 1) {
    ops_timing_realloc(0, "initialise_chunk_kernel_xx");
    OPS_kernels[0].count++;
    ops_timers_core(&c1, &t1);
  }

  // compute localy allocated range for the sub-block

  int start[2];
  int end[2];
#ifdef OPS_MPI
  sub_block_list sb = OPS_sub_block_list[block->index];
#endif // OPS_MPI

  int arg_idx[2];
  int arg_idx_base[2];
#ifdef OPS_MPI
  if (compute_ranges(args, 2, block, range, start, end, arg_idx) < 0)
    return;
#else // OPS_MPI
  for (int n = 0; n < 2; n++) {
    start[n] = range[2 * n];
    end[n] = range[2 * n + 1];
    arg_idx[n] = start[n];
  }
#endif
  for (int n = 0; n < 2; n++) {
    arg_idx_base[n] = arg_idx[n];
  }

  int dat0 = args[0].dat->elem_size;

  // set up initial pointers
  int base0 = args[0].dat->base_offset +
              (OPS_soa ? args[0].dat->type_size : args[0].dat->elem_size) *
                  start[0] * args[0].stencil->stride[0];
  base0 = base0 +
          (OPS_soa ? args[0].dat->type_size : args[0].dat->elem_size) *
              args[0].dat->size[0] * start[1] * args[0].stencil->stride[1];
#ifdef OPS_GPU
  int *p_a0 = (int *)((char *)args[0].data_d + base0);
#else
  int *p_a0 = (int *)((char *)args[0].data + base0);
#endif

  int *p_a1 = NULL;

  int x_size = MAX(0, end[0] - start[0]);
  int y_size = MAX(0, end[1] - start[1]);

  // initialize global variable with the dimension of dats
  xdim0 = args[0].dat->size[0];
  if (xdim0 != xdim0_initialise_chunk_kernel_xx_h) {
    xdim0_initialise_chunk_kernel_xx = xdim0;
    xdim0_initialise_chunk_kernel_xx_h = xdim0;
  }

// Halo Exchanges

#ifdef OPS_GPU
  ops_H_D_exchanges_device(args, 2);
#else
  ops_H_D_exchanges_host(args, 2);
#endif
  ops_halo_exchanges(args, 2, range);

#ifdef OPS_GPU
  ops_H_D_exchanges_device(args, 2);
#else
  ops_H_D_exchanges_host(args, 2);
#endif
  if (OPS_diags > 1) {
    ops_timers_core(&c2, &t2);
    OPS_kernels[0].mpi_time += t2 - t1;
  }

  initialise_chunk_kernel_xx_c_wrapper(p_a0, p_a1, arg_idx[0], arg_idx[1],
                                       x_size, y_size);

  if (OPS_diags > 1) {
    ops_timers_core(&c1, &t1);
    OPS_kernels[0].time += t1 - t2;
  }
#ifdef OPS_GPU
  ops_set_dirtybit_device(args, 2);
#else
  ops_set_dirtybit_host(args, 2);
#endif
  ops_set_halo_dirtybit3(&args[0], range);

  if (OPS_diags > 1) {
    // Update kernel record
    ops_timers_core(&c2, &t2);
    OPS_kernels[0].mpi_time += t2 - t1;
    OPS_kernels[0].transfer += ops_compute_transfer(dim, start, end, &arg0);
  }
}
Beispiel #7
0
void  MSXtank_mix2(int i, double vIn, double cIn[], long dt)
/*
**   Purpose: 2-compartment tank model                      
**
**   Input:   i = tank index
**            vIn = volume of inflow to tank (ft3)
**            cIn[] = concen. of inflow to tank
**            dt = current WQ time step (sec)
*/
{
    int     k, m, n;
    long    tstep,                     // Actual time step taken
            tstar;                     // Time to fill or drain a zone
    double  qIn,                       // Inflow rate
            qOut,                      // Outflow rate
            qNet;                      // Net flow rate
    double  c, c1, c2;                 // Species concentrations
    Pseg    seg1,                      // Mixing zone segment
            seg2;                      // Ambient zone segment

// --- find inflows & outflows 

    n = MSX.Tank[i].node;
    qNet = MSX.D[n];
    qIn = vIn/(double)dt;
    qOut = qIn - qNet;

// --- get segments for each zone

    k = MSX.Nobjects[LINK] + i;
    seg1 = MSX.FirstSeg[k];
    seg2 = MSX.LastSeg[k];

// --- case of no net volume change

    if ( fabs(qNet) < TINY ) return;

// --- case of net filling (qNet > 0)

    else if (qNet > 0.0)
    {

    // --- case where ambient zone empty & mixing zone filling 

        if (seg2->v <= 0.0)
        {
        // --- time to fill mixing zone
            tstar = (long) ((MSX.Tank[i].vMix - (seg1->v))/qNet);
            tstep = MIN(dt, tstar);

            for (m=1; m<=MSX.Nobjects[SPECIES]; m++)
            {
                if ( MSX.Species[m].type != BULK ) continue;

            // --- new quality in mixing zone
                c = seg1->c[m]; 
                if (seg1->v > 0.0) seg1->c[m] += qIn*tstep*(cIn[m]-c)/(seg1->v);
                else seg1->c[m] = cIn[m];
                seg1->c[m] = MAX(0.0, seg1->c[m]);
                seg2->c[m] = 0.0;
            }

        // --- new volume of mixing zone
            seg1->v += qNet*tstep;

        // --- time during which ambient zone fills
            dt -= tstep;
        }

    // --- case where mixing zone full & ambient zone filling 
        if (dt > 1)
        {
            for (m=1; m<=MSX.Nobjects[SPECIES]; m++)
            {
                if ( MSX.Species[m].type != BULK ) continue;

            // --- new quality in mixing zone
                c1 = seg1->c[m]; 
                seg1->c[m] += qIn * dt * (cIn[m] - c1) / (seg1->v);
                seg1->c[m] = MAX(0.0, seg1->c[m]);

            // --- new quality in ambient zone
		        c2 = seg2->c[m];
                if (seg2->v <= 0.0)
                    seg2->c[m] = seg1->c[m];
                else
                    seg2->c[m] += qNet * dt * ((seg1->c[m]) - c2) / (seg2->v);
                seg2->c[m] = MAX(0.0, seg2->c[m]);
	        }

        // --- new volume of ambient zone
            seg2->v += qNet*dt;
        }
        if ( seg1->v > 0.0 ) MSXchem_equil(NODE, seg1->c);
        if ( seg2->v > 0.0 ) MSXchem_equil(NODE, seg2->c);
    }

// --- case of net emptying (qnet < 0)

    else if ( qNet < 0.0 && seg1->v > 0.0 )
    {

    // --- case where mixing zone full & ambient zone draining

        if ((seg2->v) > 0.0)
        {

        // --- time to drain ambient zone
            tstar = (long)(seg2->v/-qNet);
            tstep = MIN(dt, tstar);

            for (m=1; m<=MSX.Nobjects[SPECIES]; m++)
            {
                if ( MSX.Species[m].type != BULK ) continue;
	            c1 = seg1->c[m];
	            c2 = seg2->c[m];

            // --- new mizing zone quality (affected by both external inflow
            //     and drainage from the ambient zone
                seg1->c[m] += (qIn*cIn[m] - qNet*c2 - qOut*c1)*tstep/(seg1->v);
                seg1->c[m] = MAX(0.0, seg1->c[m]);
	        }

        // --- new ambient zone volume
            seg2->v += qNet*tstep;
            seg2->v = MAX(0.0, seg2->v);

        // --- time during which mixing zone empties
            dt -= tstep;
        }

    // --- case where ambient zone empty & mixing zone draining

        if (dt > 1)
        {
            for (m=1; m<=MSX.Nobjects[SPECIES]; m++)
            {
                if ( MSX.Species[m].type != BULK ) continue;

            // --- new mixing zone quality (affected by external inflow only)
		        c = seg1->c[m];
                seg1->c[m] += qIn*dt*(cIn[m]-c)/(seg1->v);
                seg1->c[m] = MAX(0.0, seg1->c[m]);
                seg2->c[m] = 0.0;
	        }

        // --- new volume of mixing zone
            seg1->v += qNet*dt;
            seg1->v = MAX(0.0, seg1->v);
        }
        if ( seg1->v > 0.0 ) MSXchem_equil(NODE, seg1->c);
    }

// --- use quality of mixed compartment (seg1) to represent quality
//     of tank since this is where outflow begins to flow from

    for (m=1; m<=MSX.Nobjects[SPECIES]; m++) MSX.Tank[i].c[m] = seg1->c[m];
}
Beispiel #8
0
static int mag_manacost(struct char_data *ch, int spellnum)
{
  return MAX(SINFO.mana_max - (SINFO.mana_change *
		    (GET_LEVEL(ch) - SINFO.min_level[(int) GET_CLASS(ch)])),
	     SINFO.mana_min);
}
Beispiel #9
0
static void
mx_texture_frame_paint_texture_internal (CoglHandle  material,
                                         CoglHandle  texture,
                                         guint8      opacity,
                                         gfloat      top,
                                         gfloat      right,
                                         gfloat      bottom,
                                         gfloat      left,
                                         gfloat      width,
                                         gfloat      height)
{
  gfloat tex_width, tex_height;
  gfloat ex, ey;
  gfloat tx1, ty1, tx2, ty2;

  /* apply opacity */
  cogl_material_set_color4ub (material, opacity, opacity, opacity, opacity);

  /* add the texture */
  cogl_material_set_layer (material, 0, texture);

  /* set the source */
  cogl_set_source (material);

  tex_width  = cogl_texture_get_width (texture);
  tex_height = cogl_texture_get_height (texture);

  /* simple stretch */
  if (left == 0 && right == 0 && top == 0
      && bottom == 0)
    {
      cogl_rectangle (0, 0, width, height);
      return;
    }

  tx1 = left / tex_width;
  tx2 = (tex_width - right) / tex_width;
  ty1 = top / tex_height;
  ty2 = (tex_height - bottom) / tex_height;

  ex = width - right;
  if (ex < left)
    ex = left;

  ey = height - bottom;
  if (ey < top)
    ey = top;


  {
    float rectangles[] =
    {
      /* top left corner */
      0, 0,
      left, top,
      0.0, 0.0,
      tx1, ty1,

      /* top middle */
      left, 0,
      MAX (left, ex), top,
      tx1, 0.0,
      tx2, ty1,

      /* top right */
      ex, 0,
      MAX (ex + right, width), top,
      tx2, 0.0,
      1.0, ty1,

      /* mid left */
      0, top,
      left,  ey,
      0.0, ty1,
      tx1, ty2,

      /* center */
      left, top,
      ex, ey,
      tx1, ty1,
      tx2, ty2,

      /* mid right */
      ex, top,
      MAX (ex + right, width), ey,
      tx2, ty1,
      1.0, ty2,

      /* bottom left */
      0, ey,
      left, MAX (ey + bottom, height),
      0.0, ty2,
      tx1, 1.0,

      /* bottom center */
      left, ey,
      ex, MAX (ey + bottom, height),
      tx1, ty2,
      tx2, 1.0,

      /* bottom right */
      ex, ey,
      MAX (ex + right, width), MAX (ey + bottom, height),
      tx2, ty2,
      1.0, 1.0
    };

    cogl_rectangles_with_texture_coords (rectangles, 9);
  }
}
Beispiel #10
0
void Blob2D::resize(short destLeft, short destTop, short destWidth, short destHeight)
{
	if( width == 0 && height == 0)
	{
		size_t siz = Bitmap::size(destWidth,destHeight);
		if( alloc_size < siz )
		{
			if(ptr)
				mem_del(ptr);
			ptr = (Bitmap *)mem_add((alloc_size = siz + DEFAULT_BLOB2D_INC));
		}
		memset(ptr, BACKGROUND_COLOR, siz);
		ptr->init(destWidth, destHeight);
	}
	else if( destWidth == 0 && destHeight == 0 )
	{
		err_when(!ptr);
		ptr->init(destWidth, destHeight);
	}
	else if( left_edge == destLeft && top_edge == destTop && width == destWidth )
	{
		if( destHeight == height )
			return;		// unchange

		size_t siz = Bitmap::size(destWidth,destHeight);
		if( alloc_size < siz )
		{
			ptr = (Bitmap *)mem_resize(ptr, (alloc_size = siz + DEFAULT_BLOB2D_INC));
		}

		if( destHeight > height && destWidth > 0 )
		{
			int y2 = top_edge+height;	// must keep the old instant
			height = destHeight;			// as height must be change to make fill_area correct

			// extend, then fill the new with the background color
			fill_area(destLeft, top_edge+height, destLeft+destWidth-1, destTop+destHeight-1, BACKGROUND_COLOR, 0);
		}
	}
	else if( left_edge <= destLeft && top_edge <= destTop &&
		left_edge+width >= destLeft+destWidth && top_edge+height >= destTop+destHeight)
	{
		// clipping
		unsigned char *src = ptr->get_ptr(destLeft-left_edge, destTop-top_edge);
		int srcPitch = ptr->get_pitch();
		ptr->init(destWidth, destHeight);
		unsigned char *dest = ptr->get_ptr();
		int destPitch = ptr->get_pitch();

		for(int y = 0; y < destHeight; ++y, src += srcPitch, dest += destPitch )
			memmove(dest, src, destWidth);

		// ptr = (Bitmap *)mem_resize(ptr, ptr->size());
	}
	else
	{
		// general resize, new another buffer
		// copy range, intersection of two area :
		short copyLeft, copyTop, copyWidth, copyHeight;
		copyLeft = MAX(destLeft, left_edge);
		copyTop = MAX(destTop, top_edge);
		copyWidth = MIN(destLeft + destWidth, left_edge + width) - copyLeft;
		copyHeight = MIN(destTop + destHeight, top_edge + height) - copyTop;

		{
			size_t siz = Bitmap::size(destWidth, destHeight);
			Bitmap *newPtr = (Bitmap *)mem_add(siz + DEFAULT_BLOB2D_INC);
			memset(newPtr, BACKGROUND_COLOR, siz);
			newPtr->init(destWidth, destHeight);

			if( copyWidth > 0 && copyHeight > 0 )
			{
				int yCount = 0;
				unsigned char *src = ptr->get_ptr(copyLeft-left_edge, yCount+copyTop-top_edge );
				unsigned char *dest = newPtr->get_ptr(copyLeft-destLeft, yCount+copyTop-destTop );

				for( ; yCount < copyHeight; ++yCount, src += ptr->get_pitch(), dest += ptr->get_pitch() )
				{
					// unsigned char *src = (yCount+copyTop-top_edge)*width + copyLeft-left_edge;
					// unsigned char *dest = (yCount+copyTop-destTop)*destWdith + copyLeft-destLeft;
					memcpy(dest, src, copyWidth);
				}
			}

			// assign to the newPtr now
			left_edge = destLeft;
			top_edge = destTop;
			width = destWidth;
			height = destHeight;
			if(ptr)
				mem_del(ptr);
			ptr = newPtr;
		}

		// fill rest area with background color
		if( top_edge < copyTop && width > 0)
		{
			fill_area(left_edge, top_edge, left_edge+width-1, copyTop, BACKGROUND_COLOR, 0 );
		}

		// fill bottom
		if( top_edge+height > copyTop+copyHeight && width > 0)
		{
			fill_area(left_edge, copyTop+copyHeight, left_edge+width-1, top_edge+height-1, BACKGROUND_COLOR, 0 );
		}

		// fill left
		if( left_edge < copyLeft && destHeight > 0)
		{
			fill_area(left_edge, copyTop, copyLeft-1, copyTop+copyHeight-1,
				BACKGROUND_COLOR, 0);
		}

		// fill right
		if( left_edge+width > copyLeft+copyWidth && destHeight > 0 )
		{
			fill_area(copyLeft+copyWidth, copyTop, left_edge+width, copyTop+copyHeight-1,
				BACKGROUND_COLOR, 0);
		}
	}

	left_edge = destLeft;
	top_edge = destTop;
	width = destWidth;
	height = destHeight;
}
Beispiel #11
0
STATIC
UINT64*
GetBlockEntryListFromAddress (
  IN  UINT64       *RootTable,
  IN  UINT64        RegionStart,
  OUT UINTN        *TableLevel,
  IN OUT UINT64    *BlockEntrySize,
  OUT UINT64      **LastBlockEntry
  )
{
  UINTN   RootTableLevel;
  UINTN   RootTableEntryCount;
  UINT64 *TranslationTable;
  UINT64 *BlockEntry;
  UINT64 *SubTableBlockEntry;
  UINT64  BlockEntryAddress;
  UINTN   BaseAddressAlignment;
  UINTN   PageLevel;
  UINTN   Index;
  UINTN   IndexLevel;
  UINTN   T0SZ;
  UINT64  Attributes;
  UINT64  TableAttributes;

  // Initialize variable
  BlockEntry = NULL;

  // Ensure the parameters are valid
  if (!(TableLevel && BlockEntrySize && LastBlockEntry)) {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return NULL;
  }

  // Ensure the Region is aligned on 4KB boundary
  if ((RegionStart & (SIZE_4KB - 1)) != 0) {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return NULL;
  }

  // Ensure the required size is aligned on 4KB boundary and not 0
  if ((*BlockEntrySize & (SIZE_4KB - 1)) != 0 || *BlockEntrySize == 0) {
    ASSERT_EFI_ERROR (EFI_INVALID_PARAMETER);
    return NULL;
  }

  T0SZ = ArmGetTCR () & TCR_T0SZ_MASK;
  // Get the Table info from T0SZ
  GetRootTranslationTableInfo (T0SZ, &RootTableLevel, &RootTableEntryCount);

  // If the start address is 0x0 then we use the size of the region to identify the alignment
  if (RegionStart == 0) {
    // Identify the highest possible alignment for the Region Size
    BaseAddressAlignment = LowBitSet64 (*BlockEntrySize);
  } else {
    // Identify the highest possible alignment for the Base Address
    BaseAddressAlignment = LowBitSet64 (RegionStart);
  }

  // Identify the Page Level the RegionStart must belong to. Note that PageLevel
  // should be at least 1 since block translations are not supported at level 0
  PageLevel = MAX (3 - ((BaseAddressAlignment - 12) / 9), 1);

  // If the required size is smaller than the current block size then we need to go to the page below.
  // The PageLevel was calculated on the Base Address alignment but did not take in account the alignment
  // of the allocation size
  while (*BlockEntrySize < TT_BLOCK_ENTRY_SIZE_AT_LEVEL (PageLevel)) {
    // It does not fit so we need to go a page level above
    PageLevel++;
  }

  //
  // Get the Table Descriptor for the corresponding PageLevel. We need to decompose RegionStart to get appropriate entries
  //

  TranslationTable = RootTable;
  for (IndexLevel = RootTableLevel; IndexLevel <= PageLevel; IndexLevel++) {
    BlockEntry = (UINT64*)TT_GET_ENTRY_FOR_ADDRESS (TranslationTable, IndexLevel, RegionStart);

    if ((IndexLevel != 3) && ((*BlockEntry & TT_TYPE_MASK) == TT_TYPE_TABLE_ENTRY)) {
      // Go to the next table
      TranslationTable = (UINT64*)(*BlockEntry & TT_ADDRESS_MASK_DESCRIPTION_TABLE);

      // If we are at the last level then update the last level to next level
      if (IndexLevel == PageLevel) {
        // Enter the next level
        PageLevel++;
      }
    } else if ((*BlockEntry & TT_TYPE_MASK) == TT_TYPE_BLOCK_ENTRY) {
      // If we are not at the last level then we need to split this BlockEntry
      if (IndexLevel != PageLevel) {
        // Retrieve the attributes from the block entry
        Attributes = *BlockEntry & TT_ATTRIBUTES_MASK;

        // Convert the block entry attributes into Table descriptor attributes
        TableAttributes = TT_TABLE_AP_NO_PERMISSION;
        if (Attributes & TT_NS) {
          TableAttributes = TT_TABLE_NS;
        }

        // Get the address corresponding at this entry
        BlockEntryAddress = RegionStart;
        BlockEntryAddress = BlockEntryAddress >> TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel);
        // Shift back to right to set zero before the effective address
        BlockEntryAddress = BlockEntryAddress << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel);

        // Set the correct entry type for the next page level
        if ((IndexLevel + 1) == 3) {
          Attributes |= TT_TYPE_BLOCK_ENTRY_LEVEL3;
        } else {
          Attributes |= TT_TYPE_BLOCK_ENTRY;
        }

        // Create a new translation table
        TranslationTable = (UINT64*)AllocateAlignedPages (EFI_SIZE_TO_PAGES(TT_ENTRY_COUNT * sizeof(UINT64)), TT_ALIGNMENT_DESCRIPTION_TABLE);
        if (TranslationTable == NULL) {
          return NULL;
        }

        // Populate the newly created lower level table
        SubTableBlockEntry = TranslationTable;
        for (Index = 0; Index < TT_ENTRY_COUNT; Index++) {
          *SubTableBlockEntry = Attributes | (BlockEntryAddress + (Index << TT_ADDRESS_OFFSET_AT_LEVEL(IndexLevel + 1)));
          SubTableBlockEntry++;
        }

        // Fill the BlockEntry with the new TranslationTable
        ReplaceLiveEntry (BlockEntry,
          ((UINTN)TranslationTable & TT_ADDRESS_MASK_DESCRIPTION_TABLE) | TableAttributes | TT_TYPE_TABLE_ENTRY);
      }
    } else {
      if (IndexLevel != PageLevel) {
static void loop()
{
    static const uint8_t compass_count = compass.get_count();
    static float min[COMPASS_MAX_INSTANCES][3];
    static float max[COMPASS_MAX_INSTANCES][3];
    static float offset[COMPASS_MAX_INSTANCES][3];

    if ((AP_HAL::micros() - timer) > 100000L) {
        timer = AP_HAL::micros();
        compass.read();
        const uint32_t read_time = AP_HAL::micros() - timer;

        for (uint8_t i = 0; i < compass_count; i++) {
            float heading;

            hal.console->printf("Compass #%u: ", i);

            if (!compass.healthy()) {
                hal.console->printf("not healthy\n");
                continue;
            }

            Matrix3f dcm_matrix;
            // use roll = 0, pitch = 0 for this example
            dcm_matrix.from_euler(0, 0, 0);
            heading = compass.calculate_heading(dcm_matrix, i);

            const Vector3f &mag = compass.get_field(i);

            // capture min
            min[i][0] = MIN(mag.x, min[i][0]);
            min[i][1] = MIN(mag.y, min[i][1]);
            min[i][2] = MIN(mag.z, min[i][2]);

            // capture max
            max[i][0] = MAX(mag.x, max[i][0]);
            max[i][1] = MAX(mag.y, max[i][1]);
            max[i][2] = MAX(mag.z, max[i][2]);

            // calculate offsets
            offset[i][0] = -(max[i][0] + min[i][0]) / 2;
            offset[i][1] = -(max[i][1] + min[i][1]) / 2;
            offset[i][2] = -(max[i][2] + min[i][2]) / 2;

            // display all to user
            hal.console->printf("Heading: %.2f (%3d, %3d, %3d)",
                                (double)ToDeg(heading),
                                (int)mag.x,
                                (int)mag.y,
                                (int)mag.z);

            // display offsets
            hal.console->printf(" offsets(%.2f, %.2f, %.2f)",
                                (double)offset[i][0],
                                (double)offset[i][1],
                                (double)offset[i][2]);

            hal.console->printf(" t=%u", (unsigned)read_time);

            hal.console->printf("\n");
        }
    } else {
        hal.scheduler->delay(1);
    }
}
Beispiel #13
0
static void fmtint(char *buffer, size_t *currlen, size_t maxlen,
		    long value, int base, int min, int max, int flags)
{
	int signvalue = 0;
	unsigned long uvalue;
	char convert[20];
	int place = 0;
	int spadlen = 0; /* amount to space pad */
	int zpadlen = 0; /* amount to zero pad */
	int caps = 0;
	
	if (max < 0)
		max = 0;
	
	uvalue = value;
	
	if(!(flags & DP_F_UNSIGNED)) {
		if( value < 0 ) {
			signvalue = '-';
			uvalue = -value;
		} else {
			if (flags & DP_F_PLUS)  /* Do a sign (+/i) */
				signvalue = '+';
			else if (flags & DP_F_SPACE)
				signvalue = ' ';
		}
	}
  
	if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */

	do {
		convert[place++] =
			(caps? "0123456789ABCDEF":"0123456789abcdef")
			[uvalue % (unsigned)base  ];
		uvalue = (uvalue / (unsigned)base );
	} while(uvalue && (place < 20));
	if (place == 20) place--;
	convert[place] = 0;

	zpadlen = max - place;
	spadlen = min - MAX (max, place) - (signvalue ? 1 : 0);
	if (zpadlen < 0) zpadlen = 0;
	if (spadlen < 0) spadlen = 0;
	if (flags & DP_F_ZERO) {
		zpadlen = MAX(zpadlen, spadlen);
		spadlen = 0;
	}
	if (flags & DP_F_MINUS) 
		spadlen = -spadlen; /* Left Justifty */

#ifdef DEBUG_SNPRINTF
	printf("zpad: %d, spad: %d, min: %d, max: %d, place: %d\n",
	       zpadlen, spadlen, min, max, place);
#endif

	/* Spaces */
	while (spadlen > 0) {
		dopr_outch (buffer, currlen, maxlen, ' ');
		--spadlen;
	}

	/* Sign */
	if (signvalue) 
		dopr_outch (buffer, currlen, maxlen, signvalue);

	/* Zeros */
	if (zpadlen > 0) {
		while (zpadlen > 0) {
			dopr_outch (buffer, currlen, maxlen, '0');
			--zpadlen;
		}
	}

	/* Digits */
	while (place > 0) 
		dopr_outch (buffer, currlen, maxlen, convert[--place]);
  
	/* Left Justified spaces */
	while (spadlen < 0) {
		dopr_outch (buffer, currlen, maxlen, ' ');
		++spadlen;
	}
}
Beispiel #14
0
/******************************************************************************
Description.: this is the main worker thread
              it loops forever, grabs a fresh frame and calculates focus
Input Value.:
Return Value:
******************************************************************************/
void *worker_thread( void *arg ) {
  int frame_size=0;
  double sv=-1.0, max_sv=100.0, delta=500;
  int focus=255, step=10, max_focus=100, search_focus=1;

  if ( (frame = malloc(256*1024)) == NULL ) {
    OPRINT("not enough memory for worker thread\n");
    exit(EXIT_FAILURE);
  }

  /* set cleanup handler to cleanup allocated ressources */
  pthread_cleanup_push(worker_cleanup, NULL);

  while ( !pglobal->stop ) {
    DBG("waiting for fresh frame\n");
    pthread_cond_wait(&pglobal->db_update, &pglobal->db);

    /* read buffer */
    frame_size = pglobal->size;
    memcpy(frame, pglobal->buf, frame_size);

    pthread_mutex_unlock( &pglobal->db );

    /* process frame */
    sv = getFrameSharpnessValue(frame, frame_size);
    DBG("sharpness is: %f\n", sv);

    if ( search_focus || (ABS(sv-max_sv) > delta) ) {
      DBG("adjusting focus: %d\n", focus);

      /* entered because focus changed */
      if ( !search_focus ) {
        DBG("starting to search for focus\n");
        max_focus    = 255;
        focus        = 255;
        max_sv       = -1.0;
        search_focus = 1;
      }

      if ( focus <= 0 ) {
        focus = max_focus;
        DBG("max focus found at: %d\n", max_focus);
        search_focus = 0;
      }

      if ( search_focus ) {
        if (sv > max_sv) {
          /* sharpness is better then max now */
          DBG("found better focus at: %d\n", focus);
          max_focus = focus;
          max_sv = sv;
        }

        focus = MIN(MAX(focus-step,0), 255);
        DBG("decrement focus now to: %d\n", focus);
        //focus = pglobal->in.cmd(IN_CMD_FOCUS_SET, focus);
      }
    }

    if ( (delay > 0) && !search_focus ) {
      usleep(1000*delay);
    }
  }

  pthread_cleanup_pop(1);

  return NULL;
}
Beispiel #15
0
int
MOS3dSetup(GENmodel *inModel, CKTcircuit *ckt)
        /* actually load the current value into the 
         * sparse matrix previously provided 
         */
{
    MOS3model *model = (MOS3model *)inModel;
    MOS3instance *here;
    double Beta;
    double DrainSatCur;
    double EffectiveLength;
    double EffectiveWidth;
    double GateBulkOverlapCap;
    double GateDrainOverlapCap;
    double GateSourceOverlapCap;
    double OxideCap;
    double SourceSatCur;
    double arg;
    double cdrain;
    double evbs;
    double sarg;
    double sargsw;
    double lvgs;
    double vbd;
    double vbs;
    double vds;
    double vdsat;
    double vgb;
    double vgd;
    double vgs;
    double von;
    double lcapgs2,lcapgs3;   /* total gate-source capacitance */
    double lcapgd2,lcapgd3;   /* total gate-drain capacitance */
    double lcapgb2,lcapgb3;   /* total gate-bulk capacitance */
    double lgbs, lgbs2, lgbs3;
    double lgbd, lgbd2, lgbd3;
    double gm2, gb2, gds2, gmb, gmds, gbds;
    double gm3, gb3, gds3, gm2ds, gm2b, gb2ds, gbds2, gmb2, gmds2, gmbds;
    double lcapbd, lcapbd2, lcapbd3;
    double lcapbs, lcapbs2, lcapbs3;
    double ebd;
    double vt;  /* vt at instance temperature */
    Dderivs d_cdrain;



    /*  loop through all the MOS3 device models */
    for( ; model != NULL; model = model->MOS3nextModel ) {

        /* loop through all the instances of the model */
        for (here = model->MOS3instances; here != NULL ;
                here=here->MOS3nextInstance) {
	    if (here->MOS3owner != ARCHme) continue;

            vt = CONSTKoverQ * here->MOS3temp;

            /* first, we compute a few useful values - these could be
             * pre-computed, but for historical reasons are still done
             * here.  They may be moved at the expense of instance size
             */

            EffectiveWidth=here->MOS3w-2*model->MOS3widthNarrow+
                                    model->MOS3widthAdjust;
            EffectiveLength=here->MOS3l - 2*model->MOS3latDiff+
                                    model->MOS3lengthAdjust;
            
            if( (here->MOS3tSatCurDens == 0) || 
                    (here->MOS3drainArea == 0) ||
                    (here->MOS3sourceArea == 0)) {
                DrainSatCur = here->MOS3m * here->MOS3tSatCur;
                SourceSatCur = here->MOS3m * here->MOS3tSatCur;
            } else {
                DrainSatCur = here->MOS3tSatCurDens * 
                        here->MOS3m * here->MOS3drainArea;
                SourceSatCur = here->MOS3tSatCurDens * 
                        here->MOS3m * here->MOS3sourceArea;
            }
            GateSourceOverlapCap = model->MOS3gateSourceOverlapCapFactor * 
                    here->MOS3m * EffectiveWidth;
            GateDrainOverlapCap = model->MOS3gateDrainOverlapCapFactor * 
                    here->MOS3m * EffectiveWidth;
            GateBulkOverlapCap = model->MOS3gateBulkOverlapCapFactor * 
                    here->MOS3m * EffectiveLength;
            Beta = here->MOS3tTransconductance * here->MOS3m *
                    EffectiveWidth/EffectiveLength;
            OxideCap = model->MOS3oxideCapFactor * EffectiveLength * 
                    here->MOS3m * EffectiveWidth;

            /* 
             * ok - now to do the start-up operations
             *
             * we must get values for vbs, vds, and vgs from somewhere
             * so we either predict them or recover them from last iteration
             * These are the two most common cases - either a prediction
             * step or the general iteration step and they
             * share some code, so we put them first - others later on
             */


                    /* general iteration */

                    vbs = model->MOS3type * ( 
                        *(ckt->CKTrhsOld+here->MOS3bNode) -
                        *(ckt->CKTrhsOld+here->MOS3sNodePrime));
                    vgs = model->MOS3type * ( 
                        *(ckt->CKTrhsOld+here->MOS3gNode) -
                        *(ckt->CKTrhsOld+here->MOS3sNodePrime));
                    vds = model->MOS3type * ( 
                        *(ckt->CKTrhsOld+here->MOS3dNodePrime) -
                        *(ckt->CKTrhsOld+here->MOS3sNodePrime));

                /* now some common crunching for some more useful quantities */



            /*
             * now all the preliminaries are over - we can start doing the
             * real work
             */
            vbd = vbs - vds;
            vgd = vgs - vds;
            vgb = vgs - vbs;

            /* bulk-source and bulk-drain doides
             * here we just evaluate the ideal diode current and the
             * correspoinding derivative (conductance).
             */
	    if(vbs <= 0) {
                lgbs = SourceSatCur/vt;
                lgbs += ckt->CKTgmin;
		lgbs2 = lgbs3 = 0;
            } else {
                evbs = exp(MIN(MAX_EXP_ARG,vbs/vt));
                lgbs = SourceSatCur*evbs/vt + ckt->CKTgmin;
		lgbs2 = model->MOS3type *0.5 * (lgbs - ckt->CKTgmin)/vt;
		lgbs3 = model->MOS3type *lgbs2/(vt*3);

            }
            if(vbd <= 0) {
                lgbd = DrainSatCur/vt;
                lgbd += ckt->CKTgmin;
		lgbd2 = lgbd3 = 0;
            } else {
                ebd = exp(MIN(MAX_EXP_ARG,vbd/vt));
                lgbd = DrainSatCur*ebd/vt +ckt->CKTgmin;
		lgbd2 = model->MOS3type *0.5 * (lgbd - ckt->CKTgmin)/vt;
		lgbd3 = model->MOS3type *lgbd2/(vt*3);
            }


            /* now to determine whether the user was able to correctly
             * identify the source and drain of his device
             */
            if(vds >= 0) {
                /* normal mode */
                here->MOS3mode = 1;
            } else {
                /* inverse mode */
                here->MOS3mode = -1;
            }

            {
            /*
             * subroutine moseq3(vds,vbs,vgs,gm,gds,gmbs,
             * qg,qc,qb,cggb,cgdb,cgsb,cbgb,cbdb,cbsb)
             */

            /*
             *     this routine evaluates the drain current, its derivatives and
             *     the charges associated with the gate, channel and bulk
             *     for mosfets based on semi-empirical equations
             */

            /*
            common /mosarg/ vto,beta,gamma,phi,phib,cox,xnsub,xnfs,xd,xj,xld,
            1   xlamda,uo,uexp,vbp,utra,vmax,xneff,xl,xw,vbi,von,vdsat,qspof,
            2   beta0,beta1,cdrain,xqco,xqc,fnarrw,fshort,lev
            common /status/ omega,time,delta,delold(7),ag(7),vt,xni,egfet,
            1   xmu,sfactr,mode,modedc,icalc,initf,method,iord,maxord,noncon,
            2   iterno,itemno,nosolv,modac,ipiv,ivmflg,ipostp,iscrch,iofile
            common /knstnt/ twopi,xlog2,xlog10,root2,rad,boltz,charge,ctok,
            1   gmin,reltol,abstol,vntol,trtol,chgtol,eps0,epssil,epsox,
            2   pivtol,pivrel
            */

            /* equivalence (xlamda,alpha),(vbp,theta),(uexp,eta),(utra,xkappa)*/

            double coeff0 = 0.0631353e0;
            double coeff1 = 0.8013292e0;
            double coeff2 = -0.01110777e0;
            double oneoverxl;   /* 1/effective length */
            double eta; /* eta from model after length factor */
            double phibs;   /* phi - vbs */
            double sqphbs;  /* square root of phibs */
            double sqphis;  /* square root of phi */
            double wps;
            double oneoverxj;   /* 1/junction depth */
            double xjonxl;  /* junction depth/effective length */
            double djonxj;
            double wponxj;
            double arga;
            double argb;
            double argc;
            double gammas;
            double fbodys;
            double fbody;
            double onfbdy;
            double qbonco;
            double vbix;
            double wconxj;
            double vth;
            double csonco;
            double cdonco;
            double vgsx;
            double onfg;
            double fgate;
            double us;
            double xn = 0.0;
            double vdsc;
            double onvdsc = 0.0;
            double vdsx;
            double cdnorm;
            double cdo;
            double fdrain = 0.0;
            double gdsat;
            double cdsat;
            double emax;
            double delxl;
            double dlonxl;
            double xlfact;
            double ondvt;
            double onxn;
            double wfact;
            double fshort;
	    double lvds, lvbs, lvbd;
	    Dderivs d_onxn, d_ondvt, d_wfact, d_MOS3gds;
	    Dderivs d_emax, d_delxl, d_dlonxl, d_xlfact;
	    Dderivs d_cdonco, d_fdrain, d_cdsat, d_gdsat;
	    Dderivs d_vdsx, d_cdo, d_cdnorm, d_Beta, d_dummy;
	    Dderivs d_vdsc, d_onvdsc, d_arga, d_argb;
	    Dderivs d_onfg, d_fgate, d_us, d_vgsx;
	    Dderivs d_von, d_xn, d_vth, d_onfbdy, d_qbonco, d_vbix;
	    Dderivs d_argc, d_fshort, d_gammas, d_fbodys, d_fbody;
	    Dderivs d_wps, d_wconxj, d_wponxj;
	    Dderivs d_phibs, d_sqphbs;
	    Dderivs d_p, d_q, d_r, d_zero, d_vdsat;

            /*
             *     bypasses the computation of charges
             */
	     if (here->MOS3mode == 1) {
		lvgs = vgs;
		lvds = vds;
		lvbs = vbs;
		lvbd = vbd;
			} else {
			lvgs = vgd;
			lvds = -vds;
			lvbs = vbd;
			lvbd = vbs;
			}

            /*
             *     reference cdrain equations to source and
             *     charge equations to bulk
             */
d_p.value = 0.0;
d_p.d1_p = 1.0;
d_p.d1_q = 0.0;
d_p.d1_r = 0.0;
d_p.d2_p2 = 0.0;
d_p.d2_q2 = 0.0;
d_p.d2_r2 = 0.0;
d_p.d2_pq = 0.0;
d_p.d2_qr = 0.0;
d_p.d2_pr = 0.0;
d_p.d3_p3 = 0.0;
d_p.d3_q3 = 0.0;
d_p.d3_r3 = 0.0;
d_p.d3_p2r = 0.0;
d_p.d3_p2q = 0.0;
d_p.d3_q2r = 0.0;
d_p.d3_pq2 = 0.0;
d_p.d3_pr2 = 0.0;
d_p.d3_qr2 = 0.0;
d_p.d3_pqr = 0.0;
	EqualDeriv(&d_q,&d_p);
	EqualDeriv(&d_r,&d_p);
	EqualDeriv(&d_zero,&d_p);
    d_q.d1_p = d_r.d1_p = d_zero.d1_p = 0.0;
    d_q.d1_q = d_r.d1_r = 1.0;
            vdsat = 0.0;
	    EqualDeriv(&d_vdsat,&d_zero);
            oneoverxl = 1.0/EffectiveLength;/*const*/
            eta = model->MOS3eta * 8.15e-22/(model->MOS3oxideCapFactor*
                    EffectiveLength*EffectiveLength*EffectiveLength);/*const*/
            /*
             *.....square root term
             */
            if ( lvbs <=  0.0 ) {
                phibs  =  here->MOS3tPhi-lvbs;
		EqualDeriv(&d_phibs,&d_q);
		d_phibs.value = lvbs;
		TimesDeriv(&d_phibs,&d_phibs,-1.0);
		d_phibs.value += here->MOS3tPhi;
                sqphbs  =  sqrt(phibs);
		SqrtDeriv(&d_sqphbs,&d_phibs);
            } else {
                sqphis = sqrt(here->MOS3tPhi);/*const*/
                /*sqphs3 = here->MOS3tPhi*sqphis;const*/
                sqphbs = sqphis/(1.0+lvbs/
                    (here->MOS3tPhi+here->MOS3tPhi));
		EqualDeriv(&d_sqphbs,&d_q); d_sqphbs.value = lvbs;
		TimesDeriv(&d_sqphbs,&d_sqphbs,1/(here->MOS3tPhi+here->MOS3tPhi));
		d_sqphbs.value += 1.0;
		InvDeriv(&d_sqphbs,&d_sqphbs);
		TimesDeriv(&d_sqphbs,&d_sqphbs,sqphis);
                phibs = sqphbs*sqphbs;
		MultDeriv(&d_phibs,&d_sqphbs,&d_sqphbs);
            }
            /*
             *.....short channel effect factor
             */
            if ( (model->MOS3junctionDepth != 0.0) && 
                    (model->MOS3coeffDepLayWidth != 0.0) ) {
                wps = model->MOS3coeffDepLayWidth*sqphbs;
		TimesDeriv(&d_wps,&d_sqphbs,model->MOS3coeffDepLayWidth);
                oneoverxj = 1.0/model->MOS3junctionDepth;/*const*/
                xjonxl = model->MOS3junctionDepth*oneoverxl;/*const*/
                djonxj = model->MOS3latDiff*oneoverxj;/*const*/
                wponxj = wps*oneoverxj;
		TimesDeriv(&d_wponxj,&d_wps,oneoverxj);
                wconxj = coeff0+coeff1*wponxj+coeff2*wponxj*wponxj;
		TimesDeriv(&d_wconxj,&d_wponxj,coeff2);
		d_wconxj.value += coeff1;
		MultDeriv(&d_wconxj,&d_wconxj,&d_wponxj);
		d_wconxj.value += coeff0;
		arga = wconxj + djonxj;
		EqualDeriv(&d_arga,&d_wconxj); d_arga.value += djonxj;
                argc = wponxj/(1.0+wponxj);
		EqualDeriv(&d_argc,&d_wponxj);
		d_argc.value += 1.0;
		InvDeriv(&d_argc,&d_argc);
		MultDeriv(&d_argc,&d_argc,&d_wponxj);
                argb = sqrt(1.0-argc*argc);
		MultDeriv(&d_argb,&d_argc,&d_argc);
		TimesDeriv(&d_argb,&d_argb,-1.0);
		d_argb.value += 1.0;
		SqrtDeriv(&d_argb,&d_argb);

                fshort = 1.0-xjonxl*(arga*argb-djonxj);
		MultDeriv(&d_fshort,&d_arga,&d_argb);
		d_fshort.value -= djonxj;
		TimesDeriv(&d_fshort,&d_fshort,-xjonxl);
		d_fshort.value += 1.0;
            } else {
                fshort = 1.0;
		EqualDeriv(&d_fshort,&d_zero);
		d_fshort.value = 1.0;

            }
            /*
             *.....body effect
             */
            gammas = model->MOS3gamma*fshort;
	    TimesDeriv(&d_gammas,&d_fshort,model->MOS3gamma);
            fbodys = 0.5*gammas/(sqphbs+sqphbs);
	    DivDeriv(&d_fbodys,&d_gammas,&d_sqphbs);
	    TimesDeriv(&d_fbodys,&d_fbodys,0.25);
            fbody = fbodys+model->MOS3narrowFactor/EffectiveWidth;
	    EqualDeriv(&d_fbody,&d_fbodys);
	    d_fbody.value += fbody - fbodys;

            onfbdy = 1.0/(1.0+fbody);
	    EqualDeriv(&d_onfbdy,&d_fbody);
	    d_onfbdy.value += 1.0;
	    InvDeriv(&d_onfbdy,&d_onfbdy);
            qbonco =gammas*sqphbs+model->MOS3narrowFactor*phibs/EffectiveWidth;
	    EqualDeriv(&d_dummy,&d_phibs);
	    TimesDeriv(&d_dummy,&d_dummy,model->
                             MOS3narrowFactor*EffectiveWidth);
	    MultDeriv(&d_qbonco,&d_gammas,&d_sqphbs);
	    PlusDeriv(&d_qbonco,&d_qbonco,&d_dummy);
            /*
             *.....static feedback effect
             */
            vbix = here->MOS3tVbi*model->MOS3type-eta*(lvds);
	    EqualDeriv(&d_vbix,&d_r); d_vbix.value = vbix;
	    d_vbix.d1_r = -eta;
            /*
             *.....threshold voltage
             */
            vth = vbix+qbonco;
	    PlusDeriv(&d_vth,&d_vbix,&d_qbonco);
            /*
             *.....joint weak inversion and strong inversion
             */
            von = vth;
	    EqualDeriv(&d_von,&d_vth);
            if ( model->MOS3fastSurfaceStateDensity != 0.0 ) {
                csonco = CHARGE*model->MOS3fastSurfaceStateDensity * 
                    1e4 /*(cm**2/m**2)*/ *EffectiveLength*EffectiveWidth *
                    here->MOS3m/OxideCap; /*const*/
                cdonco = 0.5*qbonco/phibs;
		DivDeriv(&d_cdonco,&d_qbonco,&d_phibs);
		TimesDeriv(&d_cdonco,&d_cdonco,0.5);
                xn = 1.0+csonco+cdonco;
		EqualDeriv(&d_xn,&d_cdonco);
		d_xn.value += 1.0 + csonco;
                von = vth+vt*xn;
		TimesDeriv(&d_von,&d_xn,vt);
		PlusDeriv(&d_von,&d_von,&d_vth);


            } else {
                /*
                 *.....cutoff region
                 */
                if ( lvgs <= von ) {
                    cdrain = 0.0;
		    EqualDeriv(&d_cdrain,&d_zero);
                    goto innerline1000;
                }
            }
            /*
             *.....device is on
             */
            vgsx = MAX(lvgs,von);
if (lvgs >= von) {
EqualDeriv(&d_vgsx,&d_p);
d_vgsx.value = lvgs;
} else {
EqualDeriv(&d_vgsx,&d_von);
}
            /*
             *.....mobility modulation by gate voltage
             */
            onfg = 1.0+model->MOS3theta*(vgsx-vth);
	    TimesDeriv(&d_onfg,&d_vth,-1.0);
	    PlusDeriv(&d_onfg,&d_onfg,&d_vgsx);
	    TimesDeriv(&d_onfg,&d_onfg,model->MOS3theta);
	    d_onfg.value += 1.0;
            fgate = 1.0/onfg;
	    InvDeriv(&d_fgate,&d_onfg);
            us = here->MOS3tSurfMob * 1e-4 /*(m**2/cm**2)*/ *fgate;
	    TimesDeriv(&d_us,&d_fgate,here->MOS3tSurfMob * 1e-4);
            /*
             *.....saturation voltage
             */
            vdsat = (vgsx-vth)*onfbdy;
	    TimesDeriv(&d_vdsat,&d_vth, -1.0);
	    PlusDeriv(&d_vdsat,&d_vdsat,&d_vgsx);
	    MultDeriv(&d_vdsat,&d_vdsat,&d_onfbdy);
            if ( model->MOS3maxDriftVel <= 0.0 ) {
            } else {
                vdsc = EffectiveLength*model->MOS3maxDriftVel/us;
		InvDeriv(&d_vdsc,&d_us);
		TimesDeriv(&d_vdsc,&d_vdsc,EffectiveLength*model->MOS3maxDriftVel);
                onvdsc = 1.0/vdsc;
		InvDeriv(&d_onvdsc,&d_vdsc);
                arga = (vgsx-vth)*onfbdy;
		/* note arga = vdsat at this point */
		EqualDeriv(&d_arga,&d_vdsat);
                argb = sqrt(arga*arga+vdsc*vdsc);
		MultDeriv(&d_dummy,&d_arga,&d_arga);
		MultDeriv(&d_argb,&d_vdsc,&d_vdsc);
		PlusDeriv(&d_argb,&d_argb,&d_dummy);
		SqrtDeriv(&d_argb,&d_argb);
                vdsat = arga+vdsc-argb;
		TimesDeriv(&d_vdsat,&d_argb,-1.0);
		PlusDeriv(&d_vdsat,&d_vdsat,&d_vdsc);
		PlusDeriv(&d_vdsat,&d_vdsat,&d_arga);
            }
            /*
             *.....current factors in linear region
             */
            vdsx = MIN((lvds),vdsat);
if (lvds < vdsat) {
EqualDeriv(&d_vdsx,&d_r);
d_vdsx.value = lvds;
} else {
EqualDeriv(&d_vdsx,&d_vdsat);
}

            if ( vdsx == 0.0 ) goto line900;
            cdo = vgsx-vth-0.5*(1.0+fbody)*vdsx;
	    EqualDeriv(&d_cdo,&d_fbody);
	    d_cdo.value += 1.0;
	    MultDeriv(&d_cdo,&d_cdo,&d_vdsx);
	    TimesDeriv(&d_cdo,&d_cdo,0.5);
	    PlusDeriv(&d_cdo,&d_cdo,&d_vth);
	    TimesDeriv(&d_cdo,&d_cdo,-1.0);
	    PlusDeriv(&d_cdo,&d_cdo,&d_vgsx);


            /* 
             *.....normalized drain current
             */
            cdnorm = cdo*vdsx;
	    MultDeriv(&d_cdnorm,&d_cdo,&d_vdsx);
            /* 
             *.....drain current without velocity saturation effect
             */
/* Beta is a constant till now */
            Beta = Beta*fgate;
	    TimesDeriv(&d_Beta,&d_fgate,Beta);
            cdrain = Beta*cdnorm;
	    MultDeriv(&d_cdrain,&d_Beta,&d_cdnorm);
            /*
             *.....velocity saturation factor
             */
            if ( model->MOS3maxDriftVel != 0.0 ) {
                fdrain = 1.0/(1.0+vdsx*onvdsc);
		MultDeriv(&d_fdrain,&d_vdsx,&d_onvdsc);
		d_fdrain.value += 1.0;
		InvDeriv(&d_fdrain,&d_fdrain);
                /*
                 *.....drain current
                 */
	    cdrain = fdrain*cdrain;
	    MultDeriv(&d_cdrain,&d_cdrain,&d_fdrain);
	    Beta = Beta*fdrain;
	    MultDeriv(&d_Beta,&d_Beta,&d_fdrain);
		
            }
            /*
             *.....channel length modulation
             */
            if ( (lvds) <= vdsat ) goto line700;
            if ( model->MOS3maxDriftVel == 0.0 ) goto line510;
            if (model->MOS3alpha == 0.0) goto line700;
            cdsat = cdrain;
	    EqualDeriv(&d_cdsat,&d_cdrain);
            gdsat = cdsat*(1.0-fdrain)*onvdsc;
	    TimesDeriv(&d_dummy,&d_fdrain,-1.0);
	    d_dummy.value += 1.0;
	    MultDeriv(&d_gdsat,&d_cdsat,&d_dummy);
	    MultDeriv(&d_gdsat,&d_gdsat,&d_onvdsc);
            gdsat = MAX(1.0e-12,gdsat);
	    if (gdsat == 1.0e-12) {
		EqualDeriv(&d_gdsat,&d_zero);
		d_gdsat.value = gdsat;
		}

            emax = cdsat*oneoverxl/gdsat;
	    DivDeriv(&d_emax,&d_cdsat,&d_gdsat);
	    TimesDeriv(&d_emax,&d_emax,oneoverxl);


            arga = 0.5*emax*model->MOS3alpha;
	    TimesDeriv(&d_arga,&d_emax,0.5*model->MOS3alpha);
            argc = model->MOS3kappa*model->MOS3alpha;/*const*/
            argb = sqrt(arga*arga+argc*((lvds)-vdsat));
	    TimesDeriv(&d_dummy,&d_vdsat,-1.0);
	    d_dummy.value += lvds;
	    d_dummy.d1_r += 1.0;
	    TimesDeriv(&d_argb,&d_dummy,argc);
	    MultDeriv(&d_dummy,&d_arga,&d_arga);
	    PlusDeriv(&d_argb,&d_argb,&d_dummy);
	    SqrtDeriv(&d_argb,&d_argb);
            delxl = argb-arga;
	    TimesDeriv(&d_delxl,&d_arga,-1.0);
	    PlusDeriv(&d_delxl,&d_argb,&d_delxl);
            goto line520;
line510:
            delxl = sqrt(model->MOS3kappa*((lvds)-vdsat)*model->MOS3alpha);
	    TimesDeriv(&d_delxl,&d_vdsat,-1.0);
	    d_delxl.value += lvds;
	    d_delxl.d1_r += 1.0;
	    TimesDeriv(&d_delxl,&d_delxl,model->MOS3kappa*model->MOS3alpha);
	    SqrtDeriv(&d_delxl,&d_delxl);
	    
            /*
             *.....punch through approximation
             */
line520:
            if ( delxl > (0.5*EffectiveLength) ) {
	    delxl = EffectiveLength - (EffectiveLength*EffectiveLength/
		delxl*0.25);
	    InvDeriv(&d_delxl,&d_delxl);
	    TimesDeriv(&d_delxl,&d_delxl,-EffectiveLength*EffectiveLength*0.25);
	    d_delxl.value += EffectiveLength;
            }
            /*
             *.....saturation region
             */
            dlonxl = delxl*oneoverxl;
	    TimesDeriv(&d_dlonxl,&d_delxl,oneoverxl);
            xlfact = 1.0/(1.0-dlonxl);
	    TimesDeriv(&d_xlfact,&d_dlonxl,-1.0);
	    d_xlfact.value += 1.0;
	    InvDeriv(&d_xlfact,&d_xlfact);

            cdrain = cdrain*xlfact;
	    MultDeriv(&d_cdrain,&d_cdrain,&d_xlfact);
            /*
             *.....finish strong inversion case
             */
line700:
            if ( lvgs < von ) {
                /*
                 *.....weak inversion
                 */
                onxn = 1.0/xn;
		InvDeriv(&d_onxn,&d_xn);
		ondvt = onxn/vt;
		TimesDeriv(&d_ondvt,&d_onxn,1/vt);
                wfact = exp( (lvgs-von)*ondvt );
		TimesDeriv(&d_wfact,&d_von,-1.0);
		d_wfact.value += lvgs;
		d_wfact.d1_p += 1.0;
		MultDeriv(&d_wfact,&d_wfact,&d_ondvt);
		ExpDeriv(&d_wfact,&d_wfact);
                cdrain = cdrain*wfact;
		MultDeriv(&d_cdrain,&d_cdrain,&d_wfact);
            }
            /*
             *.....charge computation
             */
            goto innerline1000;
            /*
             *.....special case of vds = 0.0d0
             */

line900:
            Beta = Beta*fgate;
	    /* Beta is still a constant */
	    TimesDeriv(&d_Beta,&d_fgate,Beta);
            cdrain = 0.0;
	    EqualDeriv(&d_cdrain,&d_zero);
            here->MOS3gds = Beta*(vgsx-vth);
	    TimesDeriv(&d_MOS3gds,&d_vth,-1.0);
	    PlusDeriv(&d_MOS3gds,&d_MOS3gds,&d_vgsx);
	    MultDeriv(&d_MOS3gds,&d_MOS3gds,&d_Beta);
            if ( (model->MOS3fastSurfaceStateDensity != 0.0) && 
                    (lvgs < von) ) {
                here->MOS3gds *=exp((lvgs-von)/(vt*xn));
		TimesDeriv(&d_dummy,&d_von,-1.0);
		d_dummy.value += lvgs;
		d_dummy.d1_p += 1.0;
		DivDeriv(&d_dummy,&d_dummy,&d_xn);
		TimesDeriv(&d_dummy,&d_dummy,1/vt);
		ExpDeriv(&d_dummy,&d_dummy);
		MultDeriv(&d_MOS3gds,&d_MOS3gds,&d_dummy);
            }
	    d_cdrain.d1_r = d_MOS3gds.value;
	    d_cdrain.d2_r2 = d_MOS3gds.d1_r;
	    d_cdrain.d3_r3 = d_MOS3gds.d2_r2;



innerline1000:;
            /* 
             *.....done
             */
            }


            /*
             *  COMPUTE EQUIVALENT DRAIN CURRENT SOURCE
             */
                /* 
                 * now we do the hard part of the bulk-drain and bulk-source
                 * diode - we evaluate the non-linear capacitance and
                 * charge
                 *
                 * the basic equations are not hard, but the implementation
                 * is somewhat long in an attempt to avoid log/exponential
                 * evaluations
                 */
                /*
                 *  charge storage elements
                 *
                 *.. bulk-drain and bulk-source depletion capacitances
                 */
                    if (vbs < here->MOS3tDepCap){
                        arg=1-vbs/here->MOS3tBulkPot;
                        /*
                         * the following block looks somewhat long and messy,
                         * but since most users use the default grading
                         * coefficients of .5, and sqrt is MUCH faster than an
                         * exp(log()) we use this special case code to buy time.
                         * (as much as 10% of total job time!)
                         */
#ifndef NOSQRT
                        if(model->MOS3bulkJctBotGradingCoeff ==
                                model->MOS3bulkJctSideGradingCoeff) {
                            if(model->MOS3bulkJctBotGradingCoeff == .5) {
                                sarg = sargsw = 1/sqrt(arg);
                            } else {
                                sarg = sargsw =
                                        exp(-model->MOS3bulkJctBotGradingCoeff*
                                        log(arg));
                            }
                        } else {
                            if(model->MOS3bulkJctBotGradingCoeff == .5) {
                                sarg = 1/sqrt(arg);
                            } else {
#endif /*NOSQRT*/
                                sarg = exp(-model->MOS3bulkJctBotGradingCoeff*
                                        log(arg));
#ifndef NOSQRT
                            }
                            if(model->MOS3bulkJctSideGradingCoeff == .5) {
                                sargsw = 1/sqrt(arg);
                            } else {
#endif /*NOSQRT*/
                                sargsw =exp(-model->MOS3bulkJctSideGradingCoeff*
                                        log(arg));
#ifndef NOSQRT
                            }
                        }
#endif /*NOSQRT*/
		    lcapbs=here->MOS3Cbs*sarg+
                                here->MOS3Cbssw*sargsw;
		    lcapbs2 = model->MOS3type*0.5/here->MOS3tBulkPot*(
			here->MOS3Cbs*model->MOS3bulkJctBotGradingCoeff*
			sarg/arg + here->MOS3Cbssw*
			model->MOS3bulkJctSideGradingCoeff*sargsw/arg);
		    lcapbs3 = here->MOS3Cbs*sarg*
			model->MOS3bulkJctBotGradingCoeff*
			(model->MOS3bulkJctBotGradingCoeff+1);
		    lcapbs3 += here->MOS3Cbssw*sargsw*
			model->MOS3bulkJctSideGradingCoeff*
			(model->MOS3bulkJctSideGradingCoeff+1);
		    lcapbs3 = lcapbs3/(6*here->MOS3tBulkPot*
			here->MOS3tBulkPot*arg*arg);
                    } else {
                    /*    *(ckt->CKTstate0 + here->MOS3qbs)= here->MOS3f4s +
                                vbs*(here->MOS3f2s+vbs*(here->MOS3f3s/2));*/
                        lcapbs=here->MOS3f2s+here->MOS3f3s*vbs;
			lcapbs2 = 0.5*here->MOS3f3s;
			lcapbs3 = 0;
                    }
                    if (vbd < here->MOS3tDepCap) {
                        arg=1-vbd/here->MOS3tBulkPot;
                        /*
                         * the following block looks somewhat long and messy,
                         * but since most users use the default grading
                         * coefficients of .5, and sqrt is MUCH faster than an
                         * exp(log()) we use this special case code to buy time.
                         * (as much as 10% of total job time!)
                         */
#ifndef NOSQRT
                        if(model->MOS3bulkJctBotGradingCoeff == .5 &&
                                model->MOS3bulkJctSideGradingCoeff == .5) {
                            sarg = sargsw = 1/sqrt(arg);
                        } else {
                            if(model->MOS3bulkJctBotGradingCoeff == .5) {
                                sarg = 1/sqrt(arg);
                            } else {
#endif /*NOSQRT*/
                                sarg = exp(-model->MOS3bulkJctBotGradingCoeff*
                                        log(arg));
#ifndef NOSQRT
                            }
                            if(model->MOS3bulkJctSideGradingCoeff == .5) {
                                sargsw = 1/sqrt(arg);
                            } else {
#endif /*NOSQRT*/
                                sargsw =exp(-model->MOS3bulkJctSideGradingCoeff*
                                        log(arg));
#ifndef NOSQRT
                            }
                        }
#endif /*NOSQRT*/
		    lcapbd=here->MOS3Cbd*sarg+
                                here->MOS3Cbdsw*sargsw;
		    lcapbd2 = model->MOS3type*0.5/here->MOS3tBulkPot*(
			here->MOS3Cbd*model->MOS3bulkJctBotGradingCoeff*
			sarg/arg + here->MOS3Cbdsw*
			model->MOS3bulkJctSideGradingCoeff*sargsw/arg);
		    lcapbd3 = here->MOS3Cbd*sarg*
			model->MOS3bulkJctBotGradingCoeff*
			(model->MOS3bulkJctBotGradingCoeff+1);
		    lcapbd3 += here->MOS3Cbdsw*sargsw*
			model->MOS3bulkJctSideGradingCoeff*
			(model->MOS3bulkJctSideGradingCoeff+1);
		    lcapbd3 = lcapbd3/(6*here->MOS3tBulkPot*
			here->MOS3tBulkPot*arg*arg);
                    } else {
                        lcapbd=here->MOS3f2d + vbd * here->MOS3f3d;
			lcapbd2=0.5*here->MOS3f3d;
			lcapbd3=0;
                    }
            /*
             *     meyer's capacitor model
             */
	/*
	 * the meyer capacitance equations are in DEVqmeyer
	 * these expressions are derived from those equations.
	 * these expressions are incorrect; they assume just one
	 * controlling variable for each charge storage element
	 * while actually there are several;  the MOS3 small
	 * signal ac linear model is also wrong because it 
	 * ignores controlled capacitive elements. these can be 
	 * corrected (as can the linear ss ac model) if the 
	 * expressions for the charge are available
	 */

	 
{


    double phi;
    double cox;
    double vddif;
    double vddif1;
    double vddif2;
    double vgst;
    /* von, lvgs and vdsat have already been adjusted for 
        possible source-drain interchange */



    vgst = lvgs -von;
    phi = here->MOS3tPhi;
    cox = OxideCap;
    if (vgst <= -phi) {
    lcapgb2=lcapgb3=lcapgs2=lcapgs3=lcapgd2=lcapgd3=0;
    } else if (vgst <= -phi/2) {
    lcapgb2= -cox/(4*phi);
    lcapgb3=lcapgs2=lcapgs3=lcapgd2=lcapgd3=0;
    } else if (vgst <= 0) {
    lcapgb2= -cox/(4*phi);
    lcapgb3=lcapgs3=lcapgd2=lcapgd3=0;
    lcapgs2 = cox/(3*phi);
    } else  {			/* the MOS3modes are around because 
					vds has not been adjusted */
        if (vdsat <= here->MOS3mode*vds) {
	lcapgb2=lcapgb3=lcapgs2=lcapgs3=lcapgd2=lcapgd3=0;
        } else {
            vddif = 2.0*vdsat-here->MOS3mode*vds;
            vddif1 = vdsat-here->MOS3mode*vds/*-1.0e-12*/;
            vddif2 = vddif*vddif;
	    lcapgd2 = -vdsat*here->MOS3mode*vds*cox/(3*vddif*vddif2);
	    lcapgd3 = - here->MOS3mode*vds*cox*(vddif - 6*vdsat)/(9*vddif2*vddif2);
	    lcapgs2 = -vddif1*here->MOS3mode*vds*cox/(3*vddif*vddif2);
	    lcapgs3 = - here->MOS3mode*vds*cox*(vddif - 6*vddif1)/(9*vddif2*vddif2);
	    lcapgb2=lcapgb3=0;
        }
    }
    }

		/* the b-s and b-d diodes need no processing ...  */
	here->capbs2 = lcapbs2;
	here->capbs3 = lcapbs3;
	here->capbd2 = lcapbd2;
	here->capbd3 = lcapbd3;
	here->gbs2 = lgbs2;
	here->gbs3 = lgbs3;
	here->gbd2 = lgbd2;
	here->gbd3 = lgbd3;
	here->capgb2 = model->MOS3type*lcapgb2;
	here->capgb3 = lcapgb3;
                /*
                 *   process to get Taylor coefficients, taking into
		 * account type and mode.
                 */
gm2 =  d_cdrain.d2_p2;
gb2 =  d_cdrain.d2_q2;
gds2 =  d_cdrain.d2_r2;
gmb =  d_cdrain.d2_pq;
gbds =  d_cdrain.d2_qr;
gmds =  d_cdrain.d2_pr;
gm3 =  d_cdrain.d3_p3;
gb3 =  d_cdrain.d3_q3;
gds3 =  d_cdrain.d3_r3;
gm2ds =  d_cdrain.d3_p2r;
gm2b =  d_cdrain.d3_p2q;
gb2ds =  d_cdrain.d3_q2r;
gmb2 =  d_cdrain.d3_pq2;
gmds2 =  d_cdrain.d3_pr2;
gbds2 =  d_cdrain.d3_qr2;
gmbds =  d_cdrain.d3_pqr;

	if (here->MOS3mode == 1)
		{
		/* normal mode - no source-drain interchange */

 here->cdr_x2 = gm2;
 here->cdr_y2 = gb2;;
 here->cdr_z2 = gds2;;
 here->cdr_xy = gmb;
 here->cdr_yz = gbds;
 here->cdr_xz = gmds;
 here->cdr_x3 = gm3;
 here->cdr_y3 = gb3;
 here->cdr_z3 = gds3;
 here->cdr_x2z = gm2ds;
 here->cdr_x2y = gm2b;
 here->cdr_y2z = gb2ds;
 here->cdr_xy2 = gmb2;
 here->cdr_xz2 = gmds2;
 here->cdr_yz2 = gbds2;
 here->cdr_xyz = gmbds;

		/* the gate caps have been divided and made into
			Taylor coeffs., but not adjusted for type */

	here->capgs2 = model->MOS3type*lcapgs2;
	here->capgs3 = lcapgs3;
	here->capgd2 = model->MOS3type*lcapgd2;
	here->capgd3 = lcapgd3;
} else {
		/*
		 * inverse mode - source and drain interchanged
		 */

here->cdr_x2 = -gm2;
here->cdr_y2 = -gb2;
here->cdr_z2 = -(gm2 + gb2 + gds2 + 2*(gmb + gmds + gbds));
here->cdr_xy = -gmb;
here->cdr_yz = gmb + gb2 + gbds;
here->cdr_xz = gm2 + gmb + gmds;
here->cdr_x3 = -gm3;
here->cdr_y3 = -gb3;
here->cdr_z3 = gm3 + gb3 + gds3 + 
	3*(gm2b + gm2ds + gmb2 + gb2ds + gmds2 + gbds2) + 6*gmbds ;
here->cdr_x2z = gm3 + gm2b + gm2ds;
here->cdr_x2y = -gm2b;
here->cdr_y2z = gmb2 + gb3 + gb2ds;
here->cdr_xy2 = -gmb2;
here->cdr_xz2 = -(gm3 + 2*(gm2b + gm2ds + gmbds) +
					gmb2 + gmds2);
here->cdr_yz2 = -(gb3 + 2*(gmb2 + gb2ds + gmbds) +
					gm2b + gbds2);
here->cdr_xyz = gm2b + gmb2 + gmbds;

          here->capgs2 = model->MOS3type*lcapgd2;
	  here->capgs3 = lcapgd3;

	  here->capgd2 = model->MOS3type*lcapgs2;
	  here->capgd3 = lcapgs3;

}

/* now to adjust for type and multiply by factors to convert to Taylor coeffs. */

here->cdr_x2 = 0.5*model->MOS3type*here->cdr_x2;
here->cdr_y2 = 0.5*model->MOS3type*here->cdr_y2;
here->cdr_z2 = 0.5*model->MOS3type*here->cdr_z2;
here->cdr_xy = model->MOS3type*here->cdr_xy;
here->cdr_yz = model->MOS3type*here->cdr_yz;
here->cdr_xz = model->MOS3type*here->cdr_xz;
here->cdr_x3 = here->cdr_x3/6.;
here->cdr_y3 = here->cdr_y3/6.;
here->cdr_z3 = here->cdr_z3/6.;
here->cdr_x2z = 0.5*here->cdr_x2z;
here->cdr_x2y = 0.5*here->cdr_x2y;
here->cdr_y2z = 0.5*here->cdr_y2z;
here->cdr_xy2 = 0.5*here->cdr_xy2;
here->cdr_xz2 = 0.5*here->cdr_xz2;
here->cdr_yz2 = 0.5*here->cdr_yz2;


        }
    }
    return(OK);
}
int main(int argc, char *argv[])
{
  int const n=40;
  ov_double mysizeof;
  double *x, *y, *z, *w, *r;
	int i;

  printf("OV_PLATFORM: %s\n", OV_PLATFORM);
  printf("OV_DOUBLE_WIDTH %d\n", OV_DOUBLE_WIDTH);

  if(sizeof(mysizeof) != (OV_DOUBLE_WIDTH*sizeof(double)))
  {
    printf("sizeof error.\n");
    exit(1);
  }

  x=(double*)malloc(sizeof(double)*(n));
  y=(double*)malloc(sizeof(double)*(n));
  z=(double*)malloc(sizeof(double)*(n));
  w=(double*)malloc(sizeof(double)*(n));
  r=(double*)malloc(sizeof(double)*(n));


  /*
     Square Root
  */
  DO_TEST(i, ov_sqrtd, sqrt(x[i]), "SQRT");

  /*
     Fast square Root
  */
  DO_TEST(i, ov_fastsqrtd, sqrt(x[i]), "FAST SQRT");

  /*
     Reciprocal Square Root
  */
  DO_TEST(i, ov_rsqrtd, 1.0/sqrt(x[i]), "RECIPROCAL SQRT");

  /*
     Reciprocal
  */
  DO_TEST(i, ov_rcpd, 1.0/x[i], "RECIPROCAL");

  /*
     Floor
  */
  DO_TEST((2*i -n)/8.0, ov_floord, floor(x[i]), "FLOOR");

  /*
     Ceil
  */
  DO_TEST(i/10.0 -n/20.0, ov_ceild, ceil(x[i]), "CEIL");

  /*
     Abs
  */
  DO_TEST(i-n/2, ov_absd, abs(x[i]), "ABS");


  /*
     GET ZERO
  */
  for (i=0; i<n; i++) y[i]=1.0;
  for (i=0; i<n; i+=OV_DOUBLE_WIDTH) 
  { 
    ov_double vy = ov_getzerod();
    ov_std(&y[i], vy); 
  } 
  for (i=1; i<n; i++) TEST(y[i], 0.0, "OV_GETZERO"); 


  /*
     Masked Ops
  */
  DO_COND_TEST(ov_ltd, <,  "LT");
  DO_COND_TEST(ov_led, <=, "LE");
  DO_COND_TEST(ov_gtd, >,  "GT");
  DO_COND_TEST(ov_ged, >=, "GE");
  DO_COND_TEST(ov_eqd, ==, "GE");

  /*
     Masked Ops with C++ operators
  */
#ifdef __cplusplus
  DO_COND_TESTCPP(<,  "LT");
  DO_COND_TESTCPP(<=, "LE");
  DO_COND_TESTCPP(>,  "GT");
  DO_COND_TESTCPP(>=, "GE");
  DO_COND_TESTCPP(==, "GE");

 /*
     Logical operators on MASKS
  */
  DO_COND_EXPR(ov_andmaskd((vx>vy), (vx> 10.0)), (x[i]>y[i]) && (x[i]> 10.0), "OV_AND");
  DO_COND_EXPR( ov_ormaskd((vx>vy), (vx>-10.0)), (x[i]>y[i]) || (x[i]>-10.0), "OV_OR");

#endif

  /*
     Logical operators on MASKS
  */
  DO_COND_EXPR(ov_andmaskd(ov_gtd(vx,vy), ov_gtd(vx,ov_setd(10.0))), (x[i]>y[i]) && (x[i]> 10.0), "OV_AND");
  DO_COND_EXPR( ov_ormaskd(ov_gtd(vx,vy), ov_gtd(vx,ov_setd(-10.0))), (x[i]>y[i]) || (x[i]>-10.0), "OV_OR");

  /*
     Coditional Reduction Functions
  */
  DO_COND_REDUCTION_TEST(i+1,   ov_alld, ov_gtd, >,  "ALL GT");
  DO_COND_REDUCTION_TEST(i+i%2, ov_alld, ov_ged, >=, "ALL GE");
  DO_COND_REDUCTION_TEST(i  ,   ov_alld, ov_eqd, ==, "ALL EQ");
  DO_COND_REDUCTION_TEST(i-1,   ov_alld, ov_ltd, <,  "ALL LT");
  DO_COND_REDUCTION_TEST(i-i%2, ov_alld, ov_led, <=, "ALL LE");

  DO_COND_REDUCTION_TEST(i+1,   ov_anyd, ov_gtd, >,  "ANY GT");
  DO_COND_REDUCTION_TEST(i+i%2, ov_anyd, ov_ged, >=, "ANY GE");
  DO_COND_REDUCTION_TEST(i  ,   ov_anyd, ov_eqd, ==, "ANY EQ");
  DO_COND_REDUCTION_TEST(i-1,   ov_anyd, ov_ltd, <,  "ANY LT");
  DO_COND_REDUCTION_TEST(i-i%2, ov_anyd, ov_led, <=, "ANY LE");


  /*
     MATH
  */
  int const ihig=n-2;
  for (i=0; i<n; i++) x[i]=i-n/2;
  for (i=0; i<n; i++) y[i]=10.0*(i+1);
  for (i=0; i<n; i++) z[i]=i*0.5;
  for (i=0; i<ihig; i++) 
  {
    double vx=x[i];
    double vy=y[i+1];
    double vz=z[i+2];
    vz=(vx*vy)+vz;
    double vw=(vz+vx)/vy;
    vw += 100.0;
    vw = vw - vx;
    vw = vw * vx;
    vw = vx * vy -vw;
    vw = MAX(vw, -250.0);
    vw = MIN(vw, 5000.0);
    r[i]=vw;
  }

  for (i=0; i<n; i++) x[i]=i-n/2;
  for (i=0; i<n; i++) y[i]=10.0*(i+1);
  for (i=0; i<n; i++) z[i]=i*0.5;

#ifdef __cplusplus
  for (i=0; i<n; i++) w[i]=9999.9;
  for (i=0; i<ihig; i+=OV_DOUBLE_WIDTH) 
  {
    ov_double vx=ov_ldd(&x[i]);
    ov_double vy=ov_uldd(&y[i+1]);
    ov_double vz=ov_uldd(&z[i+2]);
    vz=(vx*vy)+vz;
    ov_double vw=(vz+vx)/vy;
    vw += 100.0;
    vw = 1.0*vw - vx*1.0;
    vw = vw * (vx/1.0);
    vw = vx * vy -vw;
    vw = ov_maxd(vw, -250.0);
    vw = ov_mind(vw, 5000.0);
   
    ov_std(&w[i], vw); 
  }

  for (i=0; i<ihig; i++) printf("MATH C++ VEC " FMT_OUT
                                 " SCALAR " FMT_OUT "\n",
                                 w[i], r[i]); \

  for (i=1; i<ihig; i++) TEST(w[i], r[i], "MATH C++");

#endif

  for (i=0; i<n; i++) w[i]=9999.9;
  for (i=0; i<ihig; i+=OV_DOUBLE_WIDTH) 
  {
    ov_double vx=ov_ldd(&x[i]);
    ov_double vy=ov_uldd(&y[i+1]);
    ov_double vz=ov_uldd(&z[i+2]);
    vz=ov_maddd(vx,vy,vz);
    ov_double vw=ov_divd(ov_addd(vz, vx), vy);
    vw = ov_addd(vw, ov_setd(100.0));
    vw = ov_subd(vw, vx);
    vw = ov_muld(vw, vx);
    vw = ov_msubd(vx, vy, vw);
    vw = ov_maxd(vw, ov_setd(-250.0));
    vw = ov_mind(vw, ov_setd(5000.0));
    ov_std(&w[i], vw); 
  }


  for (i=0; i<ihig; i++) printf("MATH VEC " FMT_OUT
                                 " SCALAR " FMT_OUT "\n",
                                 w[i], r[i]); \

  for (i=1; i<ihig; i++) TEST(w[i], r[i], "MATH");


  free(x);
  free(y);
  free(z);
  free(w);
  free(r);

  printf("Passed all tests.\n");

  return 0;
}
int
main(int argc, char *argv[])
{
#ifdef __FreeBSD__
	FILE *fpid = NULL;
#endif	
	fd_set *fdsr = NULL, *fdsw = NULL;
	struct sockaddr_in sin;
	struct sockaddr_in lin;
	int ch, s, s2, conflisten = 0, syncfd = 0, i, omax = 0, one = 1;
	socklen_t sinlen;
	u_short port;
	struct servent *ent;
	struct rlimit rlp;
	char *bind_address = NULL;
	const char *errstr;
	char *sync_iface = NULL;
	char *sync_baddr = NULL;

	tzset();
	openlog_r("spamd", LOG_PID | LOG_NDELAY, LOG_DAEMON, &sdata);

	if ((ent = getservbyname("spamd", "tcp")) == NULL)
		errx(1, "Can't find service \"spamd\" in /etc/services");
	port = ntohs(ent->s_port);
	if ((ent = getservbyname("spamd-cfg", "tcp")) == NULL)
		errx(1, "Can't find service \"spamd-cfg\" in /etc/services");
	cfg_port = ntohs(ent->s_port);
	if ((ent = getservbyname("spamd-sync", "udp")) == NULL)
		errx(1, "Can't find service \"spamd-sync\" in /etc/services");
	sync_port = ntohs(ent->s_port);

	if (gethostname(hostname, sizeof hostname) == -1)
		err(1, "gethostname");
	maxfiles = get_maxfiles();
	if (maxcon > maxfiles)
		maxcon = maxfiles;
	if (maxblack > maxfiles)
		maxblack = maxfiles;
	while ((ch =
#ifndef __FreeBSD__
	    getopt(argc, argv, "45l:c:B:p:bdG:h:s:S:M:n:vw:y:Y:")) != -1) {
#else
	    getopt(argc, argv, "45l:c:B:p:bdG:h:s:S:M:n:vw:y:Y:t:m:")) != -1) {
#endif
		switch (ch) {
		case '4':
			nreply = "450";
			break;
		case '5':
			nreply = "550";
			break;
		case 'l':
			bind_address = optarg;
			break;
		case 'B':
			i = atoi(optarg);
			maxblack = i;
			break;
		case 'c':
			i = atoi(optarg);
			if (i > maxfiles) {
				fprintf(stderr,
				    "%d > system max of %d connections\n",
				    i, maxfiles);
				usage();
			}
			maxcon = i;
			break;
		case 'p':
			i = atoi(optarg);
			port = i;
			break;
		case 'd':
			debug = 1;
			break;
		case 'b':
			greylist = 0;
			break;
		case 'G':
			if (sscanf(optarg, "%d:%d:%d", &passtime, &greyexp,
			    &whiteexp) != 3)
				usage();
			/* convert to seconds from minutes */
			passtime *= 60;
			/* convert to seconds from hours */
			whiteexp *= (60 * 60);
			/* convert to seconds from hours */
			greyexp *= (60 * 60);
			break;
		case 'h':
			bzero(&hostname, sizeof(hostname));
			if (strlcpy(hostname, optarg, sizeof(hostname)) >=
			    sizeof(hostname))
				errx(1, "-h arg too long");
			break;
		case 's':
			i = atoi(optarg);
			if (i < 0 || i > 10)
				usage();
			stutter = i;
			break;
		case 'S':
			/* 
			 * strtonum is aviable with FreeBSD 6.1,
			 * for older versions we have to fallback
			 */

			i = strtonum(optarg, 0, 90, &errstr);
			if (errstr)
				usage();
			grey_stutter = i;
			break;
		case 'M':
			low_prio_mx_ip = optarg;
			break;
		case 'n':
			spamd = optarg;
			break;
		case 'v':
			verbose = 1;
			break;
		case 'w':
			window = atoi(optarg);
			if (window <= 0)
				usage();
			break;
		case 'Y':
			if (sync_addhost(optarg, sync_port) != 0)
				sync_iface = optarg;
			syncsend++;
			break;
		case 'y':
			sync_baddr = optarg;
			syncrecv++;
			break;
#ifdef __FreeBSD__
		case 't':
			ipfw_tabno = atoi(optarg);
			break;
		case 'm':
			if (strcmp(optarg, "ipfw") == 0)
				use_pf=0;
			break;
#endif
		default:
			usage();
			break;
		}
	}

	setproctitle("[priv]%s%s",
	    greylist ? " (greylist)" : "",
	    (syncrecv || syncsend) ? " (sync)" : "");

	if (!greylist)
		maxblack = maxcon;
	else if (maxblack > maxcon)
		usage();

	rlp.rlim_cur = rlp.rlim_max = maxcon + 15;
	if (setrlimit(RLIMIT_NOFILE, &rlp) == -1)
		err(1, "setrlimit");

	con = calloc(maxcon, sizeof(*con));
	if (con == NULL)
		err(1, "calloc");

	con->obuf = malloc(8192);

	if (con->obuf == NULL)
		err(1, "malloc");
	con->osize = 8192;

	for (i = 0; i < maxcon; i++)
		con[i].fd = -1;

	signal(SIGPIPE, SIG_IGN);

	s = socket(AF_INET, SOCK_STREAM, 0);
	if (s == -1)
		err(1, "socket");

	if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one,
	    sizeof(one)) == -1)
		return (-1);

	conflisten = socket(AF_INET, SOCK_STREAM, 0);
	if (conflisten == -1)
		err(1, "socket");

	if (setsockopt(conflisten, SOL_SOCKET, SO_REUSEADDR, &one,
	    sizeof(one)) == -1)
		return (-1);

	memset(&sin, 0, sizeof sin);
	sin.sin_len = sizeof(sin);
	if (bind_address) {
		if (inet_pton(AF_INET, bind_address, &sin.sin_addr) != 1)
			err(1, "inet_pton");
	} else
		sin.sin_addr.s_addr = htonl(INADDR_ANY);
	sin.sin_family = AF_INET;
	sin.sin_port = htons(port);

	if (bind(s, (struct sockaddr *)&sin, sizeof sin) == -1)
		err(1, "bind");

	memset(&lin, 0, sizeof sin);
	lin.sin_len = sizeof(sin);
	lin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
	lin.sin_family = AF_INET;
	lin.sin_port = htons(cfg_port);

	if (bind(conflisten, (struct sockaddr *)&lin, sizeof lin) == -1)
		err(1, "bind local");

	if (syncsend || syncrecv) {
		syncfd = sync_init(sync_iface, sync_baddr, sync_port);
		if (syncfd == -1)
			err(1, "sync init");
	}

	pw = getpwnam("_spamd");
	if (!pw)
		pw = getpwnam("nobody");

#ifdef __FreeBSD__
	/* open the pid file just before daemon */
	fpid = fopen(pid_file, "w");
	if (fpid == NULL) {
		syslog(LOG_ERR, "exiting (couldn't create pid file %s)", 
			pid_file);
		err(1, "couldn't create pid file \"%s\"", pid_file);
	}
#endif	

	if (debug == 0) {
		if (daemon(1, 1) == -1)
			err(1, "daemon");
	}

	if (greylist) {
#ifdef __FreeBSD__
		if(use_pf){
#endif			
			pfdev = open("/dev/pf", O_RDWR);
			if (pfdev == -1) {
				syslog_r(LOG_ERR, &sdata, "open /dev/pf: %m");
				exit(1);
			}
#ifdef __FreeBSD__
		} 	
#endif

		maxblack = (maxblack >= maxcon) ? maxcon - 100 : maxblack;
		if (maxblack < 0)
			maxblack = 0;

		/* open pipe to talk to greylister */
		if (pipe(greypipe) == -1) {
			syslog(LOG_ERR, "pipe (%m)");
			exit(1);
		}
		/* open pipe to recieve spamtrap configs */
		if (pipe(trappipe) == -1) {
			syslog(LOG_ERR, "pipe (%m)");
			exit(1);
		}
		jail_pid = fork();
		switch (jail_pid) {
		case -1:
			syslog(LOG_ERR, "fork (%m)");
			exit(1);
		case 0:
			/* child - continue */
			signal(SIGPIPE, SIG_IGN);
			grey = fdopen(greypipe[1], "w");
			if (grey == NULL) {
				syslog(LOG_ERR, "fdopen (%m)");
				_exit(1);
			}
			close(greypipe[0]);
			trapfd = trappipe[0];
			trapcfg = fdopen(trappipe[0], "r");
			if (trapcfg == NULL) {
				syslog(LOG_ERR, "fdopen (%m)");
				_exit(1);
			}
			close(trappipe[1]);
			goto jail;
		}
		/* parent - run greylister */
		grey = fdopen(greypipe[0], "r");
		if (grey == NULL) {
			syslog(LOG_ERR, "fdopen (%m)");
			exit(1);
		}
		close(greypipe[1]);
		trapcfg = fdopen(trappipe[1], "w");
		if (trapcfg == NULL) {
			syslog(LOG_ERR, "fdopen (%m)");
			exit(1);
		}
		close(trappipe[0]);
		return (greywatcher());
		/* NOTREACHED */
	}

jail:
#ifdef __FreeBSD__
	/* after switch user and daemon write and close the pid file */
	if (fpid) {
		fprintf(fpid, "%ld\n", (long) getpid());
		if (fclose(fpid) == EOF) {
			syslog(LOG_ERR, "exiting (couldn't close pid file %s)", 
				pid_file);
			exit(1);
		}
	}
#endif	

	if (chroot("/var/empty") == -1 || chdir("/") == -1) {
		syslog(LOG_ERR, "cannot chdir to /var/empty.");
		exit(1);
	}

	if (pw)
		if (setgroups(1, &pw->pw_gid) ||
		    setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) ||
		    setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
			err(1, "failed to drop privs");

	if (listen(s, 10) == -1)
		err(1, "listen");

	if (listen(conflisten, 10) == -1)
		err(1, "listen");

	if (debug != 0)
		printf("listening for incoming connections.\n");
	syslog_r(LOG_WARNING, &sdata, "listening for incoming connections.");

	while (1) {
		struct timeval tv, *tvp;
		int max, n;
		int writers;

		max = MAX(s, conflisten);
		if (syncrecv)
			max = MAX(max, syncfd);
		max = MAX(max, conffd);
		max = MAX(max, trapfd);

		time(&t);
		for (i = 0; i < maxcon; i++)
			if (con[i].fd != -1)
				max = MAX(max, con[i].fd);

		if (max > omax) {
			free(fdsr);
			fdsr = NULL;
			free(fdsw);
			fdsw = NULL;
			fdsr = (fd_set *)calloc(howmany(max+1, NFDBITS),
			    sizeof(fd_mask));
			if (fdsr == NULL)
				err(1, "calloc");
			fdsw = (fd_set *)calloc(howmany(max+1, NFDBITS),
			    sizeof(fd_mask));
			if (fdsw == NULL)
				err(1, "calloc");
			omax = max;
		} else {
			memset(fdsr, 0, howmany(max+1, NFDBITS) *
			    sizeof(fd_mask));
			memset(fdsw, 0, howmany(max+1, NFDBITS) *
			    sizeof(fd_mask));
		}

		writers = 0;
		for (i = 0; i < maxcon; i++) {
			if (con[i].fd != -1 && con[i].r) {
				if (con[i].r + MAXTIME <= t) {
					closecon(&con[i]);
					continue;
				}
				FD_SET(con[i].fd, fdsr);
			}
			if (con[i].fd != -1 && con[i].w) {
				if (con[i].w + MAXTIME <= t) {
					closecon(&con[i]);
					continue;
				}
				if (con[i].w <= t)
					FD_SET(con[i].fd, fdsw);
				writers = 1;
			}
		}
		FD_SET(s, fdsr);

		/* only one active config conn at a time */
		if (conffd == -1)
			FD_SET(conflisten, fdsr);
		else
			FD_SET(conffd, fdsr);
		if (trapfd != -1)
			FD_SET(trapfd, fdsr);
		if (syncrecv)
			FD_SET(syncfd, fdsr);

		if (writers == 0) {
			tvp = NULL;
		} else {
			tv.tv_sec = 1;
			tv.tv_usec = 0;
			tvp = &tv;
		}

		n = select(max+1, fdsr, fdsw, NULL, tvp);
		if (n == -1) {
			if (errno != EINTR)
				err(1, "select");
			continue;
		}
		if (n == 0)
			continue;

		for (i = 0; i < maxcon; i++) {
			if (con[i].fd != -1 && FD_ISSET(con[i].fd, fdsr))
				handler(&con[i]);
			if (con[i].fd != -1 && FD_ISSET(con[i].fd, fdsw))
				handlew(&con[i], clients + 5 < maxcon);
		}
		if (FD_ISSET(s, fdsr)) {
			sinlen = sizeof(sin);
			s2 = accept(s, (struct sockaddr *)&sin, &sinlen);
			if (s2 == -1)
				/* accept failed, they may try again */
				continue;
			for (i = 0; i < maxcon; i++)
				if (con[i].fd == -1)
					break;
			if (i == maxcon)
				close(s2);
			else {
				initcon(&con[i], s2, (struct sockaddr *)&sin);
				syslog_r(LOG_INFO, &sdata,
				    "%s: connected (%d/%d)%s%s",
				    con[i].addr, clients, blackcount,
				    ((con[i].lists == NULL) ? "" :
				    ", lists:"),
				    ((con[i].lists == NULL) ? "":
				    con[i].lists));
			}
		}
		if (FD_ISSET(conflisten, fdsr)) {
			sinlen = sizeof(lin);
			conffd = accept(conflisten, (struct sockaddr *)&lin,
			    &sinlen);
			if (conffd == -1)
				/* accept failed, they may try again */
				continue;
			else if (ntohs(lin.sin_port) >= IPPORT_RESERVED) {
				close(conffd);
				conffd = -1;
			}
		}
		if (conffd != -1 && FD_ISSET(conffd, fdsr))
			do_config();
		if (trapfd != -1 && FD_ISSET(trapfd, fdsr))
			read_configline(trapcfg);
		if (syncrecv && FD_ISSET(syncfd, fdsr))
			sync_recv();
	}
	exit(1);
}
Beispiel #18
0
/*
 * ----------------------------------------------------------
 * Set version of $extract
 *
 * Arguments:
 *	src	- source mval
 *	expr	- expression string mval to be inserted into source
 *	schar	- starting character index to be replaced
 *	echar	- ending character index to be replaced
 *	dst	- destination mval where the result is saved.
 *
 * Return:
 *	none
 * ----------------------------------------------------------
 */
void op_setextract(mval *src, mval *expr, int schar, int echar, mval *dst)
{
	int		srclen, padlen, pfxlen, sfxoff, sfxlen, dstlen, bytelen, skip, char_len;
	unsigned char	*srcptr, *srcbase, *srctop, *straddr;

	error_def(ERR_MAXSTRLEN);

	padlen = pfxlen = sfxlen = 0;
	MV_FORCE_STR(expr);	/* Expression to put into piece place */
	if (MV_DEFINED(src))
	{
		MV_FORCE_STR(src);	/* Make sure is string prior to length check */
		srclen = src->str.len;
	} else	/* Source is not defined -- treat as a null string */
		srclen = 0;
	schar = MAX(schar, 1);	/* schar starts at 1 at a minimum */

	/* There are four cases in the spec:
	   1) schar > echar or echar < 1 -- glvn and naked indicator are not changed. This is
	                                    handled by generated code in m_set
	   2) echar >= schar-1 > $L(src) -- dst = src_$J("",schar-1-$L(src))_expr
	   3) schar-1 <= $L(src) < echar -- dst = $E(src,1,schar-1)_expr
	   4) All others                 -- dst = $E(src,1,schar-1)_expr_$E(src,echar+1,$L(src))
	*/
	srcbase = (unsigned char *)src->str.addr;
	srctop = srcbase + srclen;
	for (srcptr = srcbase, skip = schar - 1; (skip > 0 && srcptr < srctop); --skip)
	{ /* skip the first schar - 1 characters */
		if (!UTF8_VALID(srcptr, srctop, bytelen) && !badchar_inhibit)
			utf8_badchar(0, srcptr, srctop, 0, NULL);
		srcptr += bytelen;
	}
	pfxlen = (int)(srcptr - srcbase);
	if (skip > 0)
	{ /* Case #2: schar is past the string length. echar test handled in generated code.
	     Should be padded with as many spaces as characters remained to be skipped */
		padlen = skip;
	}
	for (skip = echar - schar + 1; (skip > 0 && srcptr < srctop); --skip)
	{ /* skip up to the character position echar */
		if (!UTF8_VALID(srcptr, srctop, bytelen) && !badchar_inhibit)
			utf8_badchar(0, srcptr, srctop, 0, NULL);
		srcptr += bytelen;
	}
	char_len = 0;
	if (skip <= 0)
	{ /* Case #4: echar is within the string length, suffix to be added */
		sfxoff = (int)(srcptr - srcbase);
		sfxlen = (int)(srctop - srcptr);
		if (!badchar_inhibit && sfxlen > 0)
		{ /* validate the suffix, and we can compute char_len as well */
			for (; (srcptr < srctop); ++char_len)
			{
				if (!UTF8_VALID(srcptr, srctop, bytelen))
					utf8_badchar(0, srcptr, srctop, 0, NULL);
				srcptr += bytelen;
			}
			MV_FORCE_LEN(expr);
			char_len += schar - 1 + expr->str.char_len;
		}
	}

	/* Calculate total string len */
	dstlen = pfxlen + padlen + expr->str.len + sfxlen;
	if (dstlen > MAX_STRLEN)
		rts_error(VARLSTCNT(1) ERR_MAXSTRLEN);
	ENSURE_STP_FREE_SPACE(dstlen);

	srcbase = (unsigned char *)src->str.addr;
	straddr = stringpool.free;

	if (0 < pfxlen)
	{ /* copy prefix */
		memcpy(straddr, srcbase, pfxlen);
		straddr += pfxlen;
	}
	if (0 < padlen)
	{ /* insert padding */
		memset(straddr, ' ', padlen);
		straddr += padlen;
	}
	if (0 < expr->str.len)
	{ /* copy expression */
		memcpy(straddr, expr->str.addr, expr->str.len);
		straddr += expr->str.len;
	}
	if (0 < sfxlen)
	{ /* copy suffix */
		memcpy(straddr, srcbase + sfxoff, sfxlen);
		straddr += sfxlen;
	}
	assert(straddr - stringpool.free == dstlen);
	MV_INIT_STRING(dst, straddr - stringpool.free, (char *)stringpool.free);
	if (0 < char_len)
	{
		dst->mvtype |= MV_UTF_LEN;
		dst->str.char_len = char_len;
	}
	stringpool.free = straddr;
}
Beispiel #19
0
/*----------------------------------------------------------------------
            Parameters:

           Description:
----------------------------------------------------------------------*/
MRI *
MRIprobabilityThresholdNeighborhoodOn(MRI *mri_src, MRI *mri_prob,MRI *mri_dst,
                                      float threshold, int nsize, int out_label)
{
    BUFTYPE   *pprob, out_val ;
    int       width, height, depth, x, y, z, x1, y1, z1, xi, yi, zi,
              xmin, xmax, ymin, ymax, zmin, zmax, nchanged ;
    float     nvox ;

    if (mri_prob->type != MRI_UCHAR)
        ErrorReturn(NULL, (ERROR_UNSUPPORTED,
                           "MRI3Dthreshold: prob must be MRI_UCHAR")) ;

    if (!mri_dst)
        mri_dst = MRIclone(mri_src, NULL) ;

    width = mri_src->width ;
    height = mri_src->height ;
    depth = mri_src->depth ;


    /* now apply the inverse morph to build an average wm representation
       of the input volume
       */

    xmin = width ;
    ymin = height ;
    zmin = depth ;
    xmax = ymax = zmax = 0 ;
    for (z = 0 ; z < depth ; z++)
    {
        for (y = 0 ; y < height ; y++)
        {
            pprob = &MRIvox(mri_prob, 0, y, z) ;
            for (x = 0 ; x < width ; x++)
            {
                if (*pprob++ > threshold)
                {
                    if (x < xmin)
                        xmin = x ;
                    if (x > xmax)
                        xmax = x ;
                    if (y < ymin)
                        ymin = y ;
                    if (y > ymax)
                        ymax = y ;
                    if (z < zmin)
                        zmin = z ;
                    if (z > zmax)
                        zmax = z ;
                }
            }
        }
    }
    xmin = MAX(xmin-nsize, 0) ;
    ymin = MAX(ymin-nsize, 0) ;
    zmin = MAX(zmin-nsize, 0) ;
    xmax = MIN(xmax+nsize, width-1) ;
    ymax = MIN(ymax+nsize, height-1) ;
    zmax = MIN(zmax+nsize, depth-1) ;

    if (Gdiag & DIAG_SHOW && DIAG_VERBOSE_ON)
        fprintf(stderr, "bounding box = (%d:%d, %d:%d, %d:%d).\n",
                xmin, xmax, ymin, ymax, zmin, zmax) ;

#if 0
    xmin = ymin = zmin = 0 ;
    xmax = width-1 ;
    ymax = height-1 ;
    zmax = depth-1 ;
#endif

    nchanged = 0 ;
    for (z = zmin ; z <= zmax ; z++)
    {
        for (y = ymin ; y <= ymax ; y++)
        {
            for (x = xmin ; x <= xmax ; x++)
            {
                if (DEBUG_POINT(x,y,z))
                    DiagBreak() ;
                out_val = out_label ;
                for (z1 = -nsize ; z1 <= nsize ; z1++)
                {
                    zi = mri_src->zi[z+z1] ;
                    for (y1 = -nsize ; y1 <= nsize ; y1++)
                    {
                        yi = mri_src->yi[y+y1] ;
                        for (x1 = -nsize ; x1 <= nsize ; x1++)
                        {
                            xi = mri_src->xi[x+x1] ;
                            if (MRIvox(mri_prob, xi, yi, zi) < threshold)
                            {
                                out_val = MRIvox(mri_src, x, y, z) ;
                                break ;
                            }
                        }
                    }
                }
                if (out_val == out_label && MRIvox(mri_src,x,y,z) != out_label)
                    nchanged++ ;
                MRIvox(mri_dst, x, y, z) = out_val ;
            }
        }
    }

    nvox = (float)(width*height*depth) ;
    fprintf(stderr, "%8d of %8d voxels changed - %2.1f%%.\n",
            nchanged, (int)nvox, 100.0f*(float)nchanged/nvox) ;

    return(mri_dst) ;
}
Beispiel #20
0
/* The terrain revealing ray callback */
static void doWaveTerrain(const BASE_OBJECT *psObj, TILEPOS *recordTilePos, int *lastRecordTilePos)
{
	const int sx = psObj->pos.x;
	const int sy = psObj->pos.y;
	const int sz = psObj->pos.z + MAX(MIN_VIS_HEIGHT, psObj->sDisplay.imd->max.y);
	const unsigned radius = objSensorRange(psObj);
	const int rayPlayer = psObj->player;
	size_t i;
	size_t size;
	const WavecastTile *tiles = getWavecastTable(radius, &size);
	int tileHeight, perspectiveHeight, perspectiveHeightLeeway;
#define MAX_WAVECAST_LIST_SIZE 1360  // Trivial upper bound to what a fully upgraded WSS can use (its number of angles). Should probably be some factor times the maximum possible radius. Is probably a lot more than needed. Tested to need at least 180.
	int heights[2][MAX_WAVECAST_LIST_SIZE];
	int angles[2][MAX_WAVECAST_LIST_SIZE + 1];
	int readListSize = 0, readListPos = 0, writeListPos = 0;  // readListSize, readListPos dummy initialisations.
	int readList = 0;  // Reading from this list, writing to the other. Could also initialise to rand()%2.
	int lastHeight = 0;  // lastHeight dummy initialisation.
	int lastAngle = 0x7FFFFFFF;

	// Start with full vision of all angles. (If someday wanting to make droids that can only look in one direction, change here, after getting the original angle values saved in the wavecast table.)
	heights[!readList][writeListPos] = -0x7FFFFFFF-1;  // Smallest integer.
	angles[!readList][writeListPos] = 0;               // Smallest angle.
	++writeListPos;

	for (i = 0; i < size; ++i)
	{
		const int mapX = map_coord(sx) + tiles[i].dx;
		const int mapY = map_coord(sy) + tiles[i].dy;
		MAPTILE *psTile;
		bool seen = false;

		if (mapX < 0 || mapX >= mapWidth || mapY < 0 || mapY >= mapHeight)
		{
			continue;
		}
		psTile = mapTile(mapX, mapY);
		tileHeight = psTile->height;
		perspectiveHeight = (tileHeight - sz) * tiles[i].invRadius;
		perspectiveHeightLeeway = (tileHeight - sz + MIN_VIS_HEIGHT) * tiles[i].invRadius;

		if (tiles[i].angBegin < lastAngle)
		{
			// Gone around the circle. (Or just started scan.)
			angles[!readList][writeListPos] = lastAngle;

			// Flip the lists.
			readList = !readList;
			readListPos = 0;
			readListSize = writeListPos;
			writeListPos = 0;
			lastHeight = 1;  // Impossible value since tiles[i].invRadius > 1 for all i, so triggers writing first entry in list.
		}
		lastAngle = tiles[i].angEnd;

		while (angles[readList][readListPos + 1] <= tiles[i].angBegin && readListPos < readListSize)
		{
			++readListPos;  // Skip, not relevant.
		}

		while (angles[readList][readListPos] < tiles[i].angEnd && readListPos < readListSize)
		{
			int oldHeight = heights[readList][readListPos];
			int newHeight = MAX(oldHeight, perspectiveHeight);
			seen = seen || perspectiveHeightLeeway >= oldHeight; // consider point slightly above ground in case there is something on the tile
			if (newHeight != lastHeight)
			{
				heights[!readList][writeListPos] = newHeight;
				angles[!readList][writeListPos] = MAX(angles[readList][readListPos], tiles[i].angBegin);
				lastHeight = newHeight;
				++writeListPos;
				ASSERT_OR_RETURN( , writeListPos <= MAX_WAVECAST_LIST_SIZE, "Visibility too complicated! Need to increase MAX_WAVECAST_LIST_SIZE.");
			}
			++readListPos;
		}
		--readListPos;

		if (seen)
		{
			// Can see this tile.
			psTile->tileExploredBits |= alliancebits[rayPlayer];                            // Share exploration with allies too
			visMarkTile(psObj, mapX, mapY, psTile, recordTilePos, lastRecordTilePos);   // Mark this tile as seen by our sensor
		}
	}
Beispiel #21
0
CV_IMPL CvFileStorage*
cvOpenFileStorage( const char* query, CvMemStorage* dststorage, int flags, const char* encoding )
{
    CvFileStorage* fs = 0;
    int default_block_size = 1 << 18;
    bool append = (flags & 3) == CV_STORAGE_APPEND;
    bool mem = (flags & CV_STORAGE_MEMORY) != 0;
    bool write_mode = (flags & 3) != 0;
    bool write_base64 = (write_mode || append) && (flags & CV_STORAGE_BASE64) != 0;
    bool isGZ = false;
    size_t fnamelen = 0;
    const char * filename = query;

    std::vector<std::string> params;
    if ( !mem )
    {
        params = analyze_file_name( query );
        if ( !params.empty() )
            filename = params.begin()->c_str();

        if ( write_base64 == false && is_param_exist( params, "base64" ) )
            write_base64 = (write_mode || append);
    }

    if( !filename || filename[0] == '\0' )
    {
        if( !write_mode )
            CV_Error( CV_StsNullPtr, mem ? "NULL or empty filename" : "NULL or empty buffer" );
        mem = true;
    }
    else
        fnamelen = strlen(filename);

    if( mem && append )
        CV_Error( CV_StsBadFlag, "CV_STORAGE_APPEND and CV_STORAGE_MEMORY are not currently compatible" );

    fs = (CvFileStorage*)cvAlloc( sizeof(*fs) );
    CV_Assert(fs);
    memset( fs, 0, sizeof(*fs));

    fs->memstorage = cvCreateMemStorage( default_block_size );
    fs->dststorage = dststorage ? dststorage : fs->memstorage;

    fs->flags = CV_FILE_STORAGE;
    fs->write_mode = write_mode;

    if( !mem )
    {
        fs->filename = (char*)cvMemStorageAlloc( fs->memstorage, fnamelen+1 );
        strcpy( fs->filename, filename );

        char* dot_pos = strrchr(fs->filename, '.');
        char compression = '\0';

        if( dot_pos && dot_pos[1] == 'g' && dot_pos[2] == 'z' &&
            (dot_pos[3] == '\0' || (cv_isdigit(dot_pos[3]) && dot_pos[4] == '\0')) )
        {
            if( append )
            {
                cvReleaseFileStorage( &fs );
                CV_Error(CV_StsNotImplemented, "Appending data to compressed file is not implemented" );
            }
            isGZ = true;
            compression = dot_pos[3];
            if( compression )
                dot_pos[3] = '\0', fnamelen--;
        }

        if( !isGZ )
        {
            fs->file = fopen(fs->filename, !fs->write_mode ? "rt" : !append ? "wt" : "a+t" );
            if( !fs->file )
                goto _exit_;
        }
        else
        {
            #if USE_ZLIB
            char mode[] = { fs->write_mode ? 'w' : 'r', 'b', compression ? compression : '3', '\0' };
            fs->gzfile = gzopen(fs->filename, mode);
            if( !fs->gzfile )
                goto _exit_;
            #else
            cvReleaseFileStorage( &fs );
            CV_Error(CV_StsNotImplemented, "There is no compressed file storage support in this configuration");
            #endif
        }
    }

    fs->roots = 0;
    fs->struct_indent = 0;
    fs->struct_flags = 0;
    fs->wrap_margin = 71;

    if( fs->write_mode )
    {
        int fmt = flags & CV_STORAGE_FORMAT_MASK;

        if( mem )
            fs->outbuf = new std::deque<char>;

        if( fmt == CV_STORAGE_FORMAT_AUTO && filename )
        {
            const char* dot_pos = NULL;
            const char* dot_pos2 = NULL;
            // like strrchr() implementation, but save two last positions simultaneously
            for (const char* pos = filename; pos[0] != 0; pos++)
            {
                if (pos[0] == '.')
                {
                    dot_pos2 = dot_pos;
                    dot_pos = pos;
                }
            }
            if (cv_strcasecmp(dot_pos, ".gz") && dot_pos2 != NULL)
            {
                dot_pos = dot_pos2;
            }
            fs->fmt
                = (cv_strcasecmp(dot_pos, ".xml") || cv_strcasecmp(dot_pos, ".xml.gz"))
                ? CV_STORAGE_FORMAT_XML
                : (cv_strcasecmp(dot_pos, ".json") || cv_strcasecmp(dot_pos, ".json.gz"))
                ? CV_STORAGE_FORMAT_JSON
                : CV_STORAGE_FORMAT_YAML
                ;
        }
        else if ( fmt != CV_STORAGE_FORMAT_AUTO )
        {
            fs->fmt = fmt;
        }
        else
        {
            fs->fmt = CV_STORAGE_FORMAT_XML;
        }

        // we use factor=6 for XML (the longest characters (' and ") are encoded with 6 bytes (&apos; and &quot;)
        // and factor=4 for YAML ( as we use 4 bytes for non ASCII characters (e.g. \xAB))
        int buf_size = CV_FS_MAX_LEN*(fs->fmt == CV_STORAGE_FORMAT_XML ? 6 : 4) + 1024;

        if (append)
        {
            fseek( fs->file, 0, SEEK_END );
            if (ftell(fs->file) == 0)
                append = false;
        }

        fs->write_stack = cvCreateSeq( 0, sizeof(CvSeq), fs->fmt == CV_STORAGE_FORMAT_XML ?
                sizeof(CvXMLStackRecord) : sizeof(int), fs->memstorage );
        fs->is_first = 1;
        fs->struct_indent = 0;
        fs->struct_flags = CV_NODE_EMPTY;
        fs->buffer_start = fs->buffer = (char*)cvAlloc( buf_size + 1024 );
        fs->buffer_end = fs->buffer_start + buf_size;

        fs->base64_writer           = 0;
        fs->is_default_using_base64 = write_base64;
        fs->state_of_writing_base64 = base64::fs::Uncertain;

        fs->is_write_struct_delayed = false;
        fs->delayed_struct_key      = 0;
        fs->delayed_struct_flags    = 0;
        fs->delayed_type_name       = 0;

        if( fs->fmt == CV_STORAGE_FORMAT_XML )
        {
            size_t file_size = fs->file ? (size_t)ftell( fs->file ) : (size_t)0;
            fs->strstorage = cvCreateChildMemStorage( fs->memstorage );
            if( !append || file_size == 0 )
            {
                if( encoding )
                {
                    if( strcmp( encoding, "UTF-16" ) == 0 ||
                        strcmp( encoding, "utf-16" ) == 0 ||
                        strcmp( encoding, "Utf-16" ) == 0 )
                    {
                        cvReleaseFileStorage( &fs );
                        CV_Error( CV_StsBadArg, "UTF-16 XML encoding is not supported! Use 8-bit encoding\n");
                    }

                    CV_Assert( strlen(encoding) < 1000 );
                    char buf[1100];
                    sprintf(buf, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", encoding);
                    icvPuts( fs, buf );
                }
                else
                    icvPuts( fs, "<?xml version=\"1.0\"?>\n" );
                icvPuts( fs, "<opencv_storage>\n" );
            }
            else
            {
                int xml_buf_size = 1 << 10;
                char substr[] = "</opencv_storage>";
                int last_occurence = -1;
                xml_buf_size = MIN(xml_buf_size, int(file_size));
                fseek( fs->file, -xml_buf_size, SEEK_END );
                char* xml_buf = (char*)cvAlloc( xml_buf_size+2 );
                // find the last occurrence of </opencv_storage>
                for(;;)
                {
                    int line_offset = (int)ftell( fs->file );
                    char* ptr0 = icvGets( fs, xml_buf, xml_buf_size ), *ptr;
                    if( !ptr0 )
                        break;
                    ptr = ptr0;
                    for(;;)
                    {
                        ptr = strstr( ptr, substr );
                        if( !ptr )
                            break;
                        last_occurence = line_offset + (int)(ptr - ptr0);
                        ptr += strlen(substr);
                    }
                }
                cvFree( &xml_buf );
                if( last_occurence < 0 )
                {
                    cvReleaseFileStorage( &fs );
                    CV_Error( CV_StsError, "Could not find </opencv_storage> in the end of file.\n" );
                }
                icvCloseFile( fs );
                fs->file = fopen( fs->filename, "r+t" );
                CV_Assert(fs->file);
                fseek( fs->file, last_occurence, SEEK_SET );
                // replace the last "</opencv_storage>" with " <!-- resumed -->", which has the same length
                icvPuts( fs, " <!-- resumed -->" );
                fseek( fs->file, 0, SEEK_END );
                icvPuts( fs, "\n" );
            }
            fs->start_write_struct = icvXMLStartWriteStruct;
            fs->end_write_struct = icvXMLEndWriteStruct;
            fs->write_int = icvXMLWriteInt;
            fs->write_real = icvXMLWriteReal;
            fs->write_string = icvXMLWriteString;
            fs->write_comment = icvXMLWriteComment;
            fs->start_next_stream = icvXMLStartNextStream;
        }
        else if( fs->fmt == CV_STORAGE_FORMAT_YAML )
        {
            if( !append)
                icvPuts( fs, "%YAML:1.0\n---\n" );
            else
                icvPuts( fs, "...\n---\n" );
            fs->start_write_struct = icvYMLStartWriteStruct;
            fs->end_write_struct = icvYMLEndWriteStruct;
            fs->write_int = icvYMLWriteInt;
            fs->write_real = icvYMLWriteReal;
            fs->write_string = icvYMLWriteString;
            fs->write_comment = icvYMLWriteComment;
            fs->start_next_stream = icvYMLStartNextStream;
        }
        else
        {
            if( !append )
                icvPuts( fs, "{\n" );
            else
            {
                bool valid = false;
                long roffset = 0;
                for ( ;
                      fseek( fs->file, roffset, SEEK_END ) == 0;
                      roffset -= 1 )
                {
                    const char end_mark = '}';
                    if ( fgetc( fs->file ) == end_mark )
                    {
                        fseek( fs->file, roffset, SEEK_END );
                        valid = true;
                        break;
                    }
                }

                if ( valid )
                {
                    icvCloseFile( fs );
                    fs->file = fopen( fs->filename, "r+t" );
                    CV_Assert(fs->file);
                    fseek( fs->file, roffset, SEEK_END );
                    fputs( ",", fs->file );
                }
                else
                {
                    CV_Error( CV_StsError, "Could not find '}' in the end of file.\n" );
                }
            }
            fs->struct_indent = 4;
            fs->start_write_struct = icvJSONStartWriteStruct;
            fs->end_write_struct = icvJSONEndWriteStruct;
            fs->write_int = icvJSONWriteInt;
            fs->write_real = icvJSONWriteReal;
            fs->write_string = icvJSONWriteString;
            fs->write_comment = icvJSONWriteComment;
            fs->start_next_stream = icvJSONStartNextStream;
        }
    }
    else
    {
        if( mem )
        {
            fs->strbuf = filename;
            fs->strbufsize = fnamelen;
        }

        size_t buf_size = 1 << 20;
        const char* yaml_signature = "%YAML";
        const char* json_signature = "{";
        const char* xml_signature  = "<?xml";
        char buf[16];
        icvGets( fs, buf, sizeof(buf)-2 );
        char* bufPtr = cv_skip_BOM(buf);
        size_t bufOffset = bufPtr - buf;

        if(strncmp( bufPtr, yaml_signature, strlen(yaml_signature) ) == 0)
            fs->fmt = CV_STORAGE_FORMAT_YAML;
        else if(strncmp( bufPtr, json_signature, strlen(json_signature) ) == 0)
            fs->fmt = CV_STORAGE_FORMAT_JSON;
        else if(strncmp( bufPtr, xml_signature, strlen(xml_signature) ) == 0)
            fs->fmt = CV_STORAGE_FORMAT_XML;
        else if(fs->strbufsize  == bufOffset)
            CV_Error(CV_BADARG_ERR, "Input file is empty");
        else
            CV_Error(CV_BADARG_ERR, "Unsupported file storage format");

        if( !isGZ )
        {
            if( !mem )
            {
                fseek( fs->file, 0, SEEK_END );
                buf_size = ftell( fs->file );
            }
            else
                buf_size = fs->strbufsize;
            buf_size = MIN( buf_size, (size_t)(1 << 20) );
            buf_size = MAX( buf_size, (size_t)(CV_FS_MAX_LEN*2 + 1024) );
        }
        icvRewind(fs);
        fs->strbufpos = bufOffset;

        fs->str_hash = cvCreateMap( 0, sizeof(CvStringHash),
                        sizeof(CvStringHashNode), fs->memstorage, 256 );

        fs->roots = cvCreateSeq( 0, sizeof(CvSeq),
                        sizeof(CvFileNode), fs->memstorage );

        fs->buffer = fs->buffer_start = (char*)cvAlloc( buf_size + 256 );
        fs->buffer_end = fs->buffer_start + buf_size;
        fs->buffer[0] = '\n';
        fs->buffer[1] = '\0';

        //mode = cvGetErrMode();
        //cvSetErrMode( CV_ErrModeSilent );
        CV_TRY
        {
            switch (fs->fmt)
            {
            case CV_STORAGE_FORMAT_XML : { icvXMLParse ( fs ); break; }
            case CV_STORAGE_FORMAT_YAML: { icvYMLParse ( fs ); break; }
            case CV_STORAGE_FORMAT_JSON: { icvJSONParse( fs ); break; }
            default: break;
            }
        }
        CV_CATCH_ALL
        {
            fs->is_opened = true;
            cvReleaseFileStorage( &fs );
            CV_RETHROW();
        }
        //cvSetErrMode( mode );

        // release resources that we do not need anymore
        cvFree( &fs->buffer_start );
        fs->buffer = fs->buffer_end = 0;
    }
    fs->is_opened = true;

_exit_:
    if( fs )
    {
        if( cvGetErrStatus() < 0 || (!fs->file && !fs->gzfile && !fs->outbuf && !fs->strbuf) )
        {
            cvReleaseFileStorage( &fs );
        }
        else if( !fs->write_mode )
        {
            icvCloseFile(fs);
            // we close the file since it's not needed anymore. But icvCloseFile() resets is_opened,
            // which may be misleading. Since we restore the value of is_opened.
            fs->is_opened = true;
        }
    }

    return  fs;
}
// host stub function
void ops_par_loop_update_halo_kernel4_plus_2_a(char const *name,
                                               ops_block block, int dim,
                                               int *range, ops_arg arg0,
                                               ops_arg arg1, ops_arg arg2) {

  ops_arg args[3] = {arg0, arg1, arg2};

#ifdef CHECKPOINTING
  if (!ops_checkpointing_before(args, 3, range, 46))
    return;
#endif

  ops_timing_realloc(46, "update_halo_kernel4_plus_2_a");
  OPS_kernels[46].count++;

  // compute localy allocated range for the sub-block
  int start[2];
  int end[2];
#ifdef OPS_MPI
  sub_block_list sb = OPS_sub_block_list[block->index];
  if (!sb->owned)
    return;
  for (int n = 0; n < 2; n++) {
    start[n] = sb->decomp_disp[n];
    end[n] = sb->decomp_disp[n] + sb->decomp_size[n];
    if (start[n] >= range[2 * n]) {
      start[n] = 0;
    } else {
      start[n] = range[2 * n] - start[n];
    }
    if (sb->id_m[n] == MPI_PROC_NULL && range[2 * n] < 0)
      start[n] = range[2 * n];
    if (end[n] >= range[2 * n + 1]) {
      end[n] = range[2 * n + 1] - sb->decomp_disp[n];
    } else {
      end[n] = sb->decomp_size[n];
    }
    if (sb->id_p[n] == MPI_PROC_NULL &&
        (range[2 * n + 1] > sb->decomp_disp[n] + sb->decomp_size[n]))
      end[n] += (range[2 * n + 1] - sb->decomp_disp[n] - sb->decomp_size[n]);
  }
#else
  for (int n = 0; n < 2; n++) {
    start[n] = range[2 * n];
    end[n] = range[2 * n + 1];
  }
#endif

  int x_size = MAX(0, end[0] - start[0]);
  int y_size = MAX(0, end[1] - start[1]);

  xdim0 = args[0].dat->size[0];
  xdim1 = args[1].dat->size[0];

  // Timing
  double t1, t2, c1, c2;
  ops_timers_core(&c2, &t2);

  if (xdim0 != xdim0_update_halo_kernel4_plus_2_a_h ||
      xdim1 != xdim1_update_halo_kernel4_plus_2_a_h) {
    xdim0_update_halo_kernel4_plus_2_a = xdim0;
    xdim0_update_halo_kernel4_plus_2_a_h = xdim0;
    xdim1_update_halo_kernel4_plus_2_a = xdim1;
    xdim1_update_halo_kernel4_plus_2_a_h = xdim1;
  }

  int dat0 = (OPS_soa ? args[0].dat->type_size : args[0].dat->elem_size);
  int dat1 = (OPS_soa ? args[1].dat->type_size : args[1].dat->elem_size);

  int *arg2h = (int *)arg2.data;

  // set up initial pointers
  int d_m[OPS_MAX_DIM];
#ifdef OPS_MPI
  for (int d = 0; d < dim; d++)
    d_m[d] =
        args[0].dat->d_m[d] + OPS_sub_dat_list[args[0].dat->index]->d_im[d];
#else
  for (int d = 0; d < dim; d++)
    d_m[d] = args[0].dat->d_m[d];
#endif
  int base0 = dat0 * 1 * (start[0] * args[0].stencil->stride[0] -
                          args[0].dat->base[0] - d_m[0]);
  base0 = base0 +
          dat0 * args[0].dat->size[0] * (start[1] * args[0].stencil->stride[1] -
                                         args[0].dat->base[1] - d_m[1]);
  double *p_a0 = (double *)((char *)args[0].data + base0);

#ifdef OPS_MPI
  for (int d = 0; d < dim; d++)
    d_m[d] =
        args[1].dat->d_m[d] + OPS_sub_dat_list[args[1].dat->index]->d_im[d];
#else
  for (int d = 0; d < dim; d++)
    d_m[d] = args[1].dat->d_m[d];
#endif
  int base1 = dat1 * 1 * (start[0] * args[1].stencil->stride[0] -
                          args[1].dat->base[0] - d_m[0]);
  base1 = base1 +
          dat1 * args[1].dat->size[0] * (start[1] * args[1].stencil->stride[1] -
                                         args[1].dat->base[1] - d_m[1]);
  double *p_a1 = (double *)((char *)args[1].data + base1);

  int *p_a2 = arg2h;

  ops_H_D_exchanges_host(args, 3);
  ops_halo_exchanges(args, 3, range);

  ops_timers_core(&c1, &t1);
  OPS_kernels[46].mpi_time += t1 - t2;

  update_halo_kernel4_plus_2_a_c_wrapper(p_a0, p_a1, p_a2, x_size, y_size);

  ops_timers_core(&c2, &t2);
  OPS_kernels[46].time += t2 - t1;
  ops_set_dirtybit_host(args, 3);
  ops_set_halo_dirtybit3(&args[0], range);
  ops_set_halo_dirtybit3(&args[1], range);

  // Update kernel record
  OPS_kernels[46].transfer += ops_compute_transfer(dim, start, end, &arg0);
  OPS_kernels[46].transfer += ops_compute_transfer(dim, start, end, &arg1);
}
void spqrgpu_buildAssemblyMaps
(
    Long numFronts,
    Long n,
    Long *Fmap,
    Long *Post,
    Long *Super,
    Long *Rp,
    Long *Rj,
    Long *Sleft,
    Long *Sp,
    Long *Sj,
    double *Sx,
    Long *Fm,
    Long *Cm,
    Long *Childp,
    Long *Child,
    Long *CompleteStair,
    int *CompleteRjmap,
    Long *RjmapOffsets,
    int *CompleteRimap,
    Long *RimapOffsets,
    SEntry *cpuS
)
{
    PR (("GPU: building assembly maps:\n")) ;

    /* Use Fmap and Stair to map a front's local rows to global rows. */
    Long sindex = 0;

    for(Long pf=0; pf<numFronts; pf++) // iterate in post-order
    {
        Long f = Post[pf];

        /* Build Fmap for front f. */
        Long pstart = Rp[f], pend = Rp[f+1];
        for (Long p=pstart; p<pend ; p++)
        {
            Fmap[Rj[p]] = p - pstart;
        }

        /* Get workspaces for offset front members */
        Long *Stair = CompleteStair + Rp[f];

        // ---------------------------------------------------------------------
        // initialize the staircase for front F
        // ---------------------------------------------------------------------

        // initialize the staircase with original rows of S
        Long col1 = Super[f], col2 = Super[f+1];
        Long fp = col2 - col1;
        Long fn = Rp[f+1] - Rp[f];

        for (Long j = 0 ; j < fp ; j++)
        {
            // global column j+col1 is the jth pivot column of front F
            Long col = j + col1 ;
            Stair[j] = Sleft [col+1] - Sleft [col] ;
            PR (("GPU init rows, j: %ld count %ld\n", j, Stair[j])) ;
        }

        // contribution blocks from children will be added here
        for (Long j = fp ; j < fn ; j++){ Stair[j] = 0; }

        /* Build Rjmap and Stair for each child of the current front. */
        for(Long p=Childp[f]; p<Childp[f+1]; p++)
        {
            Long c = Child[p];
            PR (("child %ld\n", c)) ;
            ASSERT (c >= 0 && c < f) ;
            int *Rjmap = CompleteRjmap + RjmapOffsets[c];
            Long pc = Rp [c] ;
            Long pcend = Rp [c+1] ;
            Long fnc = pcend - pc ;              // total # cols in child F
            Long fpc = Super [c+1] - Super [c] ; // # of pivot cols in child
            Long cm = Cm [c] ;                   // # of rows in child C
            Long cn = fnc - fpc ;                // # of cols in child C

            // Create the relative column indices of the child's contributions
            // to the parent.  The global column 'col' in the child is a
            // contribution to the jth column of its parent front.  j is
            // a relative column index.
            for (Long pp=0 ; pp<cn ; pp++)
            {
                Long col = Rj [pc+fpc+pp] ;    // global column index
                Long j = Fmap [col] ;          // relative column index
                Rjmap [pp] = j ;               // Save this column
            }

            ASSERT (cm >= 0 && cm <= cn) ;
            pc += fpc ;                        // pointer to column indices in C
            ASSERT (pc + cn == Rp [c+1]) ;
            PR (("  cm %ld cn %ld\n", cm, cn)) ;

            // add the child rows to the staircase
            for (Long ci = 0 ; ci < cm ; ci++)
            {
                Long col = Rj [pc + ci] ;      // leftmost col of this row of C
                Long j = Fmap [col] ;          // global col is jth col of F
                PR (("  child col %ld j %ld\n", col, j)) ;
                ASSERT (j >= 0 && j < fn) ;
                Stair[j]++ ;                   // add this row to jth staircase
            }
        }

        // ---------------------------------------------------------------------
        // replace Stair with cumsum ([0 Stair]), and find # rows of F
        // ---------------------------------------------------------------------

        Long fm = 0 ;
        for (Long j = 0 ; j < fn ; j++)
        {
            Long t = fm ;
            fm += Stair[j] ;
            Stair[j] = t ;
        }
        PR (("fm %ld %ld\n", fm, Stair[fn-1])) ;

        // ---------------------------------------------------------------------
        // pack all the S values into the cpuS workspace & advance scalar stair
        // ---------------------------------------------------------------------

        Long Scount = MAX(0, Sp[Sleft[Super[f+1]]] - Sp[Sleft[Super[f]]]);
        if(Scount > 0)
        {
            for(Long k=0 ; k<fp ; k++)
            {
                /* pack all rows whose leftmost global column index is k+col1 */
                Long leftcol = k + col1 ;

                /* for each row of S whose leftmost column is leftcol */
                for (Long row = Sleft [leftcol]; row < Sleft [leftcol+1]; row++)
                {
                    // get the location of this row in F & advance the staircase
                    Long i = Stair[k]++;

                    /* Pack into S */
                    for (Long p=Sp[row] ; p<Sp[row+1] ; p++)
                    {
                        Long j = Sj[p];
                        cpuS[sindex].findex = i*fn + j;
                        cpuS[sindex].value = Sx[p];
                        sindex++;
                    }
                }
            }
        }

        // ---------------------------------------------------------------------
        // build Rimap
        // ---------------------------------------------------------------------

        for (Long p = Childp [f] ; p < Childp [f+1] ; p++)
        {
            /* Get child details */
            Long c = Child [p] ;                 // get the child c of front F
            int *Rimap = CompleteRimap + RimapOffsets[c];
            int *Rjmap = CompleteRjmap + RjmapOffsets[c];
            Long pc = Rp [c] ;
            // Long pcend = Rp [c+1] ;
            // Long fnc = pcend - pc ;           // total # cols in child F
            Long fpc = Super [c+1] - Super [c] ; // # of pivot cols in child
            Long cm = Cm [c] ;                   // # of rows in child C
            // Long cn = (fnc - fpc) ;           // cn =# of cols in child C
            // ASSERT (cm >= 0 && cm <= cn) ;
            pc += fpc ;                        // pointer to column indices in C
            // ASSERT (pc + cn == Rp [c+1]) ;

            /* -------------------------------------------------------------- */
            /* construct the Rimap                                            */
            /* -------------------------------------------------------------- */

            for (Long ci = 0 ; ci < cm ; ci++)
            {
                Long j = Rjmap[ci] ;          // global col is jth col of F
                ASSERT (j >= 0 && j < fn) ;
                Long i = Stair[j]++ ;         // add row F(i,:) to jth staircase
                ASSERT (i >= 0 && i < fm) ;
                Rimap[ci] = i ;               // keep track of the mapping
            }
        }
    }
}
Beispiel #24
0
static int display(Hashmap *a) {
        Iterator i;
        Group *g;
        Group **array;
        signed path_columns;
        unsigned rows, n = 0, j, maxtcpu = 0, maxtpath = 0;
        char cpu_title[21];

        assert(a);

        /* Set cursor to top left corner and clear screen */
        if (on_tty())
                fputs("\033[H"
                      "\033[2J", stdout);

        array = alloca(sizeof(Group*) * hashmap_size(a));

        HASHMAP_FOREACH(g, a, i)
                if (g->n_tasks_valid || g->cpu_valid || g->memory_valid || g->io_valid)
                        array[n++] = g;

        qsort(array, n, sizeof(Group*), group_compare);

        /* Find the longest names in one run */
        for (j = 0; j < n; j++) {
                unsigned cputlen, pathtlen;
                snprintf(cpu_title, sizeof(cpu_title), "%"PRIu64, array[j]->cpu_usage);
                cputlen = strlen(cpu_title);
                maxtcpu = MAX(maxtcpu, cputlen);
                pathtlen = strlen(array[j]->path);
                maxtpath = MAX(maxtpath, pathtlen);
        }

        if (arg_cpu_type == CPU_PERCENT)
                snprintf(cpu_title, sizeof(cpu_title), "%6s", "%CPU");
        else
                snprintf(cpu_title, sizeof(cpu_title), "%*s", maxtcpu, "CPU Time");

        rows = lines();
        if (rows <= 10)
                rows = 10;

        if (on_tty()) {
                path_columns = columns() - 36 - strlen(cpu_title);
                if (path_columns < 10)
                        path_columns = 10;

                printf("%s%-*s%s %s%7s%s %s%s%s %s%8s%s %s%8s%s %s%8s%s\n\n",
                       arg_order == ORDER_PATH ? ON : "", path_columns, "Path",
                       arg_order == ORDER_PATH ? OFF : "",
                       arg_order == ORDER_TASKS ? ON : "", "Tasks",
                       arg_order == ORDER_TASKS ? OFF : "",
                       arg_order == ORDER_CPU ? ON : "", cpu_title,
                       arg_order == ORDER_CPU ? OFF : "",
                       arg_order == ORDER_MEMORY ? ON : "", "Memory",
                       arg_order == ORDER_MEMORY ? OFF : "",
                       arg_order == ORDER_IO ? ON : "", "Input/s",
                       arg_order == ORDER_IO ? OFF : "",
                       arg_order == ORDER_IO ? ON : "", "Output/s",
                       arg_order == ORDER_IO ? OFF : "");
        } else
                path_columns = maxtpath;

        for (j = 0; j < n; j++) {
                char *p;
                char m[FORMAT_BYTES_MAX];

                if (on_tty() && j + 5 > rows)
                        break;

                g = array[j];

                p = ellipsize(g->path, path_columns, 33);
                printf("%-*s", path_columns, p ? p : g->path);
                free(p);

                if (g->n_tasks_valid)
                        printf(" %7u", g->n_tasks);
                else
                        fputs("       -", stdout);

                if (arg_cpu_type == CPU_PERCENT)
                        if (g->cpu_valid)
                                printf(" %6.1f", g->cpu_fraction*100);
                        else
                                fputs("      -", stdout);
                else
                        printf(" %*"PRIu64, maxtcpu, g->cpu_usage);

                if (g->memory_valid)
                        printf(" %8s", format_bytes(m, sizeof(m), g->memory));
                else
                        fputs("        -", stdout);

                if (g->io_valid) {
                        printf(" %8s",
                               format_bytes(m, sizeof(m), g->io_input_bps));
                        printf(" %8s",
                               format_bytes(m, sizeof(m), g->io_output_bps));
                } else
                        fputs("        -        -", stdout);

                putchar('\n');
        }

        return 0;
}
Beispiel #25
0
int main(int argc, char **argv) {
        std::unordered_map<std::string, std::string> auth;
        int i,                                  // Contador
            j,                                  // Contador
            socks,                              // Tamaño del arreglo sockfds
            addrc,                              // Número de sockets retornado por getaddrinfo()
            conn,                               // file descriptor de conexión
            nfds,                               // Número de sockets con actividad para select()
            childcount,                         // Contador de hijos (uno por conexión TCP activa)
            reqcount,                           // Contador de pedidos en una conexión TCP activa.
            pid,                                // Retorno de fork()
            exitcode,                           // Código de salida de hijos
            talking,                            // Booleano para control de flujo de hijos
            opt,                                // Retorno de getopt()
            verbose = 0,                        // Opción para imprimir mensajes explícitos
            ipv = IPV_UNSET,                    // Opción para protocolo de red (versión de IP)
            backlog = DEFAULT_BACKLOG,          // Opción para máximo número de conexiones en espera
            maxchildren = DEFAULT_MAXCHILDREN,  // Opción para máximo número de hijos
            timeout = DEFAULT_TIMEOUT,          // Opción para tiempo máximo de inactividad de una conexión
            maxreqs = DEFAULT_MAXREQS,          // Opción para máximo número de pedidos por conexión
            calidad = 1;                        // Calidad del servidor
        int *sockfds;                           // Arreglo de file descriptors para atender clientes
        long int la,                            // Retorno de strtol() en lectura de argumentos
                 lb;                            // Retorno de strtol() en lectura de argumentos
        char c,                                 // Caracter leído del cliente
             *auth_file = NULL,
             *service = NULL,                   // Argumento para puerto en que aceptar conexiones
             *narg = NULL,                      // Argumento para máximo número de conexiones en espera
             *marg = NULL,                      // Argumento para máximo número de hijos
             *sarg = NULL,                      // Argumento para tiempo máximo de inactividad de una conexión
             *rarg = NULL,                      // Opción para máximo número de pedidos por conexión
             *str;                              // Respuesta al cliente
        struct timeval t;                       // Tiempo
        struct tm *tstr;                        // Tiempo descompuesto
        struct addrinfo hints,                  // Opciones para getaddrinfo()
                        *results,               // Retorno de getaddrinfo()
                        *rp;                    // Iterador para retorno de getaddrinfo()
        struct protoent *proto;                 // Protocolo de transporte
        FILE *file;                             // Archivo para revisar rango de opción -n
        fd_set fds;                             // Conjunto de file descriptors para select()

        while ((opt = getopt(argc, argv, "a:p:n:m:s:r:c:xytu46vh")) != -1) switch (opt) {
                case 'a':
                        if (auth_file != NULL) free(auth_file);
                        if (asprintf(&auth_file, "%s", optarg) == -1) {
                                fprintf(stderr, "Error copiando string para manejo de argumentos.\n");
                                exit(EX_OSERR);
                        }
                        break;
                case 'p':
                        if (service != NULL) free(service);
                        if (asprintf(&service, "%s", optarg) == -1) {
                                fprintf(stderr, "Error copiando string para manejo de argumentos.\n");
                                exit(EX_OSERR);
                        }
                        break;
                case 'n':
                        if (narg != NULL) free(narg);
                        if (asprintf(&narg, "%s", optarg) == -1) {
                                fprintf(stderr, "Error copiando string para manejo de argumentos.\n");
                                exit(EX_OSERR);
                        }
                        break;
                case 'm':
                        if (marg != NULL) free(marg);
                        if (asprintf(&marg, "%s", optarg) == -1) {
                                fprintf(stderr, "Error copiando string para manejo de argumentos.\n");
                                exit(EX_OSERR);
                        }
                        break;
                case 's':
                        if (sarg != NULL) free(sarg);
                        if (asprintf(&sarg, "%s", optarg) == -1) {
                                fprintf(stderr, "Error copiando string para manejo de argumentos.\n");
                                exit(EX_OSERR);
                        }
                        break;
                case 'x':
                        if (sarg != NULL) free(sarg);
                        timeout = 0;
                        break;
                case 'r':
                        if (rarg != NULL) free(rarg);
                        if (asprintf(&rarg, "%s", optarg) == -1) {
                                fprintf(stderr, "Error copiando string para manejo de argumentos.\n");
                                exit(EX_OSERR);
                        }
                        break;
                case 'c':
                        if ((calidad = atoi(optarg)) < 1 || calidad > 10){
                                fprintf(stderr, "La calidad debe estar entre 1 y 10\n");
                                exit(EX_OSERR);
                        }
                        break;
                case 'y':
                        if (rarg != NULL) free(rarg);
                        maxreqs = 0;
                        break;
                case '4':
                        if (ipv == IPV_UNSET) ipv = IPV_IPV4;
                        else {
                                fprintf(stderr, "%s: Las opciones -4 y -6 son mutuamente excluyentes.\n", argv[0]);
                                exit_usage(argv[0], EX_USAGE);
                        }
                        break;
                case '6':
                        if (ipv == IPV_UNSET) ipv = IPV_IPV6;
                        else {
                                fprintf(stderr, "%s: Las opciones -4 y -6 son mutuamente excluyentes.\n", argv[0]);
                                exit_usage(argv[0], EX_USAGE);
                        }
                        break;
                case 'v':
                        verbose = 1;
                        break;
                case 'h':
                        exit_usage(argv[0], EX_OK);
                        break;
                default:
                        exit_usage(argv[0], EX_USAGE);
        }
        if (auth_file == NULL) {
                fprintf(stderr, "Es obligatorio especificar un archivo de autenticación.\n");
                exit_usage(argv[0], EX_USAGE);
        } else {
                if ((file = fopen(auth_file, "r")) == NULL) {
                        if (verbose) perror("fopen");
                        fprintf(stderr, "No se pudo abrir el archivo de autenticación.\n");
                        exit(EX_DATAERR);
                } else {
                        char *username, *password;
                        do {
                                i = fscanf(file, "%m[^!\n]!%m[^!\n]", &username, &password);
                                if (i == 2) {
                                        auth[std::string(username)] = std::string(password);
                                        free(username);
                                        free(password);
                                }
                        } while (i == 2);
                        fclose(file);
                }
        }
        if (service == NULL) {
                fprintf(stderr, "Es obligatorio especificar un puerto.\n");
                exit_usage(argv[0], EX_USAGE);
        }
        if (narg != NULL) {
                errno = 0;
                la = strtol(narg, NULL, 0);
                if (errno != 0) {
                        if (verbose) perror("strtol");
                        fprintf(stderr, "El argumento de la opción -n tiene un error de formato o es demasiado grande.\n");
                        exit_usage(argv[0], EX_USAGE);
                }
                free(narg);
                backlog = la;
                lb = INT_MAX-1;
                if ((file = fopen("/proc/sys/net/core/somaxconn", "r")) == NULL) {
                        if (verbose) perror("fopen");
                        if (verbose) fprintf(stderr, "No se pudo verificar el valor máximo del sistema para el número de conexiones en espera en un socket.  Es posible que el número máximo de conexiones en espera en un socket sea menor que el pedido.\n");
                } else {
                        errno = 0;
                        i = fscanf(file, "%ld", &lb);
                        if ((i == 0)||(i == EOF)) {
                                if (errno != 0) if (verbose) perror("fscanf");
                                if (verbose) fprintf(stderr, "No se pudo verificar el valor máximo del sistema para el número de conexiones en espera en un socket.  Es posible que el número máximo de conexiones en espera en un socket sea menor que el pedido.\n");
                                lb = INT_MAX-1;
                        }
                        fclose(file);
                }
                if (la < 1 || la > lb) {
                        fprintf(stderr, "El argumento de la opción -n debe ser un entero mayor que cero y menor o igual que %ld.\n", lb);
                        exit_usage(argv[0], EX_USAGE);
                }
        }
        if (marg != NULL) {
                errno = 0;
                la = strtol(marg, NULL, 0);
                if (errno != 0) {
                        if (verbose) perror("strtol");
                        fprintf(stderr, "El argumento de la opción -m tiene un error de formato o es demasiado grande.\n");
                        exit_usage(argv[0], EX_USAGE);
                }
                free(marg);
                if (la<1) {
                        fprintf(stderr, "El argumento de la opción -m debe ser un entero mayor que cero.\n");
                        exit_usage(argv[0], EX_USAGE);
                }
                maxchildren = la;
        }
        if (sarg != NULL) {
                errno = 0;
                la = strtol(sarg, NULL, 0);
                if (errno != 0) {
                        if (verbose) perror("strtol");
                        fprintf(stderr, "El argumento de la opción -s tiene un error de formato o es demasiado grande.\n");
                        exit_usage(argv[0], EX_USAGE);
                }
                free(sarg);
                if (la<0) {
                        fprintf(stderr, "El argumento de la opción -s debe ser un entero no negativo.\n");
                        exit_usage(argv[0], EX_USAGE);
                }
                timeout = la;
        }
        if (rarg != NULL) {
                errno = 0;
                la = strtol(rarg, NULL, 0);
                if (errno != 0) {
                        if (verbose) perror("strtol");
                        fprintf(stderr, "El argumento de la opción -r tiene un error de formato o es demasiado grande.\n");
                        exit_usage(argv[0], EX_USAGE);
                }
                free(rarg);
                if (la<0) {
                        fprintf(stderr, "El argumento de la opción -r debe ser un entero no negativo.\n");
                        exit_usage(argv[0], EX_USAGE);
                }
                maxreqs = la;
        }

        if (fclose(stdin) == EOF) if (verbose) perror("Error cerrando entrada estandar con fclose");

        memset(&hints, 0, sizeof(struct addrinfo));
        switch (ipv) {
                case IPV_IPV4:
                        hints.ai_family = AF_INET;
                        break;
                case IPV_IPV6:
                        hints.ai_family = AF_INET6;
                        break;
                case IPV_UNSET:
                default:
                        hints.ai_family = AF_UNSPEC;
                        break;
        }
        hints.ai_flags = AI_PASSIVE;
        hints.ai_canonname = NULL;
        hints.ai_addr = NULL;
        hints.ai_next = NULL;

        hints.ai_socktype = SOCK_STREAM;
        proto = getprotobyname("TCP");
        hints.ai_protocol = proto->p_proto;

        if ((i = getaddrinfo(NULL, service, &hints, &results)) != 0) {
                fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(i));
                exit(EX_OSERR);
        }

        for (addrc = 0, rp = results; rp != NULL; rp = rp->ai_next, ++addrc);
        if (addrc == 0) {
                fprintf(stderr, "No se encontró ninguna manera de crear el servicio.\n");
                exit(EX_UNAVAILABLE);
        }
        if ((sockfds = static_cast<int *>(calloc(addrc, sizeof(int)))) == NULL) {
                perror("calloc");
                exit(EX_OSERR);
        }

        for (i = 0, rp = results, socks = 0; rp != NULL; ++i, rp = rp->ai_next) {
                if ((sockfds[i] = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) == -1) {
                        if (verbose) perror("socket");
                        sockfds[i] = NO_SOCK;
                        continue;
                }
                if (ipv == IPV_UNSET && rp->ai_family == PF_INET6) {
#if defined(IPV6_V6ONLY)
                        j = 1;
                        if (setsockopt(sockfds[i], IPPROTO_IPV6, IPV6_V6ONLY, &j, sizeof(j)) == -1) {
                                if (verbose) perror("setsockopt");
                                close(sockfds[i]);
                                sockfds[i] = NO_SOCK;
                                continue;
                        }
#else
                        fprintf(stderr, "Imposible usar la opción IPV6_V6ONLY para sockets IPv6; no se utilizará el socket.\n");
                        close(sockfds[i]);
                        sockfds[i] = NO_SOCK;
                        continue;
#endif
                }
                if (bind(sockfds[i], rp->ai_addr, rp->ai_addrlen) == -1) {
                        if (verbose) perror("bind");
                        close(sockfds[i]);
                        sockfds[i] = NO_SOCK;
                        continue;
                }
                if (listen(sockfds[i], backlog) == -1) {
                        if (verbose) perror("listen");
                        close(sockfds[i]);
                        sockfds[i] = NO_SOCK;
                        continue;
                }
                ++socks;
                if (verbose) {
                        fprintf(stderr, "Recibiendo conexiones en:\nai_family = %d\nai_socktype = %d\nai_protocol = %d\n\n", rp->ai_family, rp->ai_socktype, rp->ai_protocol);
                        proto = getprotobynumber(rp->ai_protocol);
                        if (proto == NULL) fprintf(stderr, "protocolo desconocido!\n");
                        else fprintf(stderr, "protocolo: %s\n", proto->p_name);
                }
        }
        freeaddrinfo(results);

        if (socks <= 0) {
                fprintf(stderr, "No se encontró ninguna manera de crear el servicio.\n");
                exit(EX_UNAVAILABLE);
        }

        for (i = 0, j = 0; i < socks; ++i) if (sockfds[i] == NO_SOCK) {
                if (j == 0) j = i+1;
                for (; j<addrc; ++j) if (sockfds[j] != NO_SOCK) break;
                sockfds[i] = sockfds[j];
                ++j;
        }
        if ((sockfds = static_cast<int *>(realloc(sockfds, socks*sizeof(int)))) == NULL) {
                perror("realloc");
                exit(EX_OSERR);
        }

        for (i = 0; i < socks; ++i) if (fcntl(sockfds[i], F_SETFL, O_NONBLOCK) == -1) {
                perror("fcntl");
                exit(EX_OSERR);
        }

        childcount = 0;
        for (;;) { // main loop
                for (;;) {
                        pid = waitpid(-1, NULL, (childcount > maxchildren) ? 0 : WNOHANG);
                        if (pid == -1) if (verbose) perror("waitpid");
                        if (pid == 0 || pid == -1) break;
                        else {
                                --childcount;
                                if (verbose) fprintf(stderr, "Proceso hijo terminó; ahora hay %d hijos.\n", childcount);
                        }
                }
                FD_ZERO(&fds);
                nfds = -1;
                for (i = 0; i < socks; ++i) {
                        nfds = MAX(nfds, sockfds[i]);
                        FD_SET(sockfds[i], &fds);
                }
                if (nfds < 0) {
                        fprintf(stderr, "Error calculando valor máximo de sockets: se obtuvo %d.\n", nfds);
                        exit(EX_SOFTWARE);
                }
                t.tv_sec = 1;
                t.tv_usec = 0;
                if ((nfds = select(nfds + 1, &fds, NULL, NULL, &t)) == -1) {
                        if (errno == EINTR) {
                                if (verbose) perror("select");
                                continue;
                        } else {
                                perror("select");
                                exit(EX_OSERR);
                        }
                }

                for (i = 0, j = 0; i < socks && j < nfds; ++i) if (FD_ISSET(sockfds[i], &fds)) {
                        if ((conn = accept(sockfds[i], NULL, NULL)) == -1) {
                                if (verbose) perror("Conexión perdida; error haciendo accept");
                        } else {
                                pid = fork();
                                if (pid == 0) {
                                        for (i = 0; i < socks; ++i) if (close(sockfds[i]) == -1) if (verbose) perror("close");
                                        free(sockfds);
                                        talking = 1;
                                        if (fcntl(conn, F_SETFL, O_NONBLOCK) == -1) {
                                                if (verbose) perror("fcntl");
                                                exitcode = EX_OSERR;
                                                talking = 0;
                                        }
                                        reqcount = 0;
                                        while (talking && (maxreqs == 0 || reqcount < maxreqs)) {
                                                t.tv_sec  = timeout;
                                                t.tv_usec = 0;
                                                FD_ZERO(&fds);
                                                FD_SET(conn, &fds);
                                                switch (select(conn+1, &fds, NULL, NULL, (timeout == 0) ? NULL : (&t))) {
                                                        case -1:
                                                                if (verbose) perror("select");
                                                                exitcode = EX_TEMPFAIL;
                                                                talking = 0;
                                                                break;
                                                        case 0:
                                                                if (verbose) fprintf(stderr, "Conexión terminada por timeout.\n");
                                                                exitcode = EX_OK;
                                                                talking = 0;
                                                                break;
                                                        case 1:
                                                                opt = recv(conn, &c, 1, 0);
                                                                if (opt == -1) {
                                                                        if (verbose) perror("Error leyendo comando de cliente: recv");
                                                                        if (errno == EAGAIN) break;
                                                                        exitcode = EX_OSERR;
                                                                        talking = 0;
                                                                }
                                                                else if (opt == 0) {
                                                                        if (verbose) fprintf(stderr, "Conexión terminada por el cliente.\n");
                                                                        exitcode = EX_OK;
                                                                        talking = 0;
                                                                }
                                                                else if (opt == 1) {
                                                                        if (c == 'r') {
// ---------------------------------------- EJEMPLO DE CÓDIGO EN RESPUESTA A COMANDO 'r' ---------------------------------
                                                                                if (gettimeofday(&t, NULL) == -1) {
                                                                                        if (verbose) perror("gettimeofday");
                                                                                        exitcode = EX_SOFTWARE;
                                                                                        talking = 0;
                                                                                        break;
                                                                                }
                                                                                if ((tstr = gmtime(&(t.tv_sec))) == NULL) {
                                                                                        if (verbose) fprintf(stderr, "Error determinando la hora.\n");
                                                                                        exitcode = EX_SOFTWARE;
                                                                                        talking = 0;
                                                                                        break;
                                                                                }
                                                                                if (asprintf(&str, "G:CE:%d:%d:%d:%d:%d:%d.%lu %d\n", 1900 + (tstr->tm_year), tstr->tm_mon, tstr->tm_mday, tstr->tm_hour, tstr->tm_min, tstr->tm_sec, static_cast<long unsigned int>(t.tv_usec), calidad) == -1) {
                                                                                        if (verbose) fprintf(stderr, "Error creando string para comunicación.\n");
                                                                                        exitcode = EX_OSERR;
                                                                                        talking = 0;
                                                                                        break;
                                                                                }
                                                                                write(conn, str, strlen(str));
                                                                                free(str);
                                                                                ++reqcount;
// --------------------------------- FIN DE EJEMPLO DE CÓDIGO EN RESPUESTA A COMANDO 'r' ---------------------------------
                                                                        } else if (c == '!') {
// ---------------------------------------- EJEMPLO DE CÓDIGO EN RESPUESTA A COMANDO '!' ---------------------------------
                                                                                if (verbose) printf("Leyendo comando del cliente.\n");
                                                                                int es = 0;
                                                                                long int fsn;
                                                                                std::stringstream username;
                                                                                std::stringstream password;
                                                                                std::stringstream lenguaje;
                                                                                std::stringstream caso    ;
                                                                                std::stringstream fs      ;
                                                                                std::stringstream archivo ;
                                                                                while (es < 9) {
                                                                                        if (verbose) printf("Leyendo dato %d del cliente.\n", es);
                                                                                        opt = recv(conn, &c, 1, 0);
                                                                                        if (opt == -1) {
                                                                                                if (verbose) perror("Error leyendo datos de cliente: recv");
                                                                                                if (errno == EAGAIN) break;
                                                                                                exitcode = EX_OSERR;
                                                                                                talking = 0;
                                                                                                break;
                                                                                        } else if (opt == 0) {
                                                                                                if (verbose) fprintf(stderr, "Conexión terminada por el cliente.\n");
                                                                                                exitcode = EX_OK;
                                                                                                talking = 0;
                                                                                                break;
                                                                                        } else if (opt == 1) {
                                                                                                if (c == '!') ++es;
                                                                                                else {
                                                                                                        if (verbose) printf("Leyendo caracter %c del cliente.\n", c);
                                                                                                        if      (es == 0) username << c;
                                                                                                        else if (es == 2) password << c;
                                                                                                        else if (es == 4) lenguaje << c;
                                                                                                        else if (es == 6) caso     << c;
                                                                                                        else if (es == 8) fs       << c;
                                                                                                }
                                                                                        }
                                                                                }
                                                                                if (!talking) break;
                                                                                if (verbose) printf("Fin de lectura de datos del cliente.\n");

                                                                                if (sscanf(fs.str().c_str(), "%ld", &fsn) != 1) {
                                                                                        fprintf(stderr, "Error leyendo tamaño del archivo a leer del cliente (%s).\n", fs.str().c_str());
                                                                                        exitcode = EX_DATAERR;
                                                                                        talking = 0;
                                                                                        break;
                                                                                }

                                                                                if (verbose) printf("Leyendo %ld caracteres del archivo del cliente.\n", fsn);
                                                                                for (int i = 0; i < fsn; ++i) {
                                                                                        opt = recv(conn, &c, 1, 0);
                                                                                        if (opt == -1) {
                                                                                                if (verbose) perror("Error leyendo programa del cliente: recv");
                                                                                                if (errno == EAGAIN) break;
                                                                                                exitcode = EX_OSERR;
                                                                                                talking = 0;
                                                                                                break;
                                                                                        } else if (opt == 0) {
                                                                                                if (verbose) fprintf(stderr, "Conexión terminada por el cliente.\n");
                                                                                                exitcode = EX_OK;
                                                                                                talking = 0;
                                                                                                break;
                                                                                        } else if (opt == 1) {
                                                                                                if (verbose) printf("Leyendo caracter '%c' del archivo del cliente.\n", c);
                                                                                                archivo << c;
                                                                                        }
                                                                                }
                                                                                if (!talking) break;
                                                                                if (verbose) printf("Fin de lectura del archivo del cliente.\n");
// --------------------------------- FIN DE EJEMPLO DE CÓDIGO EN RESPUESTA A COMANDO '!' ---------------------------------
                                                                        }
                                                                } else {
                                                                        fprintf(stderr, "Error imposible.\n");
                                                                        exitcode = EX_OSERR;
                                                                        talking = 0;
                                                                }
                                                                break;
                                                        default:
                                                                fprintf(stderr, "Error imposible.\n");
                                                                exitcode = EX_SOFTWARE;
                                                                talking = 0;
                                                                break;
                                                } // switch (select(conn))
                                        } // while (talking)
                                        if (shutdown(conn, SHUT_RDWR) == -1) if (verbose) perror("shutdown");
                                        if (close(conn) == -1) if (verbose) perror("close");
                                        exit(exitcode);
                                } // if (child)
                                else if (pid == -1) {
                                        if (verbose) perror("Conexión perdida; error haciendo fork");
                                } else {
                                        ++childcount;
                                        if (verbose) fprintf(stderr, "Conexión recibida; ahora hay %d hijos.\n", childcount);
                                }
                                if (close(conn) == -1) if (verbose) perror("close");
                        } // if accept() success
                        ++nfds;
                } /* foreach (FD_ISSET()) */
        } /* main loop */

        if (verbose) fprintf(stderr, "Error imposible.\n");
        exit(EX_SOFTWARE);
}
Beispiel #26
0
static int process(const char *controller, const char *path, Hashmap *a, Hashmap *b, unsigned iteration) {
        Group *g;
        int r;
        FILE *f;
        pid_t pid;
        unsigned n;

        assert(controller);
        assert(path);
        assert(a);

        g = hashmap_get(a, path);
        if (!g) {
                g = hashmap_get(b, path);
                if (!g) {
                        g = new0(Group, 1);
                        if (!g)
                                return -ENOMEM;

                        g->path = strdup(path);
                        if (!g->path) {
                                group_free(g);
                                return -ENOMEM;
                        }

                        r = hashmap_put(a, g->path, g);
                        if (r < 0) {
                                group_free(g);
                                return r;
                        }
                } else {
                        assert_se(hashmap_move_one(a, b, path) == 0);
                        g->cpu_valid = g->memory_valid = g->io_valid = g->n_tasks_valid = false;
                }
        }

        /* Regardless which controller, let's find the maximum number
         * of processes in any of it */

        r = cg_enumerate_tasks(controller, path, &f);
        if (r < 0)
                return r;

        n = 0;
        while (cg_read_pid(f, &pid) > 0)
                n++;
        fclose(f);

        if (n > 0) {
                if (g->n_tasks_valid)
                        g->n_tasks = MAX(g->n_tasks, n);
                else
                        g->n_tasks = n;

                g->n_tasks_valid = true;
        }

        if (streq(controller, "cpuacct")) {
                uint64_t new_usage;
                char *p, *v;
                struct timespec ts;

                r = cg_get_path(controller, path, "cpuacct.usage", &p);
                if (r < 0)
                        return r;

                r = read_one_line_file(p, &v);
                free(p);
                if (r < 0)
                        return r;

                r = safe_atou64(v, &new_usage);
                free(v);
                if (r < 0)
                        return r;

                assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);

                if (g->cpu_iteration == iteration - 1) {
                        uint64_t x, y;

                        x = ((uint64_t) ts.tv_sec * 1000000000ULL + (uint64_t) ts.tv_nsec) -
                                ((uint64_t) g->cpu_timestamp.tv_sec * 1000000000ULL + (uint64_t) g->cpu_timestamp.tv_nsec);

                        y = new_usage - g->cpu_usage;

                        if (y > 0) {
                                g->cpu_fraction = (double) y / (double) x;
                                g->cpu_valid = true;
                        }
                }

                g->cpu_usage = new_usage;
                g->cpu_timestamp = ts;
                g->cpu_iteration = iteration;

        } else if (streq(controller, "memory")) {
                char *p, *v;

                r = cg_get_path(controller, path, "memory.usage_in_bytes", &p);
                if (r < 0)
                        return r;

                r = read_one_line_file(p, &v);
                free(p);
                if (r < 0)
                        return r;

                r = safe_atou64(v, &g->memory);
                free(v);
                if (r < 0)
                        return r;

                if (g->memory > 0)
                        g->memory_valid = true;

        } else if (streq(controller, "blkio")) {
                char *p;
                uint64_t wr = 0, rd = 0;
                struct timespec ts;

                r = cg_get_path(controller, path, "blkio.io_service_bytes", &p);
                if (r < 0)
                        return r;

                f = fopen(p, "re");
                free(p);

                if (!f)
                        return -errno;

                for (;;) {
                        char line[LINE_MAX], *l;
                        uint64_t k, *q;

                        if (!fgets(line, sizeof(line), f))
                                break;

                        l = strstrip(line);
                        l += strcspn(l, WHITESPACE);
                        l += strspn(l, WHITESPACE);

                        if (first_word(l, "Read")) {
                                l += 4;
                                q = &rd;
                        } else if (first_word(l, "Write")) {
                                l += 5;
                                q = &wr;
                        } else
                                continue;

                        l += strspn(l, WHITESPACE);
                        r = safe_atou64(l, &k);
                        if (r < 0)
                                continue;

                        *q += k;
                }

                fclose(f);

                assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);

                if (g->io_iteration == iteration - 1) {
                        uint64_t x, yr, yw;

                        x = ((uint64_t) ts.tv_sec * 1000000000ULL + (uint64_t) ts.tv_nsec) -
                                ((uint64_t) g->io_timestamp.tv_sec * 1000000000ULL + (uint64_t) g->io_timestamp.tv_nsec);

                        yr = rd - g->io_input;
                        yw = wr - g->io_output;

                        if (yr > 0 || yw > 0) {
                                g->io_input_bps = (yr * 1000000000ULL) / x;
                                g->io_output_bps = (yw * 1000000000ULL) / x;
                                g->io_valid = true;

                        }
                }

                g->io_input = rd;
                g->io_output = wr;
                g->io_timestamp = ts;
                g->io_iteration = iteration;
        }

        return 0;
}
Beispiel #27
0
int main (int argc, char **argv)
{
	extern char *optarg;
	int	errflg = 0;
	int	c;
	int	help = 0;
	int	flag = 0;

	/* MBIO status variables */
	int	status = MB_SUCCESS;
	int	verbose = 0;
	int	error = MB_ERROR_NO_ERROR;
	char	*message;

	/* segy data */
	char	segyfile[MB_PATH_MAXLINE];
	void	*mbsegyioptr;
	struct mb_segyasciiheader_struct asciiheader;
	struct mb_segyfileheader_struct fileheader;
	struct mb_segytraceheader_struct traceheader;
	float	*trace = NULL;
	float	*worktrace = NULL;
	double	*spsd = NULL;
	double	*wpsd = NULL;
	double	*spsdtot = NULL;
	double	*wpsdtot = NULL;
	
	/* fft controls */
	int		nfft = 1024;
	fftw_plan 	plan;
	fftw_complex	*fftw_in = NULL;
	fftw_complex	*fftw_out = NULL;
	int		nsection;

	/* grid controls */
	char	fileroot[MB_PATH_MAXLINE];
	char	gridfile[MB_PATH_MAXLINE];
	char	psdfile[MB_PATH_MAXLINE];
	int	decimatex = 1;
	int	tracemode = MBSEGYPSD_USESHOT;
	int	tracestart = 0;
	int	traceend = 0;
	int	chanstart = 0;
	int	chanend = -1;
	double	timesweep = 0.0;
	double	timedelay = 0.0;
	double	sampleinterval = 0.0;
	int	windowmode = MBSEGYPSD_WINDOW_OFF;
	double	windowstart, windowend;
	int	ntraces;
	int	ngridx = 0;
	int	ngridy = 0;
	int	ngridxy = 0;
	float	*grid = NULL;
	double	xmin;
	double	xmax;
	double	ymin;
	double	ymax;
	double	dx;
	double	dy;
	double	gridmintot = 0.0;
	double	gridmaxtot = 0.0;
	char	projection[MB_PATH_MAXLINE];
	char	xlabel[MB_PATH_MAXLINE];
	char	ylabel[MB_PATH_MAXLINE];
	char	zlabel[MB_PATH_MAXLINE];
	char	title[MB_PATH_MAXLINE];
	char	plot_cmd[MB_PATH_MAXLINE];
	int	scale2distance = MB_NO;
	double	shotscale = 1.0;
	double	frequencyscale = 1.0;
	int	logscale = MB_NO;

	int	sinftracemode = MBSEGYPSD_USESHOT;
	int	sinftracestart = 0;
	int	sinftraceend = 0;
	int	sinfchanstart = 0;
	int	sinfchanend = -1;
	double	sinftimesweep = 0.0;
	double	sinftimedelay = 0.0;
	
	double	soundpressurelevel;
	
	double	sint, taper;
	double	norm, normraw, normtaper, normfft;

	FILE	*fp;
	int	nread;
	int	tracecount, tracenum, channum, traceok;
	double	tracemin, tracemax;
	double	xwidth, ywidth;
	int	ix, iy, iys;
	int	itstart, itend;
	double	factor, btime, stime, dtime;
	double	btimesave = 0.0;
	double	stimesave = 0.0;
	double	dtimesave = 0.0;
	int	plot_status;
	int	kstart, kend;
	int	i, j, k, n;

	/* set file to null */
	segyfile[0] = '\0';

	/* get NaN value */
	GMT_make_fnan(NaN);

	/* process argument list */
	while ((c = getopt(argc, argv, "A:a:D:d:I:i:LlN:n:O:o:PpS:s:T:t:VvW:w:Hh")) != -1)
	  switch (c) 
		{
		case 'H':
		case 'h':
			help++;
			break;
		case 'V':
		case 'v':
			verbose++;
			break;
		case 'A':
		case 'a':
			n = sscanf (optarg,"%lf/%lf", &shotscale, &frequencyscale);
			if (n == 2)
				scale2distance = MB_YES;
			flag++;
			break;
		case 'D':
		case 'd':
			n = sscanf (optarg,"%d", &decimatex);
			flag++;
			break;
		case 'I':
		case 'i':
			sscanf (optarg,"%s", segyfile);
			flag++;
			break;
		case 'L':
		case 'l':
			logscale = MB_YES;
			flag++;
			break;
		case 'N':
		case 'n':
			n = sscanf (optarg,"%d", &nfft);
			flag++;
			break;
		case 'G':
		case 'O':
		case 'o':
			sscanf (optarg,"%s", fileroot);
			flag++;
			break;
		case 'S':
		case 's':
			n = sscanf (optarg,"%d/%d/%d/%d/%d", &tracemode, &tracestart, &traceend, &chanstart, &chanend);
			if (n < 5)
				{
				chanstart = 0;
				chanend = -1;
				}
			if (n < 3)
				{
				tracestart = 0;
				traceend = 0;
				}
			if (n < 1)
				{
				tracemode = MBSEGYPSD_USESHOT;
				}
			flag++;
			break;
		case 'T':
		case 't':
			n = sscanf (optarg,"%lf/%lf", &timesweep, &timedelay);
			if (n < 2)
				timedelay = 0.0;
			flag++;
			break;
		case 'W':
		case 'w':
			n = sscanf (optarg,"%d/%lf/%lf", &windowmode, &windowstart, &windowend);
			flag++;
			break;
		case '?':
			errflg++;
		}

	/* set output stream to stdout or stderr */
	if (verbose >= 2)
	    outfp = stderr;
	else
	    outfp = stdout;

	/* if error flagged then print it and exit */
	if (errflg)
		{
		fprintf(outfp,"usage: %s\n", usage_message);
		fprintf(outfp,"\nProgram <%s> Terminated\n",
			program_name);
		error = MB_ERROR_BAD_USAGE;
		exit(error);
		}

	/* print starting message */
	if (verbose == 1 || help)
		{
		fprintf(outfp,"\nProgram %s\n",program_name);
		fprintf(outfp,"MB-system Version %s\n",MB_VERSION);
		}

	/* print starting debug statements */
	if (verbose >= 2)
		{
		fprintf(outfp,"\ndbg2  Program <%s>\n",program_name);
		fprintf(outfp,"dbg2  MB-system Version %s\n",MB_VERSION);
		fprintf(outfp,"dbg2  Control Parameters:\n");
		fprintf(outfp,"dbg2       verbose:        %d\n",verbose);
		fprintf(outfp,"dbg2       help:           %d\n",help);
		fprintf(outfp,"dbg2       segyfile:       %s\n",segyfile);
		fprintf(outfp,"dbg2       fileroot:       %s\n",fileroot);
		fprintf(outfp,"dbg2       nfft:           %d\n",nfft);
		fprintf(outfp,"dbg2       decimatex:      %d\n",decimatex);
		fprintf(outfp,"dbg2       tracemode:      %d\n",tracemode);
		fprintf(outfp,"dbg2       tracestart:     %d\n",tracestart);
		fprintf(outfp,"dbg2       traceend:       %d\n",traceend);
		fprintf(outfp,"dbg2       chanstart:      %d\n",chanstart);
		fprintf(outfp,"dbg2       chanend:        %d\n",chanend);
		fprintf(outfp,"dbg2       timesweep:      %f\n",timesweep);
		fprintf(outfp,"dbg2       timedelay:      %f\n",timedelay);
		fprintf(outfp,"dbg2       ngridx:         %d\n",ngridx);
		fprintf(outfp,"dbg2       ngridy:         %d\n",ngridy);
		fprintf(outfp,"dbg2       ngridxy:        %d\n",ngridxy);
		fprintf(outfp,"dbg2       windowmode:     %d\n",windowmode);
		fprintf(outfp,"dbg2       windowstart:    %f\n",windowstart);
		fprintf(outfp,"dbg2       windowend:      %f\n",windowend);
		fprintf(outfp,"dbg2       scale2distance: %d\n",scale2distance);
		fprintf(outfp,"dbg2       shotscale:      %f\n",shotscale);
		fprintf(outfp,"dbg2       frequencyscale: %f\n",frequencyscale);
		fprintf(outfp,"dbg2       logscale:       %d\n",logscale);
		}

	/* if help desired then print it and exit */
	if (help)
		{
		fprintf(outfp,"\n%s\n",help_message);
		fprintf(outfp,"\nusage: %s\n", usage_message);
		exit(error);
		}
		
	/* get segy limits if required */
	if (traceend < 1 || traceend < tracestart || timesweep <= 0.0)
		{
		get_segy_limits(verbose, 
				segyfile,  
				&sinftracemode,
				&sinftracestart,
				&sinftraceend,
				&sinfchanstart,
				&sinfchanend,
				&sinftimesweep,
				&sinftimedelay,
				&error);
		if (traceend < 1 || traceend < tracestart)
			{
			tracemode = sinftracemode;
			tracestart = sinftracestart;
			traceend = sinftraceend;
			}
		if (chanend < 1 || chanend < chanstart)
			{
			chanstart = sinfchanstart;
			chanend = sinfchanend;
			}
		if (timesweep <= 0.0)
			{
			timesweep = sinftimesweep;
			timedelay = sinftimedelay;
			}
		}
		
	/* check specified parameters */
	if (traceend < 1 || traceend < tracestart)
		{
		fprintf(outfp,"\nBad trace numbers: %d %d specified...\n", tracestart, traceend);
		fprintf(outfp,"\nProgram <%s> Terminated\n", program_name);
		exit(error);
		}
	if (timesweep <= 0.0)
		{
		fprintf(outfp,"\nBad time sweep: %f specified...\n", timesweep);
		fprintf(outfp,"\nProgram <%s> Terminated\n", program_name);
		exit(error);
		}

	/* initialize reading the segy file */
	if (mb_segy_read_init(verbose, segyfile, 
		&mbsegyioptr, &asciiheader, &fileheader, &error) != MB_SUCCESS)
		{
		mb_error(verbose,error,&message);
		fprintf(outfp,"\nMBIO Error returned from function <mb_segy_read_init>:\n%s\n",message);
		fprintf(outfp,"\nSEGY File <%s> not initialized for reading\n",segyfile);
		fprintf(outfp,"\nProgram <%s> Terminated\n",
			program_name);
		exit(error);
		}
		
	/* calculate implied grid parameters */
	strcpy(gridfile,fileroot);
	strcat(gridfile,".grd");
	strcpy(psdfile,fileroot);
	strcat(psdfile,"_psd.txt");
	if (chanend >= chanstart)
		ntraces = (traceend - tracestart + 1) * (chanend - chanstart + 1);
	else
		ntraces = traceend - tracestart + 1;
	ngridx = ntraces / decimatex;
	sampleinterval = 0.000001 * (double) (fileheader.sample_interval);
	ngridy = nfft / 2 + 1;
	ngridxy = ngridx * ngridy;
	dx = decimatex;
	xmin = (double) tracestart - 0.5;
	xmax = (double) traceend + 0.5;
	dy = 1.0 / (2.0 * sampleinterval * ngridy);
	ymin = -0.5 * dy;
	ymax = (ngridy - 0.5) * dy;
	
	/* get start and end samples */
	if (windowmode == MBSEGYPSD_WINDOW_OFF)
		{
		itstart = 0;
		itend = ngridy - 1;
		}
	else if (windowmode == MBSEGYPSD_WINDOW_ON)
		{
		itstart = MAX((windowstart) / sampleinterval, 0);
		itend = MIN((windowend) / sampleinterval, ngridy - 1);
		}		
	
	/* allocate memory for grid array */
	status = mb_mallocd(verbose,__FILE__,__LINE__, 2 * ngridxy * sizeof(float), (void **)&grid, &error);
	status = mb_mallocd(verbose,__FILE__,__LINE__, ngridy * sizeof(double), (void **)&spsd, &error);
	status = mb_mallocd(verbose,__FILE__,__LINE__, ngridy * sizeof(double), (void **)&wpsd, &error);
	status = mb_mallocd(verbose,__FILE__,__LINE__, ngridy * sizeof(double), (void **)&spsdtot, &error);
	status = mb_mallocd(verbose,__FILE__,__LINE__, ngridy * sizeof(double), (void **)&wpsdtot, &error);

	/* zero working psd array */
	for (iy=0;iy<ngridy;iy++)
		{
		spsdtot[iy] = 0.0;
		wpsdtot[iy] = 0.0;
		}

	/* output info */
	if (verbose >= 0)
		{
		fprintf(outfp,"\nMBsegypsd Parameters:\n");
		fprintf(outfp,"Input segy file:         %s\n",segyfile);
		fprintf(outfp,"Output fileroot:         %s\n",fileroot);
		fprintf(outfp,"Input Parameters:\n");
		fprintf(outfp,"     trace mode:         %d\n",tracemode);
		fprintf(outfp,"     trace start:        %d\n",tracestart);
		fprintf(outfp,"     trace end:          %d\n",traceend);
		fprintf(outfp,"     channel start:      %d\n",chanstart);
		fprintf(outfp,"     channel end:        %d\n",chanend);
		fprintf(outfp,"     trace decimation:   %d\n",decimatex);
		fprintf(outfp,"     time sweep:         %f seconds\n",timesweep);
		fprintf(outfp,"     time delay:         %f seconds\n",timedelay);
		fprintf(outfp,"     sample interval:    %f seconds\n",sampleinterval);
		fprintf(outfp,"     window mode:        %d\n",windowmode);
		fprintf(outfp,"     window start:       %f seconds\n",windowstart);
		fprintf(outfp,"     window end:         %f seconds\n",windowend);
		fprintf(outfp,"Output Parameters:\n");
		fprintf(outfp,"     grid filename:      %s\n",gridfile);
		fprintf(outfp,"     psd filename:       %s\n",psdfile);
		fprintf(outfp,"     x grid dimension:   %d\n",ngridx);
		fprintf(outfp,"     y grid dimension:   %d\n",ngridy);
		fprintf(outfp,"     grid xmin:          %f\n",xmin);
		fprintf(outfp,"     grid xmax:          %f\n",xmax);
		fprintf(outfp,"     grid ymin:          %f\n",ymin);
		fprintf(outfp,"     grid ymax:          %f\n",ymax);
		fprintf(outfp,"     NaN values used to flag regions with no data\n");
		fprintf(outfp,"     shotscale:          %f\n",shotscale);
		fprintf(outfp,"     frequencyscale:     %f\n",frequencyscale);
		if (scale2distance == MB_YES)
			{
			fprintf(outfp,"     trace numbers scaled to distance in meters\n");
			fprintf(outfp,"     scaled grid xmin    %f\n",0.0);
			fprintf(outfp,"     scaled grid xmax:   %f\n",shotscale * (xmax - xmin));
			}
		}
	if (verbose > 0)
		fprintf(outfp,"\n");
	
	/* proceed if all ok */
	if (status == MB_SUCCESS)
		{
	
		/* fill grid with NaNs */
		for (i=0;i<ngridxy;i++)
			grid[i] = NaN;
			
		/* generate the fftw plan */
		fftw_in = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * nfft);
		fftw_out = (fftw_complex *) fftw_malloc(sizeof(fftw_complex) * nfft);
		plan = fftw_plan_dft_1d(nfft, fftw_in, fftw_out, FFTW_FORWARD, FFTW_MEASURE);

		/* read and print data */
		nread = 0;
		while (error <= MB_ERROR_NO_ERROR)
			{
			/* reset error */
			error = MB_ERROR_NO_ERROR;

			/* read a trace */
			status = mb_segy_read_trace(verbose, mbsegyioptr, 
					&traceheader, &trace, &error);

			/* now process the trace */
			if (status == MB_SUCCESS)
				{
				/* figure out where this trace is in the grid */
				if (tracemode == MBSEGYPSD_USESHOT)
					{
					tracenum = traceheader.shot_num;
					channum = traceheader.shot_tr;
					}
				else
					{
					tracenum = traceheader.rp_num;
					channum = traceheader.rp_tr;
					}
				if (chanend >= chanstart)
					{
					tracecount = (tracenum - tracestart) * (chanend - chanstart + 1)
							+ (channum - chanstart);
					}
				else
					{
					tracecount = tracenum - tracestart;
					}
				ix = tracecount / decimatex;
				if (traceheader.elev_scalar < 0)
					factor = 1.0 / ((float) (-traceheader.elev_scalar));
				else
					factor = (float) traceheader.elev_scalar;
				if (traceheader.src_depth > 0)
					{
					btime = factor * traceheader.src_depth / 750.0 + 0.001 * traceheader.delay_mils;
					dtime = factor * traceheader.src_depth / 750.0;
					btimesave = btime;
					dtimesave = dtime;
					}
				else if (traceheader.src_elev > 0)
					{
					btime = -factor * traceheader.src_elev / 750.0 + 0.001 * traceheader.delay_mils;
					dtime = -factor * traceheader.src_elev / 750.0;
					btimesave = btime;
					dtimesave = dtime;
					}
				else
					{
					btime = btimesave;
					dtime = dtimesave;
					}
				if (traceheader.src_wbd > 0)
					{
					stime = factor * traceheader.src_wbd / 750.0;
					stimesave = stime;
					}
				else
					{
					stime = stimesave;
					}
				iys = (btime - timedelay) / sampleinterval;
				
				/* now check if this is a trace of interest */
				traceok = MB_YES;
				if (tracenum < tracestart 
					|| tracenum > traceend)
					traceok = MB_NO;
				else if (chanend >= chanstart
						&& (channum < chanstart
							|| channum > chanend))
					traceok = MB_NO;
				else if (tracecount % decimatex != 0)
					traceok = MB_NO;

				/* get trace min and max */
				tracemin = trace[0];
				tracemax = trace[0];
				for (i=0;i<traceheader.nsamps;i++)
					{
					tracemin = MIN(tracemin, trace[i]);
					tracemax = MAX(tracemin, trace[i]);
					}	

				if ((verbose == 0 && nread % 250 == 0) || (nread % 25 == 0))
					{
					if (traceok == MB_YES) 
						fprintf(outfp,"PROCESS ");
					else 
						fprintf(outfp,"IGNORE  ");
					if (tracemode == MBSEGYPSD_USESHOT) 
						fprintf(outfp,"read:%d position:%d shot:%d channel:%d ",
							nread,tracecount,tracenum,channum);
					else 
						fprintf(outfp,"read:%d position:%d rp:%d channel:%d ",
							nread,tracecount,tracenum,channum);
					fprintf(outfp,"%4.4d/%3.3d %2.2d:%2.2d:%2.2d.%3.3d samples:%d interval:%d usec minmax: %f %f\n",
					traceheader.year,traceheader.day_of_yr,
					traceheader.hour,traceheader.min,traceheader.sec,traceheader.mils,
					traceheader.nsamps,traceheader.si_micros,
					tracemin, tracemax);
					}

				/* now actually process traces of interest */
				if (traceok == MB_YES)
					{
					/* zero working psd array */
					for (iy=0;iy<ngridy;iy++)
						{
						spsd[iy] = 0.0;
						wpsd[iy] = 0.0;
						}

					/* get bounds of trace in depth window mode */
					if (windowmode == MBSEGYPSD_WINDOW_DEPTH)
						{
						itstart = (int)((dtime + windowstart - timedelay) / sampleinterval);
						itstart = MAX(itstart, 0);
						itend = (int)((dtime + windowend - timedelay) / sampleinterval);
						itend = MIN(itend, ngridy - 1);
						}
					else if (windowmode == MBSEGYPSD_WINDOW_SEAFLOOR)
						{
						itstart = MAX((stime + windowstart - timedelay) / sampleinterval, 0);
						itend = MIN((stime + windowend - timedelay) / sampleinterval, ngridy - 1);
						}
						
					/* loop over the data calculating fft in nfft long sections */
					nsection = (itend - itstart + 1) / nfft;
					if (((itend - itstart + 1) % nfft) > 0)
						nsection++;
					for (j=0;j<nsection;j++)
						{
						/* initialize normalization factors */
						normraw = 0.0;
						normtaper = 0.0;
						normfft = 0.0;
						
						/* extract data section to be fft'd with taper */
						kstart = itstart + j * nfft;
						kend = MIN(kstart + nfft, itend);
						for (i=0;i<nfft;i++)
							{
							k = itstart + j * nfft + i;
							if (k <= kend)
								{
								sint = sin(M_PI * ((double)(k - kstart)) / ((double)(kend - kstart)));
								taper = sint * sint;
								fftw_in[i][0] = taper * trace[k]; 
								normraw += trace[k] * trace[k];
								normtaper += fftw_in[i][0] * fftw_in[i][0];
								}
							else
								fftw_in[i][0] = 0.0;
/*if (ix < 500)
fftw_in[i][0] = sin(2.0 * M_PI * 1000.0 * i * sampleinterval) 
			+ sin(2.0 * M_PI * 3000.0 * i * sampleinterval) 
			+ sin(2.0 * M_PI * 6000.0 * i * sampleinterval);*/
							fftw_in[i][1] = 0.0;
							}
						soundpressurelevel = 20.0 * log10(normraw / nfft);
/*fprintf(stderr,"Sound Pressure Level: %f dB re 1 uPa\n",soundpressurelevel);*/
							
						/* execute the fft */
						fftw_execute(plan);
						
						/* get normalization factor - require variance of transform to equal variance of input */
						for (i=1;i<nfft;i++)
							{
							normfft += fftw_out[i][0] * fftw_out[i][0] + fftw_out[i][1] * fftw_out[i][1];
							}
						norm = normraw / normfft;
						
						/* apply normalization factor */
						for (i=1;i<nfft;i++)
							{
							fftw_out[i][0] = norm * fftw_out[i][0];
							fftw_out[i][1] = norm * fftw_out[i][1];
							}
							
						/* calculate psd from result of transform */
						spsd[0] += fftw_out[0][0] * fftw_out[0][0] + fftw_out[0][1] * fftw_out[0][1];
						wpsd[0] += 1.0;
/* fprintf(stderr,"FFT result: i:%d  %f %f  %f\n",
0,fftw_out[0][0],fftw_out[0][1],fftw_out[0][0] * fftw_out[0][0] + fftw_out[0][1] * fftw_out[0][1]);*/
						for (i=1;i<nfft/2;i++)
							{
							spsd[i] += 2.0 * (fftw_out[i][0] * fftw_out[i][0] + fftw_out[i][1] * fftw_out[i][1]);
							wpsd[i] += 1.0;
/* fprintf(stderr,"FFT result: i:%d  %f %f  %f\n",
i,fftw_out[i][0],fftw_out[i][1],2.0 * fftw_out[i][0] * fftw_out[i][0] + fftw_out[i][1] * fftw_out[i][1]);*/
							}
						if (nfft % 2 == 0)
							{
							spsd[i] += fftw_out[nfft/2][0] * fftw_out[nfft/2][0] + fftw_out[nfft/2][1] * fftw_out[nfft/2][1];
							wpsd[i] += 1.0;
/* fprintf(stderr,"FFT result: i:%d  %f %f  %f\n",
nfft/2,fftw_out[nfft/2][0],fftw_out[nfft/2][1],fftw_out[nfft/2][0] * fftw_out[nfft/2][0] + fftw_out[nfft/2][1] * fftw_out[nfft/2][1]); */
							}
						}
						
					/* output psd for this trace to the grid */
/*fprintf(stderr,"N:%d Normalization: %f %f %f    ratios: %f %f     %f %f\n",
nfft,normraw,normtaper,normfft,normraw/normfft,normfft/normraw,normtaper/normfft,normfft/normtaper);*/
					for (iy=0;iy<ngridy;iy++)
						{
						k = (ngridy - 1 - iy) * ngridx + ix;
						if (wpsd[iy] > 0.0)
							{
							if (logscale == MB_NO)
								grid[k] = spsd[iy] / wpsd[iy];
							else
								grid[k] = 20.0 * log10(spsd[iy] / wpsd[iy]);
							spsdtot[iy] += grid[k];
							wpsdtot[iy] += 1.0;
/*fprintf(stderr,"ix:%d iy:%d k:%d spsd:%f wpsd:%f     f:%f p:%f\n",
ix,iy,k,spsd[iy],wpsd[iy],ymax * iy / ngridy,grid[k]);*/
							gridmintot = MIN(grid[k], gridmintot);
							gridmaxtot = MAX(grid[k], gridmaxtot);
							}
						}
					}
				}

			/* now process the trace */
			if (status == MB_SUCCESS)
				nread++;
			}
			
		/* deallocate fftw arrays and plan */
		fftw_destroy_plan(plan);
		fftw_free(fftw_in);
		fftw_free(fftw_out);
		}

	/* write out the grid */
	error = MB_ERROR_NO_ERROR;
	status = MB_SUCCESS;
	strcpy(projection, "GenericLinear");
	if (scale2distance == MB_YES)
		{
		strcpy(xlabel, "Distance (m)");
		strcpy(ylabel, "Frequency (Hz)");
		xmax *= shotscale;
		xmin *= shotscale;
		dx *= shotscale;
		}
	else
		{
		strcpy(xlabel, "Trace Number");
		strcpy(ylabel, "Frequency (Hz)");
		dx = (double) decimatex;
		}
	if (logscale == MB_YES)
		strcpy(zlabel, "dB/Hz");
	else
		strcpy(zlabel, "Intensity/Hz");
	sprintf(title, "Power Spectral Density Grid from %s", segyfile);
	status = write_cdfgrd(verbose, gridfile, grid,
		ngridx, ngridy, 
		xmin, xmax, ymin, ymax,
		gridmintot, gridmaxtot, dx, dy, 
		xlabel, ylabel, zlabel, title, 
		projection, argc, argv, &error);

	/* output average power spectra */
	if ((fp = fopen(psdfile, "w")) != NULL)
		{
		for (iy=0;iy<ngridy;iy++)
			{
			if (wpsdtot[iy] > 0.0)
				{
				spsdtot[iy] = spsdtot[iy] / wpsdtot[iy];
				}
			fprintf(fp, "%f %f\n", dy * iy, spsdtot[iy]);
			}
		fclose(fp);
		}

	/* close the segy file */
	status = mb_segy_close(verbose,&mbsegyioptr,&error);

	/* deallocate memory for grid array */
	if (worktrace != NULL)
		status = mb_freed(verbose,__FILE__,__LINE__,(void **)&worktrace, &error);	
	status = mb_freed(verbose,__FILE__,__LINE__,(void **)&grid, &error);
	status = mb_freed(verbose,__FILE__,__LINE__,(void **)&spsd, &error);
	status = mb_freed(verbose,__FILE__,__LINE__,(void **)&wpsd, &error);
	status = mb_freed(verbose,__FILE__,__LINE__,(void **)&spsdtot, &error);
	status = mb_freed(verbose,__FILE__,__LINE__,(void **)&wpsdtot, &error);
	
	/* run mbm_grdplot */
	xwidth = MIN(0.01 * (double) ngridx, 55.0);
	ywidth = MIN(0.01 * (double) ngridy, 28.0);
	sprintf(plot_cmd, "mbm_grdplot -I%s -JX%f/%f -G1 -S -V -L\"File %s - %s:%s\"", 
			gridfile, xwidth, ywidth, gridfile, title, zlabel);
	if (verbose)
		{
		fprintf(outfp, "\nexecuting mbm_grdplot...\n%s\n", 
			plot_cmd);
		}
	plot_status = system(plot_cmd);
	if (plot_status == -1)
		{
		fprintf(outfp, "\nError executing mbm_grdplot on grid file %s\n", gridfile);
		}
	
	/* run mbm_xyplot */
	xwidth = 9.0;
	ywidth = 7.0;
	sprintf(plot_cmd, "mbm_xyplot -I%s -JX%f/%f -V -L\"File %s - %s:%s\"", 
			psdfile, xwidth, ywidth, psdfile, title, zlabel);
	if (verbose)
		{
		fprintf(outfp, "\nexecuting mbm_xyplot...\n%s\n", 
			plot_cmd);
		}
	plot_status = system(plot_cmd);
	if (plot_status == -1)
		{
		fprintf(outfp, "\nError executing mbm_xyplot on psd file %s\n", psdfile);
		}

	/* check memory */
	if (verbose >= 4)
		status = mb_memory_list(verbose,&error);

	/* print output debug statements */
	if (verbose >= 2)
		{
		fprintf(outfp,"\ndbg2  Program <%s> completed\n",
			program_name);
		fprintf(outfp,"dbg2  Ending status:\n");
		fprintf(outfp,"dbg2       status:  %d\n",status);
		}

	/* end it all */
	exit(error);
}
Beispiel #28
0
CEventAction::CEventAction( const CEventAction &p_EventAction )
{
	m_pNext = NULL;
	m_iIDStamp = ++s_iNextIDStamp;

	m_flDelay = p_EventAction.m_flDelay;
	m_iTarget = p_EventAction.m_iTarget;
	m_iParameter = p_EventAction.m_iParameter;
	m_iTargetInput = p_EventAction.m_iTargetInput;
	m_nTimesToFire = p_EventAction.m_nTimesToFire;
}


// this memory pool stores blocks around the size of CEventAction/inputitem_t structs
// can be used for other blocks; will error if to big a block is tried to be allocated
CUtlMemoryPool g_EntityListPool( MAX(sizeof(CEventAction),sizeof(CMultiInputVar::inputitem_t)), 512, CUtlMemoryPool::GROW_FAST, "g_EntityListPool" );

#include "tier0/memdbgoff.h"

void *CEventAction::operator new( size_t stAllocateBlock )
{
	return g_EntityListPool.Alloc( stAllocateBlock );
}

void *CEventAction::operator new( size_t stAllocateBlock, int nBlockUse, const char *pFileName, int nLine )
{
	return g_EntityListPool.Alloc( stAllocateBlock );
}

void CEventAction::operator delete( void *pMem )
{
Beispiel #29
0
int Flu_Wrap_Group :: layout( bool sbVisible, bool doScrollTo, int *measure )
{
  int xx = x()+Fl::box_dx(box()), yy = y()+Fl::box_dy(box()),
    ww = w()-Fl::box_dw(box()), hh = h()-Fl::box_dh(box());

  if( type() == FL_VERTICAL )
    {
      int i, X, Y, maxH, H, col, row, maxW, scrollY;
      Fl_Widget *c;

      scrollbar.type( FL_VERTICAL );

    BEGIN_H:

      X = xx+_offset[0];
      Y = yy+_offset[1] - (sbVisible ? scrollbar.value() : 0);
      maxH = _offset[1];
      H = 0;
      col = 0;
      row = 0;
      scrollY = 0;
      maxW = xx + ww - (sbVisible ? scrollbar.w() : 0);

      for( i = 0; i < group.children(); i++ )
	{
	  c = group.child(i);
	  if( !c->visible() )
	    continue;
	  H = MAX( H, c->h() );
	  if( col == 0 )
	    maxH += H + _spacing[1];
	  if( ( X + c->w() ) > maxW )
	    {
	      Y += H + _spacing[1];
	      scrollY += H + _spacing[1];
	      if( i == group.children()-1 )
		maxH += H + _spacing[1];

	      if( measure )
		{
		  if( xx+_offset[0] <= measure[0] && measure[0] <= xx+c->w()+_offset[0]+_spacing[0] &&
		      Y <= measure[1] && measure[1] <= Y+c->h()+_spacing[1] )
		    return i;
		}
	      else
		c->position( xx+_offset[0], Y );

	      col = 0;
	      row++;
	      H = 0;
	      X = xx+c->w() + _offset[0] + _spacing[0];
	    }
	  else
	    {
	      if( measure )
		{
		  if( X <= measure[0] && measure[0] <= X+c->w()+_spacing[0] &&
		      Y <= measure[1] && measure[1] <= Y+c->h()+_spacing[1] )
		    return i;
		}
	      else
		c->position( X, Y );
	      X += c->w() + _spacing[0];
	      col++;
	    }

	  if( doScrollTo && (c == scrollTo) )
	    {
	      if( scrollY > scrollbar.maximum() )
		scrollY = (int)scrollbar.maximum();
	      ((Fl_Valuator*)&scrollbar)->value( scrollY );
	      scrollTo = NULL;
	      goto BEGIN_H;
	    }

	  // if we exceed the height and the scrollbar is not visible,
	  // then it will soon become visible so we don't need to process anymore
	  if( !measure && !sbVisible && maxH > hh )
	    return 1;
	}

      if( measure )
	return -1;
      else if( maxH > hh )
	{
	  scrollbar.range( 0, maxH-hh );
	  scrollbar.slider_size( MAX( float(scrollbar.h()-(maxH-hh))/float(scrollbar.h()), 0.08f ) );
	  return 1;
	}
      else
	return 0;
    }
  else
    {
      int i, X, Y, W, maxW, maxH, col, row, scrollX;
      Fl_Widget *c;

      scrollbar.type( FL_HORIZONTAL );

    BEGIN_W:

      X = xx+_offset[0] - (sbVisible ? scrollbar.value() : 0);
      Y = yy+_offset[1];
      maxW = _offset[0];
      W = 0;
      col = 0;
      row = 0;
      scrollX = 0;
      maxH = yy + hh - (sbVisible ? scrollbar.h() : 0);

      for( i = 0; i < group.children(); i++ )
	{
	  c = group.child(i);
	  if( !c->visible() )
	    continue;

	  W = MAX( W, c->w() );

	  if( row == 0 )
	    maxW += W + _spacing[0];

	  if( ( Y + c->h() ) > maxH )
	    {
	      X += W + _spacing[0];
	      scrollX += W + _spacing[0];
	      if( i == group.children()-1 )
		maxW += W + _spacing[0];

	      if( measure )
		{
		  if( X <= measure[0] && measure[0] <= X+c->w()+_spacing[0] &&
		      yy+_offset[1] <= measure[1] && measure[1] <= yy+c->h()+_offset[1]+_spacing[1] )
		    return i;
		}
	      else
		c->position( X, yy+_offset[1] );

	      row = 0;
	      col++;
	      W = 0;
	      Y = yy+c->h() + _offset[1] + _spacing[1];
	    }
	  else
	    {
	      if( measure )
		{
		  if( X <= measure[0] && measure[0] <= X+c->w()+_spacing[0] &&
		      Y <= measure[1] && measure[1] <= Y+c->h()+_spacing[1] )
		    return i;
		}
	      else
		c->position( X, Y );
	      Y += c->h() + _spacing[1];
	      row++;
	    }

	  if( doScrollTo && (c == scrollTo) )
	    {
	      if( scrollX > scrollbar.maximum() )
		scrollX = (int)scrollbar.maximum();
	      ((Fl_Valuator*)&scrollbar)->value( scrollX );
	      scrollTo = NULL;
	      goto BEGIN_W;
	    }

	  // if we exceed the width and the scrollbar is not visible,
	  // then it will soon become visible so we don't need to process anymore
	  if( !measure && !sbVisible && maxW > ww )
	    return 1;
	}

      if( measure )
	return -1;
      else if( maxW > ww )
	{
	  scrollbar.range( 0, maxW-ww );
	  scrollbar.slider_size( MAX( float(scrollbar.w()-(maxW-ww))/float(scrollbar.w()), 0.08f ) );
	  return 1;
	}
      else
	return 0;
    }
}
Beispiel #30
0
lapack_int LAPACKE_dpprfs_work( int matrix_layout, char uplo, lapack_int n,
                                lapack_int nrhs, const double* ap,
                                const double* afp, const double* b,
                                lapack_int ldb, double* x, lapack_int ldx,
                                double* ferr, double* berr, double* work,
                                lapack_int* iwork )
{
    lapack_int info = 0;
    if( matrix_layout == LAPACK_COL_MAJOR ) {
        /* Call LAPACK function and adjust info */
        LAPACK_dpprfs( &uplo, &n, &nrhs, ap, afp, b, &ldb, x, &ldx, ferr, berr,
                       work, iwork, &info );
        if( info < 0 ) {
            info = info - 1;
        }
    } else if( matrix_layout == LAPACK_ROW_MAJOR ) {
        lapack_int ldb_t = MAX(1,n);
        lapack_int ldx_t = MAX(1,n);
        double* b_t = NULL;
        double* x_t = NULL;
        double* ap_t = NULL;
        double* afp_t = NULL;
        /* Check leading dimension(s) */
        if( ldb < nrhs ) {
            info = -8;
            LAPACKE_xerbla( "LAPACKE_dpprfs_work", info );
            return info;
        }
        if( ldx < nrhs ) {
            info = -10;
            LAPACKE_xerbla( "LAPACKE_dpprfs_work", info );
            return info;
        }
        /* Allocate memory for temporary array(s) */
        b_t = (double*)LAPACKE_malloc( sizeof(double) * ldb_t * MAX(1,nrhs) );
        if( b_t == NULL ) {
            info = LAPACK_TRANSPOSE_MEMORY_ERROR;
            goto exit_level_0;
        }
        x_t = (double*)LAPACKE_malloc( sizeof(double) * ldx_t * MAX(1,nrhs) );
        if( x_t == NULL ) {
            info = LAPACK_TRANSPOSE_MEMORY_ERROR;
            goto exit_level_1;
        }
        ap_t = (double*)
               LAPACKE_malloc( sizeof(double) * ( MAX(1,n) * MAX(2,n+1) ) / 2 );
        if( ap_t == NULL ) {
            info = LAPACK_TRANSPOSE_MEMORY_ERROR;
            goto exit_level_2;
        }
        afp_t = (double*)
                LAPACKE_malloc( sizeof(double) * ( MAX(1,n) * MAX(2,n+1) ) / 2 );
        if( afp_t == NULL ) {
            info = LAPACK_TRANSPOSE_MEMORY_ERROR;
            goto exit_level_3;
        }
        /* Transpose input matrices */
        LAPACKE_dge_trans( matrix_layout, n, nrhs, b, ldb, b_t, ldb_t );
        LAPACKE_dge_trans( matrix_layout, n, nrhs, x, ldx, x_t, ldx_t );
        LAPACKE_dpp_trans( matrix_layout, uplo, n, ap, ap_t );
        LAPACKE_dpp_trans( matrix_layout, uplo, n, afp, afp_t );
        /* Call LAPACK function and adjust info */
        LAPACK_dpprfs( &uplo, &n, &nrhs, ap_t, afp_t, b_t, &ldb_t, x_t, &ldx_t,
                       ferr, berr, work, iwork, &info );
        if( info < 0 ) {
            info = info - 1;
        }
        /* Transpose output matrices */
        LAPACKE_dge_trans( LAPACK_COL_MAJOR, n, nrhs, x_t, ldx_t, x, ldx );
        /* Release memory and exit */
        LAPACKE_free( afp_t );
exit_level_3:
        LAPACKE_free( ap_t );
exit_level_2:
        LAPACKE_free( x_t );
exit_level_1:
        LAPACKE_free( b_t );
exit_level_0:
        if( info == LAPACK_TRANSPOSE_MEMORY_ERROR ) {
            LAPACKE_xerbla( "LAPACKE_dpprfs_work", info );
        }
    } else {
        info = -1;
        LAPACKE_xerbla( "LAPACKE_dpprfs_work", info );
    }
    return info;
}