ADMB Documentation  11.1.1916
 All Classes Files Functions Variables Typedefs Friends Defines
smartbuf.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: smartbuf.cpp 1915 2014-04-18 21:39:00Z johnoel $
00003  *
00004  * Author: David Fournier
00005  * Copyright (c) 2008-2012 Regents of the University of California
00006  */
00011 #define HOME_VERSION
00012 #include "fvar.hpp"
00013 #include "smartbuf.h"
00014 #ifdef _MSC_VER
00015   #define lseek _lseek
00016   #define  read _read
00017   #define write _write
00018   #include <sys\stat.h>
00019 #else
00020   #include <iostream>
00021   using namespace std;
00022   #include <memory.h>
00023   #include <fcntl.h>
00024   #include <sys/stat.h>
00025   #include <sys/types.h>
00026   #include <unistd.h>
00027 #endif
00028 
00029 #if defined(__TURBOC__)
00030   #pragma hdrstop
00031   #include <iostream.h>
00032   #include <sys\stat.h>
00033   #include <fcntl.h>
00034 #endif
00035 
00036 #ifdef __ZTC__
00037   #include <iostream.hpp>
00038   #define S_IREAD 0000400
00039   #define S_IWRITE 0000200
00040   #include <fcntl.h>
00041 #endif
00042 
00043 #ifdef __NDPX__
00044   #define O_RDONLY 0
00045   #define O_WRONLY 1
00046   #define O_RDWR 2
00047   extern "C"
00048   {
00049     int lseek(int, int, int);
00050     int open(const char*, int);
00051     int creat(const char*, int);
00052     int close(int);
00053     int write(int, char*, int);
00054     int read(int, char*, int);
00055   };
00056 #endif
00057 
00058 #include <limits.h>
00059 #include <stdlib.h>
00060 #include <stdio.h>
00061 #include <string.h>
00062   char lastchar(char *);
00063 
00064   void byte_copy(void * dest,void * source, unsigned num_bytes);
00065   extern char ad_random_part[6];
00066 
00071   ad_sbuffer::ad_sbuffer(unsigned long int sz,const char * froot)
00072   {
00073     // need some code here to decide where to put the file
00074     file_name=froot;
00075 
00076     const int us=sizeof(unsigned int);
00077     if (sz > UINT_MAX)
00078     {
00079       cout << "Error -- largest size for CMPDIF_BUFFER_SIZE is "
00080         << INT_MAX<<endl;
00081     }
00082     if ( (buff=new char[sz])==NULL)
00083     {
00084       cerr << "Error trying to allocate memory for ad_sbuffer buffer"<<endl;
00085       ad_exit(1);
00086     }
00087     buff_size=sz;
00088     buff_end=sz-us-2;
00089     offset=0;
00090     toffset=0;
00091 
00092 
00093 #if defined(USE_ADPVM)
00094     char * path = getenv("ADTMP1"); // NULL if not defined
00095     adstring string_path;
00096     if (path) string_path=path;
00097     int on=0;
00098     int nopt=0;
00099     adstring currdir;
00100     ad_getcd(currdir);
00101     if (ad_comm::pvm_manager)
00102     {
00103       if ( (on=option_match(ad_comm::argc,ad_comm::argv,"-slave",nopt))>-1)
00104       {
00105         if (nopt ==1)
00106         {
00107           {
00108             int ierr=make_sub_directory(ad_comm::argv[on+1]);
00109             ad_comm::subdir=ad_comm::argv[on+1];
00110             string_path+=ad_comm::subdir;
00111             path=(char*) string_path;
00112           }
00113         }
00114         else
00115         {
00116           cerr << "Wrong number of options to -slave -- must be 1"
00117             " you have " << nopt << endl;
00118           ad_exit(1);
00119         }
00120       }
00121     }
00122 #endif
00123 
00124 #if defined(_MSC_VER)
00125     file_ptr=open(file_name, O_RDWR | O_CREAT | O_TRUNC );
00126 #else
00127     file_ptr=open(file_name, O_RDWR | O_CREAT | O_TRUNC, 0777 );
00128 #endif
00129 
00130     if (file_ptr == -1)
00131     {
00132       if (ad_printf) (*ad_printf)("Error opening temporary gradient"
00133         " file %s\n", (char*)file_name );
00134       ad_exit(1);
00135     }
00136   }
00137 
00138 
00139 
00140   ad_sbuffer::~ad_sbuffer()
00141   {
00142     delete buff;
00143     buff=0;
00144     buff_end=0;
00145 
00146     if (close(file_ptr))
00147     {
00148       cerr << "Error closing file " << cmpdif_file_name << "\n";
00149     }
00150 #if defined (_MSC_VER)
00151       adstring currentdir;
00152       ad_getcd(currentdir);
00153       int xxx=remove(cmpdif_file_name);
00154       if (xxx) {
00155         cerr << "Error trying to delete file " << cmpdif_file_name << endl;
00156         xxx=unlink(cmpdif_file_name);
00157         cout << xxx << endl;
00158       }
00159 #else
00160       unlink(cmpdif_file_name);
00161 #endif
00162   }
00163 
00164 
00169 void ad_sbuffer::fread(void* s,const size_t num_bytes)
00170 {
00171   if (toffset < num_bytes)
00172   {
00173     long lpos = lseek(file_ptr,-((long int) buff_size),SEEK_CUR);
00174     //cout << "In fread filepos = " << lpos << endl;
00175     read_cmpdif_stack_buffer(lpos);
00176 /*
00177     for(int i=0;i<sizeof(unsigned int);i++)
00178     {
00179        fourb[i] = *(buff+buff_end+1+i);
00180     }
00181 */
00182    // cout << "roffset: " << offset << endl;
00183     offset -= num_bytes;
00184     toffset = offset;
00185   }
00186   else
00187   {
00188     toffset-=num_bytes; //decrement the temporary offset count
00189   }
00190   byte_copy((char *)s,buff+toffset,num_bytes);
00191   offset=toffset;
00192 }
00193 
00198 void ad_sbuffer::fwrite(void* s, const size_t num_bytes)
00199 {
00200   #ifdef NO_DERIVS
00201     if (gradient_structure::no_derivatives)
00202     {
00203       return;
00204     }
00205   #endif
00206   toffset+=num_bytes; //increment the temporary offset count
00207   if (toffset>buff_end)
00208   {
00209     if (num_bytes > buff_end)
00210     {
00211       const int us=sizeof(unsigned int);
00212       cerr << "Need to increase gradient_structure::CMPDIF_BUFFER_SIZE "
00213        "to at least" << long (toffset)+long(us)+2L << endl;
00214     }
00215     write_cmpdif_stack_buffer();
00216     toffset=num_bytes;
00217     offset=0;
00218   }
00219   byte_copy(buff+offset,(char *) s,num_bytes);
00220   offset=toffset;
00221 }
00222 
00227 void ad_sbuffer::read_cmpdif_stack_buffer(long int& lpos)
00228 {
00229   if (lpos == -1L)
00230   { cerr << "Error rewinding file in ad_sbuffer:fread"<<endl;
00231     ad_exit(1);
00232   }
00233     //cout << " trying to read buff_size = " << buff_size
00234       //   << " from cmpdif file" << endl;
00235   //cout << "offset before read is " << lseek(file_ptr,0,SEEK_CUR)<< endl;
00236   if (read(file_ptr,buff,buff_size) < 0)
00237   {
00238     cerr << "End of file trying to read "<< cmpdif_file_name << endl;
00239     ad_exit(1);
00240   }
00241   lpos = lseek(file_ptr,-((long int) buff_size),SEEK_CUR);
00242   //cout << "offset after read is " << lseek(file_ptr,0,SEEK_CUR)<< endl;
00243   for(unsigned int i=0;i<sizeof(unsigned int);i++)
00244   {
00245      fourb[i] = *(buff+buff_end+1+i);
00246   }
00247 }
00248 
00253   void ad_sbuffer::write_cmpdif_stack_buffer(void)
00254   {
00255     //cout << " trying to write buff_size = " << buff_size
00256       //   << " into cmpdif file" << endl;
00257     //clogf << " trying to write buff_size = " << buff_size
00258          //<< " into cmpdif file" << endl;
00259     //cout << "offset before write is " << lseek(file_ptr,0,SEEK_CUR)<< endl;
00260     //if (write(file_ptr,buff,buff_size)<buff_size)
00261     for(unsigned int i=0;i<sizeof(unsigned int);i++)
00262     {
00263       // save the offset at the end of the used part of the buffer
00264       *(buff+buff_end+1+i)=fourb[i];
00265     }
00266     if (write(file_ptr,buff,buff_size) < 0)
00267     {
00268       cerr << "End of file trying to write to file "<< cmpdif_file_name << endl;
00269       cerr << "There is probably no more room on the TMP1 (if defined) device\n"
00270       "If possible set TMP1 environment string to a device with more room\n";
00271       ad_exit(1);
00272     }
00273     //cout << "offset after write is " << lseek(file_ptr,0,SEEK_CUR)<< endl;
00274     //clogf << "offset after write is " << lseek(file_ptr,0,SEEK_CUR)<< endl;
00275   }
00276 
00281 void byte_copy(void* dest, void* source, unsigned num_bytes)
00282 {
00283 #if defined(__ADSGI__)
00284   char* pdest = (char*)dest;
00285   char* psource = (char*)source;
00286   int ii=0;
00287   while (ii < num_bytes)
00288   {
00289     //*((char *)dest)++ = *((char *)source)++;
00290     *pdest = *psource;
00291     pdest++;
00292     psource++;
00293     ii++;
00294   }
00295 #else
00296   memcpy((char*)dest, (char*)source, num_bytes);
00297 #endif
00298  }