📄 vnd.c
字号:
vnd->CurrentDimension = (int *)VNDemalloc(noppanels*sizeof(int), "VNDopen: allocating CurrentDimension"); vnd->CurrentBlock = (long *)VNDemalloc(noppanels*sizeof(long), "VNDopen: allocating CurrentBlock"); vnd->N = (long *)VNDemalloc(vnd->NumDim*sizeof(long), "VNDopen: allocating N"); vnd->NNodesPerBlock = (long *)VNDemalloc(vnd->NumDim*sizeof(long), "VNDopen: allocating NNodesPerBlock"); vnd->NBlocks = (long *)VNDemalloc(vnd->NumDim*sizeof(long), "VNDopen: allocating NBlocks"); vnd->ByteIncr = (long *)VNDemalloc(vnd->NumDim*sizeof(long), "VNDopen: allocating ByteIncr"); vnd->BlockIncr = (long *)VNDemalloc(vnd->NumDim*sizeof(long), "VNDopen: allocating BlockIncr"); if(mode==0 || mode==1) { j=(int) fread(vnd->N,sizeof(long),vnd->NumDim,fp); if(j!=vnd->NumDim)VNDerr("VNDopen: read error"); j=(int) fread(vnd->NNodesPerBlock,sizeof(long),vnd->NumDim,fp); if(j!=vnd->NumDim)VNDerr("VNDopen: read error"); j=(int) fread(vnd->NBlocks,sizeof(long),vnd->NumDim,fp); if(j!=vnd->NumDim)VNDerr("VNDopen: read error"); j=(int) fread(vnd->ByteIncr,sizeof(long),vnd->NumDim,fp); if(j!=vnd->NumDim)VNDerr("VNDopen: read error"); j=(int) fread(vnd->BlockIncr,sizeof(long),vnd->NumDim,fp); if(j!=vnd->NumDim)VNDerr("VNDopen: read error"); j=(int) fread(vnd->LenFileNames,sizeof(long),vnd->NumFiles,fp); if(j!=vnd->NumFiles)VNDerr("VNDopen: read error"); j=(int) fread(vnd->FirstDataByte,sizeof(long),vnd->NumFiles,fp); if(j!=vnd->NumFiles)VNDerr("VNDopen: read error"); j=(int) fread(vnd->LenFile,sizeof(long),vnd->NumFiles,fp); if(j!=vnd->NumFiles)VNDerr("VNDopen: read error"); for(j=0;j<vnd->NumFiles;j++){ vnd->FileNames[j]=(char *)VNDemalloc(vnd->LenFileNames[j]*sizeof(char), "VNDopen: allocating FileNames"); k=(int) fread(vnd->FileNames[j],sizeof(char), vnd->LenFileNames[j],fp); if(k!=vnd->LenFileNames[j]) VNDerr("VNDopen: read error"); } /* allocate buffer space for VND routines */ vnd->w = (char *)VNDemalloc( vnd->NumBytesMemBuf*noppanels*sizeof(char), "VNDopen: allocating w"); for(j=0;j<vnd->NumBytesMemBuf;j++) vnd->w[j]=0; }else{ for(j=0;j<vnd->NumDim;j++) vnd->N[j]=N[j]; j= VNDGetDimensions(vnd, lwmax/noppanels, 1); if(mode==3) return(vnd); vnd->FirstDataByte[0]+=sizeof(VND)+vnd->NumDim*sizeof(long)*5 + vnd->NumFiles*sizeof(long)*2 + vnd->NumFiles*sizeof(int); lcontrol=vnd->FirstDataByte[0]; if(vnd->NumDim>1) vnd->FirstDataByte[0]=BytesPerSector* (1 +(vnd->FirstDataByte[0]-1)/BytesPerSector); for(j=1;j<vnd->NumFiles;j++){ vnd->FirstDataByte[j]=0; } vnd->NumBytes1stDim=vnd->NumBytesPerBlock*vnd->NBlocks[0]; /* Make the number of blocks/file a multiple of the number of blocks needed in 1st dimension so can do long reads and writes in 1st dimension. */ vnd->NumBlocksPerFile=(vnd->NumBlocksPerPanel* vnd->NumPanels)/vnd->NBlocks[0]; vnd->NumBlocksPerFile=1 + (vnd->NumBlocksPerFile-1)/ vnd->NumFiles; vnd->NumBlocksPerFile*=vnd->NBlocks[0]; /* write out VND information to first file */ j=(int) fwrite(vnd,sizeof(VND),1,fp); if(j!=1)VNDerr("VNDopen: write error"); j=(int) fwrite(vnd->N,sizeof(long),vnd->NumDim,fp); if(j!=vnd->NumDim)VNDerr("VNDopen: write error"); j=(int) fwrite(vnd->NNodesPerBlock,sizeof(long),vnd->NumDim,fp); if(j!=vnd->NumDim)VNDerr("VNDopen: write error"); j=(int) fwrite(vnd->NBlocks,sizeof(long),vnd->NumDim,fp); if(j!=vnd->NumDim)VNDerr("VNDopen: write error"); j=(int) fwrite(vnd->ByteIncr,sizeof(long),vnd->NumDim,fp); if(j!=vnd->NumDim)VNDerr("VNDopen: write error"); j=(int) fwrite(vnd->BlockIncr,sizeof(long),vnd->NumDim,fp); if(j!=vnd->NumDim)VNDerr("VNDopen: write error"); j=(int) fwrite(vnd->LenFileNames,sizeof(int),vnd->NumFiles,fp); if(j!=vnd->NumFiles)VNDerr("VNDopen: write error"); j=(int) fwrite(vnd->FirstDataByte,sizeof(long),vnd->NumFiles,fp); if(j!=vnd->NumFiles)VNDerr("VNDopen: write error"); for(j=0;j<vnd->NumFiles;j++){ vnd->LenFile[j]=vnd->FirstDataByte[j]+ vnd->NumBlocksPerFile*vnd->NumBytesPerBlock; } vnd->LenFile[vnd->NumFiles]=vnd->FirstDataByte[vnd->NumFiles] + ( (vnd->NumPanels*vnd->NumBlocksPerPanel) - (vnd->NumFiles*vnd->NumBlocksPerFile) ) *vnd->NumBytesPerBlock; j=(int) fwrite(vnd->LenFile,sizeof(long),vnd->NumFiles,fp); if(j!=vnd->NumFiles)VNDerr("VNDopen: write error"); for(j=0;j<vnd->NumFiles;j++){ k=(int) fwrite(vnd->FileNames[j],sizeof(char), vnd->LenFileNames[j],fp); if(k!=vnd->LenFileNames[j]) VNDerr("VNDopen: write error"); } /* allocate buffer space for VND routines */ vnd->w = (char *)VNDemalloc( vnd->NumBytesMemBuf*noppanels*sizeof(char), "VNDopen: allocating w"); for(j=0;j<vnd->NumBytesMemBuf;j++) vnd->w[j]=0; lcontrol=vnd->FirstDataByte[0]-lcontrol; if(lcontrol>0) fwrite(vnd->w,sizeof(char),lcontrol,fp); /* initialize the VND files all zero bytes to check disk space*/ vnd->Mode="w"; for(j=0;j<vnd->NumOpenPanels;j++){ vnd->CurrentPanel[j] = -1; vnd->CurrentDimension[j] = -1; vnd->CurrentBlock[j] = -1; vnd->Modified[j] = 0; } for(ipanel=0;ipanel<vnd->NumPanels;ipanel++){ for(iblock=0;iblock<vnd->NumBlocksPerPanel; iblock+=vnd->NBlocks[0]){ j=VNDrwslice(vnd,0,'w',0,iblock,ipanel); } } } for(j=0;j<vnd->NumOpenPanels;j++){ vnd->CurrentPanel[j] = -1; vnd->CurrentDimension[j] = -1; vnd->CurrentBlock[j] = -1; vnd->Modified[j] = 0; } j=fclose(fp); if(mode==0){vnd->Mode="r";} else {vnd->Mode="r+";} vnd->FileDescriptor = fopen(vnd->FileNames[0],vnd->Mode);/*********************** if(vnd->NumDim>1){ setbuf(vnd->FileDescriptor,NULL); }else{ iblock = 10*BUFSIZ*(1+(vnd->NumBytesPerBlock-1)/BUFSIZ); j=setvbuf(vnd->FileDescriptor,NULL,_IOFBF,iblock); }************************/ /* Set file open mode for rest of processing */ return (vnd);}int VNDGetDimensions(VND *vnd, long lwmax, int ich)/******************************************************************int VNDGetDimensions(VND *vnd, long lwmax, int ich) Set dimensions for block matrix transpose in VND control structure. Initialize: vnd.NumBlocksPerPanel vnd.NumBytesMemBuf vnd.NumBytesPerBlock vnd.NumBytes1stDim vnd.NumNodesPerBlock vnd.NNodesPerBlock[k] for k=0 to NumDim-1 vnd.NBlocks[k] vnd.ByteIncr[k] vnd.BlockIncr[k] VND *vnd VND control structure Values required to be set on input include vnd.N[k] and vnd.NumBytesPerNode long lwmax number of characters of memory available int ich 1 if force even number of first dimension nodes per block (useful to allow real-to-complex ffts and make it possible to change number of bytes per node at a later point) return -1 if all fits in memory 0 if successful in partitioning to fit in memory 1 if failed to partition so fits in memory*********************************************************************/{ long i; long j; long k; long TotalBytesPerPanel; long TotalNodesPerPanel; long TotalNodesPerBlock; long MaxN; long ByteIncr; long BlockIncr; TotalNodesPerPanel=1; MaxN=0; for(j=0;j<vnd->NumDim;j++){ TotalNodesPerPanel*=vnd->N[j]; if(vnd->N[j]>MaxN) MaxN=vnd->N[j]; } TotalBytesPerPanel=TotalNodesPerPanel*vnd->NumBytesPerNode; if(vnd->NumDim>1) TotalBytesPerPanel=BytesPerSector* (1+(TotalBytesPerPanel-1)/BytesPerSector); if(TotalBytesPerPanel<=lwmax || vnd->NumDim==1 ){ vnd->NumBlocksPerPanel=1; vnd->NumBytesMemBuf=TotalBytesPerPanel; vnd->NumBytesPerBlock=TotalBytesPerPanel; vnd->NumBytes1stDim=TotalBytesPerPanel; vnd->NumNodesPerBlock=TotalNodesPerPanel; ByteIncr=vnd->NumBytesPerNode; BlockIncr=1; for(j=0;j<vnd->NumDim;j++){ vnd->NNodesPerBlock[j]=vnd->N[j]; vnd->NBlocks[j]=1; vnd->ByteIncr[j]=ByteIncr; vnd->BlockIncr[j]=BlockIncr; ByteIncr*=vnd->NNodesPerBlock[j]; BlockIncr*=vnd->NBlocks[j]; } return(0); } for(k=1;k<=MaxN;k++) { ByteIncr=vnd->NumBytesPerNode; BlockIncr=1; TotalNodesPerBlock=1; for(j=0;j<vnd->NumDim;j++){ vnd->NBlocks[j]=k; if(k>vnd->N[j])vnd->NBlocks[j]=vnd->N[j]; vnd->NNodesPerBlock[j]=1 + (vnd->N[j]-1)/vnd->NBlocks[j]; if(j==0 && ich==1) { /* Force even number of 1st dim elements per block */ i=vnd->NNodesPerBlock[j]; if(i!=(2*(i/2))) i++; vnd->NNodesPerBlock[j]=i; vnd->NBlocks[j]=1 + (vnd->N[j]-1)/i; } vnd->ByteIncr[j]=ByteIncr; vnd->BlockIncr[j]=BlockIncr; ByteIncr*=vnd->NNodesPerBlock[j]; BlockIncr*=vnd->NBlocks[j]; TotalNodesPerBlock*=vnd->NNodesPerBlock[j]; } vnd->NumBlocksPerPanel=BlockIncr; TotalNodesPerPanel=TotalNodesPerBlock*BlockIncr; ByteIncr=BytesPerSector*(1+(ByteIncr-1)/BytesPerSector); vnd->NumBytesPerBlock=ByteIncr; vnd->NumBytesMemBuf=k*ByteIncr; vnd->NumBytes1stDim=vnd->NBlocks[0]*ByteIncr; vnd->NumNodesPerBlock=TotalNodesPerBlock; if( ByteIncr==BytesPerSector ) return(0); if( (k*ByteIncr<=lwmax) && (ByteIncr<=MaxIOBuf) ) return(0); } return(-1);}int VNDrwslice(VND *vnd,int iopanel, char mode, int idim, long iblock, long ipanel)/********************************************************************int VNDrwslice(VND *vnd,int iopanel, char mode, int idim, long iblock, long ipanel) Read or write a slice for dimension idim into or from memory VND *vnd pointer to VND control structure int iopanel open panel counter (0 based. Always equals 0 if only one panel open at a time.) char mode 'r' for read; 'w' for write. int idim Dimension of slice to be read or written. (0 based. First dimension is idim=0.) long iblock Starting block of block matrix transpose slice for dimension idim (0 based). long ipanel Panel number (0 based) for desired slice. Function returns a value of 0 if successful.*********************************************************************/{ char *w; int j; int n; int n2read; long ib; w=vnd->w+iopanel*vnd->NumBytesMemBuf; ib = ipanel*vnd->NumBlocksPerPanel + iblock; if(idim==0 && vnd->NumBytesMemBuf<MaxIOBuf ){ if(VNDseek(vnd,ib)!=0) { fprintf(stderr,"VNDrwslice: seek failed on dim 0 \n"); fprintf(stderr, " mode = %c iopanel = %d idim = %d iblock = %ld ipanel = %ld \n", mode,iopanel,idim,iblock,ipanel); VNDdump(vnd,stderr); abort(); /* return(-1); */ } n2read=(int) (vnd->NumBytes1stDim); if(mode=='r'){ n=(int) fread(w,sizeof(char),n2read,vnd->FileDescriptor); }else{ n=(int) fwrite(w,sizeof(char),n2read,vnd->FileDescriptor); } if(n!=n2read){ fprintf(stderr,"VNDrwslice: wrong number of values\n"); if(mode=='r'){ fprintf(stderr, " Read %d bytes out of %d on 1st dim",n,n2read); }else{ fprintf(stderr, " Wrote %d bytes out of %d on 1st dim",n,n2read); } fprintf(stderr, " mode = %c iopanel = %d idim = %d iblock = %ld ipanel = %ld \n", mode,iopanel,idim,iblock,ipanel); VNDdump(vnd,stderr); abort(); /* return(-2); */ } return(0); } n2read=(int) (vnd->NumBytesPerBlock); for(j=0;j<vnd->NBlocks[idim];j++){ if(VNDseek(vnd,ib)!=0) { fprintf(stderr,"VNDrwslice: seek failed"); fprintf(stderr, " mode = %c iopanel = %d idim = %d iblock = %ld ipanel = %ld \n", mode,iopanel,idim,iblock,ipanel); abort(); /* return(-1); */ } if(mode=='r'){ n=(int) fread(&w[j*n2read],sizeof(char), n2read,vnd->FileDescriptor); }else{ n=(int) fwrite(&w[j*n2read],sizeof(char), n2read,vnd->FileDescriptor); } if(n!=n2read){ fprintf(stderr,"VNDrwslice wrong number of values"); if(mode=='r'){ fprintf(stderr, " Read %d bytes out of %d on dim %d \n", n,n2read,idim); }else{ fprintf(stderr, " Wrote %d bytes out of %d on dim %d \n", n,n2read,idim); } fprintf(stderr, " mode = %c iopanel = %d idim = %d iblock = %ld ipanel = %ld \n", mode,iopanel,idim,iblock,ipanel); VNDdump(vnd,stderr); abort(); /* return(-2); */ } ib=ib+vnd->BlockIncr[idim]; } return(0);}int VNDseek(VND *vnd, long ib)/****************************************************************int VNDseek(VND *vnd, long ib) Seek the desired block in VND file structure. (a) Go to the correct physical file, reopen if necessary (b) Seek the correct starting byte within the file VND *vnd pointer to VND control structure long ib desired block number The function returns 0 if successful, Nonzero if fail.*****************************************************************/{ int ifile; ifile = (int) (ib/vnd->NumBlocksPerFile); if(vnd->CurrentFile==-1){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -