⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nc.c

📁 一个用来实现偏微分方程中网格的计算库
💻 C
📖 第 1 页 / 共 3 页
字号:
static intfill_added(NC *gnu, NC *old){	NC_var ** const gnu_varpp = (NC_var **)gnu->vars.value;	int varid = (int)old->vars.nelems;	for(; varid < (int)gnu->vars.nelems; varid++)	{		const NC_var *const gnu_varp = *(gnu_varpp + varid);		if(IS_RECVAR(gnu_varp))		{			/* skip record variables */			continue;		}		/* else */		{		const int status = fill_NC_var(gnu, gnu_varp, gnu_varp->len, 0);		if(status != NC_NOERR)			return status;		}	}	return NC_NOERR;}/* * Move the records "out".  * Fill as needed. */static intmove_recs_r(NC *gnu, NC *old){	int status;	int recno;	int varid;	NC_var **gnu_varpp = (NC_var **)gnu->vars.value;	NC_var **old_varpp = (NC_var **)old->vars.value;	NC_var *gnu_varp;	NC_var *old_varp;	off_t gnu_off;	off_t old_off;	const size_t old_nrecs = NC_get_numrecs(old);		/* Don't parallelize this loop */	for(recno = (int)old_nrecs -1; recno >= 0; recno--)	{	/* Don't parallelize this loop */	for(varid = (int)old->vars.nelems -1; varid >= 0; varid--)	{		gnu_varp = *(gnu_varpp + varid);		if(!IS_RECVAR(gnu_varp))		{			/* skip non-record variables on this pass */			continue;		}		/* else */		/* else, a pre-existing variable */		old_varp = *(old_varpp + varid);		gnu_off = gnu_varp->begin + (off_t)(gnu->recsize * recno);		old_off = old_varp->begin + (off_t)(old->recsize * recno);		if(gnu_off == old_off)			continue; 	/* nothing to do */		assert(gnu_off > old_off);			status = gnu->nciop->move(gnu->nciop, gnu_off, old_off,			 old_varp->len, 0);		if(status != NC_NOERR)			return status;			}	}	NC_set_numrecs(gnu, old_nrecs);	return NC_NOERR;}/* * Move the "non record" variables "out".  * Fill as needed. */static intmove_vars_r(NC *gnu, NC *old){	int status;	int varid;	NC_var **gnu_varpp = (NC_var **)gnu->vars.value;	NC_var **old_varpp = (NC_var **)old->vars.value;	NC_var *gnu_varp;	NC_var *old_varp;	off_t gnu_off;	off_t old_off;		/* Don't parallelize this loop */	for(varid = (int)old->vars.nelems -1;		 varid >= 0; varid--)	{		gnu_varp = *(gnu_varpp + varid);		if(IS_RECVAR(gnu_varp))		{			/* skip record variables on this pass */			continue;		}		/* else */		old_varp = *(old_varpp + varid);		gnu_off = gnu_varp->begin;		old_off = old_varp->begin;			if(gnu_off == old_off)			continue; 	/* nothing to do */		assert(gnu_off > old_off);		status = gnu->nciop->move(gnu->nciop, gnu_off, old_off,			 old_varp->len, 0);		if(status != NC_NOERR)			return status;			}	return NC_NOERR;}/* * Given a valid ncp, return NC_EVARSIZE if any variable has a bad len  * (product of non-rec dim sizes too large), else return NC_NOERR. */static intNC_check_vlens(NC *ncp){    NC_var **vpp;    /* maximum permitted variable size (or size of one record's worth       of a record variable) in bytes.  This is different for format 1       and format 2. */    size_t vlen_max;    size_t ii;    size_t large_vars_count;    size_t rec_vars_count;    int last = 0;    if(ncp->vars.nelems == 0) 	return NC_NOERR;    if ((ncp->flags & NC_64BIT_OFFSET) && sizeof(off_t) > 4) {	/* CDF2 format and LFS */	vlen_max = X_UINT_MAX - 3; /* "- 3" handles rounded-up size */    } else {	/* CDF1 format */	vlen_max = X_INT_MAX - 3;    }    /* Loop through vars, first pass is for non-record variables.   */    large_vars_count = 0;    rec_vars_count = 0;    vpp = ncp->vars.value;    for (ii = 0; ii < ncp->vars.nelems; ii++, vpp++) {	if( !IS_RECVAR(*vpp) ) {	    last = 0;	    if( NC_check_vlen(*vpp, vlen_max) == 0 ) {		large_vars_count++;		last = 1;	    }	} else {	  rec_vars_count++;	}    }    /* OK if last non-record variable size too large, since not used to        compute an offset */    if( large_vars_count > 1) { /* only one "too-large" variable allowed */      return NC_EVARSIZE;    }    /* and it has to be the last one */     if( large_vars_count == 1 && last == 0) {       return NC_EVARSIZE;    }    if( rec_vars_count > 0 ) {	/* and if it's the last one, there can't be any record variables */	if( large_vars_count == 1 && last == 1) {	    return NC_EVARSIZE;	}	/* Loop through vars, second pass is for record variables.   */	large_vars_count = 0;	vpp = ncp->vars.value;	for (ii = 0; ii < ncp->vars.nelems; ii++, vpp++) {	    if( IS_RECVAR(*vpp) ) {		last = 0;		if( NC_check_vlen(*vpp, vlen_max) == 0 ) {		    large_vars_count++;		    last = 1;		}	    }	}	/* OK if last record variable size too large, since not used to 	   compute an offset */	if( large_vars_count > 1) { /* only one "too-large" variable allowed */	    return NC_EVARSIZE;	}	/* and it has to be the last one */ 	if( large_vars_count == 1 && last == 0) { 	    return NC_EVARSIZE;	}    }    return NC_NOERR;}/* *  End define mode. *  Common code for ncendef, ncclose(endef) *  Flushes I/O buffers. */static intNC_endef(NC *ncp,	size_t h_minfree, size_t v_align,	size_t v_minfree, size_t r_align){	int status = NC_NOERR;	assert(!NC_readonly(ncp));	assert(NC_indef(ncp));	status = NC_check_vlens(ncp);	if(status != NC_NOERR)	    return status;	status = NC_begins(ncp, h_minfree, v_align, v_minfree, r_align);	if(status != NC_NOERR)	    return status;	if(ncp->old != NULL)	{		/* a plain redef, not a create */		assert(!NC_IsNew(ncp));		assert(fIsSet(ncp->flags, NC_INDEF));		assert(ncp->begin_rec >= ncp->old->begin_rec);		assert(ncp->begin_var >= ncp->old->begin_var);		if(ncp->vars.nelems != 0)		{		if(ncp->begin_rec > ncp->old->begin_rec)		{			status = move_recs_r(ncp, ncp->old);			if(status != NC_NOERR)				return status;			if(ncp->begin_var > ncp->old->begin_var)			{				status = move_vars_r(ncp, ncp->old);				if(status != NC_NOERR)					return status;			} 			/* else if (ncp->begin_var == ncp->old->begin_var) { NOOP } */		}		else		{	/* Even if (ncp->begin_rec == ncp->old->begin_rec)			   and     (ncp->begin_var == ncp->old->begin_var)			   might still have added a new record variable */		        if(ncp->recsize > ncp->old->recsize)			{			        status = move_recs_r(ncp, ncp->old);				if(status != NC_NOERR)				      return status;			}		}		}	}	status = write_NC(ncp);	if(status != NC_NOERR)		return status;	if(NC_dofill(ncp))	{		if(NC_IsNew(ncp))		{			status = fillerup(ncp);			if(status != NC_NOERR)				return status;					}		else if(ncp->vars.nelems > ncp->old->vars.nelems)		{			status = fill_added(ncp, ncp->old);			if(status != NC_NOERR)				return status;			status = fill_added_recs(ncp, ncp->old);			if(status != NC_NOERR)				return status;		}	}	if(ncp->old != NULL)	{		free_NC(ncp->old);		ncp->old = NULL;	}	fClr(ncp->flags, NC_CREAT | NC_INDEF);	return ncp->nciop->sync(ncp->nciop);}#ifdef LOCKNUMRECstatic intNC_init_pe(NC *ncp, int basepe) {	if (basepe < 0 || basepe >= _num_pes()) {		return NC_EINVAL; /* invalid base pe */	}	/* initialize common values */	ncp->lock[LOCKNUMREC_VALUE] = 0;	ncp->lock[LOCKNUMREC_LOCK] = 0;	ncp->lock[LOCKNUMREC_SERVING] = 0;	ncp->lock[LOCKNUMREC_BASEPE] =  basepe;	return NC_NOERR;}#endif/* * Compute the expected size of the file. */intNC_calcsize(NC *ncp, off_t *calcsizep){	NC_var **vpp = (NC_var **)ncp->vars.value;	NC_var *const *const end = &vpp[ncp->vars.nelems];	NC_var *last_fix = NULL;	/* last "non-record" var */	NC_var *last_rec = NULL;	/* last "record" var */	/*NC_var *last_var;*/	int status;	int numrecvars = 0;	/* number of record variables */	if(ncp->vars.nelems == 0) { /* no non-record variables and 				       no record variables */	    *calcsizep = ncp->xsz; /* size of header */	    return NC_NOERR;	}	for( /*NADA*/; vpp < end; vpp++) {	    status = NC_var_shape(*vpp, &ncp->dims);	    if(status != NC_NOERR)		return status;	    if(IS_RECVAR(*vpp)) {		last_rec = *vpp;		numrecvars++;	    } else {		last_fix = *vpp;	    }	}	if(numrecvars == 0) {	    assert(last_fix != NULL);	    *calcsizep = last_fix->begin + last_fix->len;	    /*last_var = last_fix;*/	} else {       /* we have at least one record variable */	    *calcsizep = ncp->begin_rec + ncp->numrecs * ncp->recsize;	    /*last_var = last_rec;*/	}	return NC_NOERR;}/* Public */intnc__create(const char * path, int ioflags, size_t initialsz,	size_t *chunksizehintp, int *ncid_ptr){	return nc__create_mp(path, ioflags, initialsz, 0,		chunksizehintp, ncid_ptr);}intnc__create_mp(const char * path, int ioflags, size_t initialsz, int basepe,	size_t *chunksizehintp, int *ncid_ptr){	NC *ncp;	int status;	void *xp = NULL;	int sizeof_off_t = 0;#if ALWAYS_NC_SHARE /* DEBUG */	fSet(ioflags, NC_SHARE);#endif	ncp = new_NC(chunksizehintp);	if(ncp == NULL)		return NC_ENOMEM;#if defined(LOCKNUMREC) /* && _CRAYMPP */	if (status = NC_init_pe(ncp, basepe)) {		return status;	}#else	/*	 * !_CRAYMPP, only pe 0 is valid	 */	if(basepe != 0)		return NC_EINVAL;#endif	assert(ncp->flags == 0);	/* Apply default create format. */	if (default_create_format == NC_FORMAT_64BIT)	  ioflags |= NC_64BIT_OFFSET;	if (fIsSet(ioflags, NC_64BIT_OFFSET)) {	  fSet(ncp->flags, NC_64BIT_OFFSET);	  sizeof_off_t = 8;	} else {	  sizeof_off_t = 4;	}	assert(ncp->xsz == ncx_len_NC(ncp,sizeof_off_t));		status = ncio_create(path, ioflags,		initialsz,		0, ncp->xsz, &ncp->chunk,		&ncp->nciop, &xp);	if(status != NC_NOERR)	{		/* translate error status */		if(status == EEXIST)			status = NC_EEXIST;		goto unwind_alloc;	}	fSet(ncp->flags, NC_CREAT);	if(fIsSet(ncp->nciop->ioflags, NC_SHARE))	{		/*		 * NC_SHARE implies sync up the number of records as well.		 * (File format version one.)		 * Note that other header changes are not shared		 * automatically.  Some sort of IPC (external to this package)		 * would be used to trigger a call to nc_sync().		 */		fSet(ncp->flags, NC_NSYNC);	}	status = ncx_put_NC(ncp, &xp, sizeof_off_t, ncp->xsz);	if(status != NC_NOERR)		goto unwind_ioc;	add_to_NCList(ncp);	if(chunksizehintp != NULL)		*chunksizehintp = ncp->chunk;	*ncid_ptr = ncp->nciop->fd;	return NC_NOERR;unwind_ioc:	(void) ncio_close(ncp->nciop, 1); /* N.B.: unlink */	ncp->nciop = NULL;	/*FALLTHRU*/unwind_alloc:	free_NC(ncp);	return status;}/* This function sets a default create flag that will be logically   or'd to whatever flags are passed into nc_create for all future   calls to nc_create.   Valid default create flags are NC_64BIT_OFFSET, NC_CLOBBER,   NC_LOCK, NC_SHARE. */intnc_set_default_format(int format, int *old_formatp){    /* Return existing format if desired. */    if (old_formatp)      *old_formatp = default_create_format;    /* Make sure only valid format is set. */#ifdef USE_NETCDF4    if (format != NC_FORMAT_CLASSIC && format != NC_FORMAT_64BIT &&	format != NC_FORMAT_NETCDF4 && format != NC_FORMAT_NETCDF4_CLASSIC)      return NC_EINVAL;#else    if (format != NC_FORMAT_CLASSIC && format != NC_FORMAT_64BIT)      return NC_EINVAL;#endif    default_create_format = format;    return NC_NOERR;}intnc_create(const char * path, int ioflags, int *ncid_ptr){	return nc__create(path, ioflags, 0, NULL, ncid_ptr);}intnc__open(const char * path, int ioflags,	size_t *chunksizehintp, int *ncid_ptr){	return nc__open_mp(path, ioflags, 0,		chunksizehintp, ncid_ptr);}intnc__open_mp(const char * path, int ioflags, int basepe,	size_t *chunksizehintp, int *ncid_ptr){	NC *ncp;	int status;#if ALWAYS_NC_SHARE /* DEBUG */	fSet(ioflags, NC_SHARE);#endif	ncp = new_NC(chunksizehintp);	if(ncp == NULL)		return NC_ENOMEM;#if defined(LOCKNUMREC) /* && _CRAYMPP */	if (status = NC_init_pe(ncp, basepe)) {		return status;	}#else	/*	 * !_CRAYMPP, only pe 0 is valid	 */	if(basepe != 0)		return NC_EINVAL;#endif	status = ncio_open(path, ioflags,		0, 0, &ncp->chunk,		&ncp->nciop, 0);	if(status)		goto unwind_alloc;	assert(ncp->flags == 0);	if(fIsSet(ncp->nciop->ioflags, NC_SHARE))

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -