ADMB Documentation  11.1.2545
 All Classes Files Functions Variables Typedefs Friends Defines
df_file.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: df_file.cpp 2333 2014-09-13 00:10:49Z johnoel $
00003  *
00004  * Author: David Fournier
00005  * Copyright (c) 2008-2012 Regents of the University of California
00006  */
00011 #include "fvar.hpp"
00012 #include <fcntl.h>
00013 
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 <sys/stat.h>
00024   #include <sys/types.h>
00025   #include <unistd.h>
00026 #endif
00027 
00028 #if defined(__TURBOC__)
00029   #pragma hdrstop
00030   #include <iostream.h>
00031   #include <iomanip.h>
00032   #include <sys\stat.h>
00033 #endif
00034 
00035 #ifdef __ZTC__
00036   #include <iostream.hpp>
00037   #define S_IREAD 0000400
00038   #define S_IWRITE 0000200
00039 #endif
00040 
00041 #ifdef __NDPX__
00042   #define O_RDONLY 0
00043   #define O_WRONLY 1
00044   #define O_RDWR 2
00045   extern "C"
00046   {
00047     int lseek(int, int, int);
00048     int open(const char*, int);
00049     int creat(const char*, int);
00050     int close(int);
00051     int write(int, char*, int);
00052     int read(int, char*, int);
00053   };
00054 #endif
00055 
00056 #ifdef __SUN__
00057 #include <memory.h>
00058 #include <iostream.h>
00059 #include <sys/stat.h>
00060 #include <sys/types.h>
00061 #ifndef _MSC_VER
00062 #include <unistd.h>
00063 #endif
00064 #endif
00065 
00066 #include <limits.h>
00067 #include <stdlib.h>
00068 #include <stdio.h>
00069 #include <string.h>
00070 
00071 #ifndef OPT_LIB
00072   #include <cassert>
00073 #endif
00074 
00075 char lastchar(char*);
00076 
00077 void byte_copy(void* dest, void* source, const size_t num_bytes)
00078 {
00079 #if defined(__ADSGI__)
00080   char* pdest = (char*)dest;
00081   char* psource = (char*)source;
00082   int ii=0;
00083   while (ii < num_bytes)
00084   {
00085     //*((char *)dest)++ = *((char *)source)++;
00086     *pdest = *psource;
00087     pdest++;
00088     psource++;
00089     ii++;
00090   }
00091 #else
00092   memcpy((char*)dest, (char*)source, num_bytes);
00093 #endif
00094 }
00095 
00096 extern char ad_random_part[6];
00097 
00103 DF_FILE::DF_FILE(const size_t nbytes):
00104   buff_end(nbytes - sizeof(size_t) - 2),
00105   buff_size(nbytes)
00106 {
00107 #if defined(__BORLANDC__)
00108   if (nbytes > INT_MAX)
00109   {
00110     cout << "Error -- largest size for CMPDIF_BUFFER_SIZE is "
00111          << INT_MAX<<endl;
00112   }
00113 #endif
00114 
00115 #if defined(_M_IX86)
00116   if (nbytes > LONG_MAX)
00117   {
00118     cout << "Error -- largest size for CMPDIF_BUFFER_SIZE is "
00119          << LONG_MAX <<endl;
00120   }
00121 #endif
00122 
00123 #if defined(__GNC__) && defined(__i686__)
00124   if (nbytes > INT_MAX)
00125   {
00126     cout << "Error -- largest size for CMPDIF_BUFFER_SIZE is "
00127          << INT_MAX<<endl;
00128   }
00129 #endif
00130 
00132 /*
00133 #ifndef OPT_LIB
00134   assert(nbytes > sizeof(size_t) + 2);
00135 #endif
00136 */
00137 
00138   if ((buff = new char[buff_size]) == NULL)
00139   {
00140     cerr << "Error trying to allocate memory for DF_FILE buffer"<<endl;
00141     ad_exit(1);
00142   }
00143   offset = 0;
00144   toffset = 0;
00145 
00146   char* path = getenv("ADTMP1"); // NULL if not defined
00147 
00148 #if defined(USE_ADPVM)
00149   adstring string_path;
00150   if (path) string_path=path;
00151 
00152   adstring currdir;
00153   ad_getcd(currdir);
00154   if (ad_comm::pvm_manager)
00155   {
00156     int on = 0;
00157     int nopt = 0;
00158     if ((on = option_match(ad_comm::argc,ad_comm::argv,"-slave",nopt)) > -1)
00159     {
00160       if (nopt == 1)
00161       {
00162         int ierr=make_sub_directory(ad_comm::argv[on+1]);
00163         ad_comm::subdir=ad_comm::argv[on+1];
00164         string_path+=ad_comm::subdir;
00165         path=(char*) string_path;
00166       }
00167       else
00168       {
00169         cerr << "Wrong number of options to -slave -- must be 1"
00170           " you have " << nopt << endl;
00171         ad_exit(1);
00172       }
00173     }
00174   }
00175 #endif
00176 
00177   if (path != NULL)
00178 #if !defined (_WIN32)
00179   {
00180       sprintf(&cmpdif_file_name[0],"%s/cmpdiff.%s", path,
00181         ad_random_part);
00182   }
00183 #else
00184   {
00185     if (lastchar(path) != '\\')
00186     {
00187       sprintf(&cmpdif_file_name[0],"%s\\cmpdiff.%s", path,
00188         ad_random_part);
00189     }
00190     else
00191     {
00192       sprintf(&cmpdif_file_name[0],"%scmpdiff.%s", path,
00193         ad_random_part);
00194     }
00195   }
00196 #endif
00197   else
00198   {
00199     sprintf(&cmpdif_file_name[0],"cmpdiff.%s",ad_random_part);
00200   }
00201 #if defined (_MSC_VER) || defined (__WAT32__)
00202   file_ptr=open(cmpdif_file_name, O_RDWR | O_CREAT | O_TRUNC |
00203                      O_BINARY, S_IREAD | S_IWRITE);
00204 #elif defined (__TURBOC__)
00205   file_ptr=open(cmpdif_file_name, O_RDWR | O_CREAT | O_TRUNC |
00206                      O_BINARY, S_IREAD | S_IWRITE);
00207 #elif defined (__ZTC__)
00208   file_ptr=open(cmpdif_file_name, O_RDWR | O_CREAT | O_TRUNC ,
00209                      S_IREAD | S_IWRITE);
00210 #elif  defined (__NDPX__)
00211   file_ptr=creat(cmpdif_file_name, O_RDWR);
00212 #else
00213   file_ptr=open(cmpdif_file_name, O_RDWR | O_CREAT | O_TRUNC |
00214        O_BINARY, 0777);
00215 #endif
00216 
00217   if (file_ptr == -1)
00218   {
00219     if (ad_printf) (*ad_printf)("Error opening temporary gradient"
00220         " file %s\n", cmpdif_file_name );
00221     ad_exit(1);
00222   }
00223 }
00227 DF_FILE::~DF_FILE()
00228 {
00229   delete [] buff;
00230   buff=0;
00231 
00232   int repfs = option_match(ad_comm::argc,ad_comm::argv,"-fsize");
00233 
00234   if (ad_comm::global_logfile && repfs)
00235   {
00236     off_t pos = lseek(file_ptr, 0, SEEK_END);
00237     *ad_comm::global_logfile << "size of file " << cmpdif_file_name
00238         << " = " << pos << endl;
00239   }
00240   if (close(file_ptr))
00241   {
00242     cerr << "Error closing file " << cmpdif_file_name << "\n";
00243   }
00244 #if !defined (_WIN32)
00245   unlink(cmpdif_file_name);
00246 #else
00247   adstring currentdir;
00248   ad_getcd(currentdir);
00249   int xxx=remove(cmpdif_file_name);
00250   if (xxx)
00251   {
00252     cerr << "Error trying to delete file " << cmpdif_file_name << endl;
00253     xxx=unlink(cmpdif_file_name);
00254     cout << xxx << endl;
00255   }
00256 #endif
00257 }
00262 void DF_FILE::fread(void* s,const size_t num_bytes)
00263 {
00264   if (toffset < num_bytes)
00265   {
00266     off_t lpos = lseek(file_ptr, -((off_t)buff_size), SEEK_CUR);
00267     read_cmpdif_stack_buffer(lpos);
00268     offset -= num_bytes;
00269     toffset = offset;
00270   }
00271   else
00272   {
00273     toffset-=num_bytes; //decrement the temporary offset count
00274   }
00275   byte_copy((char*)s, buff+toffset,num_bytes);
00276   offset=toffset;
00277 }
00282 void DF_FILE::fwrite(const void* s, const size_t num_bytes)
00283 {
00284 #ifdef NO_DERIVS
00285   if (gradient_structure::no_derivatives)
00286   {
00287     return;
00288   }
00289 #endif
00290   toffset+=num_bytes; //increment the temporary offset count
00291   if (toffset>buff_end)
00292   {
00293     if (num_bytes > buff_end)
00294     {
00295       const size_t us = toffset + sizeof(size_t) + 2L;
00296       cerr << "Need to increase gradient_structure::CMPDIF_BUFFER_SIZE "
00297        "to at least" << us << endl;
00298     }
00299     write_cmpdif_stack_buffer();
00300     toffset=num_bytes;
00301     offset=0;
00302   }
00303   byte_copy(buff+offset,(char *) s,num_bytes);
00304   offset=toffset;
00305 }
00310 void DF_FILE::read_cmpdif_stack_buffer(off_t& lpos)
00311 {
00312   if (lpos == -1L)
00313   {
00314     cerr << "Error rewinding file in DF_FILE:fread"<<endl;
00315     ad_exit(1);
00316   }
00317   if (read(file_ptr, buff, buff_size) < 0)
00318   {
00319     cerr << "End of file trying to read "<< cmpdif_file_name << endl;
00320     ad_exit(1);
00321   }
00322   lpos = lseek(file_ptr, -((off_t)buff_size),SEEK_CUR);
00323   for (size_t i = 0;i < sizeof(size_t); i++)
00324   {
00325     fourb[i] = *(buff+buff_end+1+i);
00326   }
00327 }
00332 void DF_FILE::write_cmpdif_stack_buffer(void)
00333 {
00334   // save the offset at the end of the used part of the buffer
00335   for (size_t i = 0; i < sizeof(size_t); i++)
00336   {
00337     *(buff+buff_end+1+i) = fourb[i];
00338   }
00339   if (write(file_ptr, buff, buff_size) < 0)
00340   {
00341     cerr << "End of file trying to write to file "<< cmpdif_file_name << endl;
00342     cerr << "There is probably no more room on the TMP1 (if defined) device\n"
00343     "If possible set TMP1 environment string to a device with more room\n";
00344     ad_exit(1);
00345   }
00346 }