mirror of
https://github.com/Unidata/netcdf-c.git
synced 2024-11-21 03:13:42 +08:00
190 lines
4.8 KiB
C
190 lines
4.8 KiB
C
/*
|
|
Copyright 2018, UCAR/Unidata
|
|
See COPYRIGHT file for copying and redistribution conditions.
|
|
|
|
This program tests the large file bug in netCDF 3.6.2,
|
|
creating byte and short variables larger than 4 GiB.
|
|
|
|
$Id: tst_big_var.c,v 1.9 2010/05/15 00:50:10 russ Exp $
|
|
*/
|
|
|
|
#include <nc_tests.h>
|
|
#include "err_macros.h"
|
|
#include <netcdf.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
|
|
#undef XFAIL
|
|
|
|
#define FILE_NAME "tst_diskless4.nc"
|
|
#define CHUNKSIZE 4096
|
|
#define DATASIZE (CHUNKSIZE/sizeof(int))
|
|
#define DIMMAX 500000000L
|
|
|
|
typedef enum Tag {Create,CreateDiskless,Open,OpenDiskless} Tag;
|
|
|
|
#define REPORT err_report(status,__FILE__,__LINE__)
|
|
|
|
static void
|
|
err_report(int status, char* file, int line)
|
|
{
|
|
printf("***FAIL: %s: line=%d status=%d %s\n",file,line,status,nc_strerror(status));
|
|
#ifdef XFAIL
|
|
exit(0);
|
|
#else
|
|
exit(1);
|
|
#endif
|
|
}
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
int status = NC_NOERR;
|
|
int iv;
|
|
unsigned int data[DATASIZE];
|
|
size_t start[1];
|
|
size_t count[1];
|
|
Tag tag = Create;
|
|
int cmode = 0;
|
|
int ncid;
|
|
int dimids[1];
|
|
void* memory;
|
|
size_t nvars;
|
|
int varids[4096];
|
|
size_t varsize;
|
|
size_t filesize;
|
|
|
|
/* Get the specified var/file size */
|
|
if(argc > 1) {
|
|
filesize = (size_t)atol(argv[1]);
|
|
} else
|
|
filesize = 1000000000L;
|
|
|
|
/* Test that we can malloc that much space */
|
|
memory = malloc(filesize);
|
|
if(memory == NULL) {
|
|
fprintf(stderr,"Cannot malloc %lu bytes\n",(unsigned long)filesize);
|
|
fprintf(stderr,"This may mean your machine does not have enough RAM. If this is the case, it is safe to ignore this error.\n");
|
|
exit(1);
|
|
}
|
|
free(memory);
|
|
|
|
if(argc > 2) {
|
|
if(strcmp(argv[2],"create")==0) tag = Create;
|
|
else if(strcmp(argv[2],"creatediskless")==0) tag = CreateDiskless;
|
|
else if(strcmp(argv[2],"open")==0) tag = Open;
|
|
else if(strcmp(argv[2],"opendiskless")==0) tag = OpenDiskless;
|
|
else {
|
|
fprintf(stderr,"illegal tag: %s",argv[2]);
|
|
exit(1);
|
|
}
|
|
} else
|
|
tag = Create; /* default */
|
|
|
|
switch (tag) {
|
|
case Create: printf("\n*** Create file\n"); break;
|
|
case CreateDiskless: printf("\n*** Create file diskless\n"); break;
|
|
case Open: printf("\n*** Open file\n"); break;
|
|
case OpenDiskless: printf("\n*** Open file diskless\n"); break;
|
|
}
|
|
|
|
switch (tag) {
|
|
case Create: cmode = NC_CLOBBER; break;
|
|
case CreateDiskless: cmode = NC_CLOBBER|NC_DISKLESS|NC_PERSIST|NC_WRITE; break;
|
|
case Open: cmode = 0; break;
|
|
case OpenDiskless: cmode = NC_DISKLESS; break;
|
|
}
|
|
|
|
switch (tag) {
|
|
case Create:
|
|
case CreateDiskless:
|
|
/* Try to alloc as much as possible initially */
|
|
if((status=nc__create(FILE_NAME, cmode, filesize, NULL, &ncid)))
|
|
REPORT;
|
|
if((status=nc_set_fill(ncid, NC_NOFILL, NULL)))
|
|
REPORT;
|
|
/* Only need 1 dimension */
|
|
if((status=nc_def_dim(ncid, "dim", DIMMAX, &dimids[0])))
|
|
REPORT;
|
|
break;
|
|
case Open:
|
|
case OpenDiskless:
|
|
if((status=nc_open(FILE_NAME, cmode, &ncid)))
|
|
REPORT;
|
|
if((status=nc_inq_dimid(ncid, "dim", &dimids[0])))
|
|
REPORT;
|
|
break;
|
|
}
|
|
|
|
varsize = DIMMAX;
|
|
nvars = filesize / varsize;
|
|
assert((filesize % DIMMAX) == 0);
|
|
assert(nvars < 4096);
|
|
|
|
for(iv=0;iv<nvars;iv++) {
|
|
char varname[32];
|
|
snprintf(varname, sizeof(varname),"var%d",iv);
|
|
switch (tag) {
|
|
case Create:
|
|
case CreateDiskless:
|
|
if((status=nc_def_var(ncid, varname, NC_BYTE, 1, &dimids[0], &varids[iv])))
|
|
REPORT;
|
|
break;
|
|
case Open:
|
|
case OpenDiskless:
|
|
if((status=nc_inq_varid(ncid, varname, &varids[iv])))
|
|
REPORT;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(tag == Create || tag == CreateDiskless) {
|
|
if((status=nc_enddef(ncid)))
|
|
REPORT;
|
|
}
|
|
|
|
for(size_t iv=0;iv<nvars;iv++) {
|
|
size_t pieces = varsize/CHUNKSIZE;
|
|
switch (tag) {
|
|
case Create:
|
|
case CreateDiskless:
|
|
/* Fill and put as integers */
|
|
for(size_t i=0;i<pieces;i++) {
|
|
start[0] = i*CHUNKSIZE;
|
|
count[0] = CHUNKSIZE;
|
|
for(size_t j=0;j<DATASIZE;j++)
|
|
data[j] = (unsigned int)(iv*((i*CHUNKSIZE)+j));
|
|
if((status=nc_put_vara(ncid,varids[iv],start,count,(void*)data)))
|
|
REPORT;
|
|
}
|
|
break;
|
|
case Open:
|
|
case OpenDiskless:
|
|
/* Read the var contents and validate */
|
|
for(size_t i=0;i<pieces;i++) {
|
|
start[0] = i*CHUNKSIZE;
|
|
count[0] = CHUNKSIZE;
|
|
if((status=nc_get_vara(ncid,varids[iv],start,count,(void*)data)))
|
|
REPORT;
|
|
for(size_t j=0;j<DATASIZE;j++) {
|
|
unsigned int expected = (unsigned int)(iv*((i*CHUNKSIZE)+j));
|
|
if(data[j] != expected) {
|
|
printf("mismatch: iv=%zu i=%zu j=%zu data=%u; should be %u\n",
|
|
iv, i,j,data[j],expected);
|
|
err++;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
if((status=nc_close(ncid)))
|
|
REPORT;
|
|
|
|
SUMMARIZE_ERR;
|
|
exit(0);
|
|
return 0;
|
|
}
|