ADMB Documentation  11.4.2890
 All Classes Files Functions Variables Typedefs Friends Defines
df_file.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id$
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 #if defined(__MINGW64__) || (defined(_WIN64) && defined(_MSC_VER))
00072   #include <cassert>
00073   #include <climits>
00074 #else
00075   #ifndef OPT_LIB
00076     #include <cassert>
00077   #endif
00078 #endif
00079 
00080 char lastchar(char*);
00081 
00082 void byte_copy(void* dest, void* source, const size_t num_bytes)
00083 {
00084 #if defined(__ADSGI__)
00085   char* pdest = (char*)dest;
00086   char* psource = (char*)source;
00087   int ii=0;
00088   while (ii < num_bytes)
00089   {
00090     //*((char *)dest)++ = *((char *)source)++;
00091     *pdest = *psource;
00092     pdest++;
00093     psource++;
00094     ii++;
00095   }
00096 #else
00097   memcpy((char*)dest, (char*)source, num_bytes);
00098 #endif
00099 }
00100 
00101 extern char ad_random_part[6];
00102 
00108 DF_FILE::DF_FILE(const size_t nbytes):
00109   buff_end(nbytes - sizeof(size_t) - 2),
00110   buff_size(nbytes)
00111 {
00112 #if defined(__BORLANDC__)
00113   if (nbytes > INT_MAX)
00114   {
00115     cout << "Error -- largest size for CMPDIF_BUFFER_SIZE is "
00116          << INT_MAX<<endl;
00117   }
00118 #endif
00119 
00120 #if defined(_M_IX86)
00121   if (nbytes > LONG_MAX)
00122   {
00123     cout << "Error -- largest size for CMPDIF_BUFFER_SIZE is "
00124          << LONG_MAX <<endl;
00125   }
00126 #endif
00127 
00128 #if defined(__GNC__) && defined(__i686__)
00129   if (nbytes > INT_MAX)
00130   {
00131     cout << "Error -- largest size for CMPDIF_BUFFER_SIZE is "
00132          << INT_MAX<<endl;
00133   }
00134 #endif
00135 
00137 /*
00138 #ifndef OPT_LIB
00139   assert(nbytes > sizeof(size_t) + 2);
00140 #endif
00141 */
00142 
00143   buff = new char[buff_size];
00144   if (buff == NULL)
00145   {
00146     cerr << "Error trying to allocate memory for DF_FILE buffer"<<endl;
00147     ad_exit(1);
00148   }
00149 #ifndef OPT_LIB
00150   memset(buff, 0, buff_size);
00151 #endif
00152 
00153   offset = 0;
00154   toffset = 0;
00155 
00156   char* path = getenv("ADTMP1"); // NULL if not defined
00157 
00158 #if defined(USE_ADPVM)
00159   adstring string_path;
00160   if (path) string_path=path;
00161 
00162   adstring currdir;
00163   ad_getcd(currdir);
00164   if (ad_comm::pvm_manager)
00165   {
00166     int on = 0;
00167     int nopt = 0;
00168     if ((on = option_match(ad_comm::argc,ad_comm::argv,"-slave",nopt)) > -1)
00169     {
00170       if (nopt == 1)
00171       {
00172         int ierr=make_sub_directory(ad_comm::argv[on+1]);
00173         ad_comm::subdir=ad_comm::argv[on+1];
00174         string_path+=ad_comm::subdir;
00175         path=(char*) string_path;
00176       }
00177       else
00178       {
00179         cerr << "Wrong number of options to -slave -- must be 1"
00180           " you have " << nopt << endl;
00181         ad_exit(1);
00182       }
00183     }
00184   }
00185 #endif
00186 
00187   if (path != NULL)
00188 #if !defined (_WIN32)
00189   {
00190       sprintf(&cmpdif_file_name[0],"%s/cmpdiff.%s", path,
00191         ad_random_part);
00192   }
00193 #else
00194   {
00195     if (lastchar(path) != '\\')
00196     {
00197       sprintf(&cmpdif_file_name[0],"%s\\cmpdiff.%s", path,
00198         ad_random_part);
00199     }
00200     else
00201     {
00202       sprintf(&cmpdif_file_name[0],"%scmpdiff.%s", path,
00203         ad_random_part);
00204     }
00205   }
00206 #endif
00207   else
00208   {
00209     sprintf(&cmpdif_file_name[0],"cmpdiff.%s",ad_random_part);
00210   }
00211 #if defined (_MSC_VER) || defined (__WAT32__)
00212   file_ptr=open(cmpdif_file_name, O_RDWR | O_CREAT | O_TRUNC |
00213                      O_BINARY, S_IREAD | S_IWRITE);
00214 #elif defined (__TURBOC__)
00215   file_ptr=open(cmpdif_file_name, O_RDWR | O_CREAT | O_TRUNC |
00216                      O_BINARY, S_IREAD | S_IWRITE);
00217 #elif defined (__ZTC__)
00218   file_ptr=open(cmpdif_file_name, O_RDWR | O_CREAT | O_TRUNC ,
00219                      S_IREAD | S_IWRITE);
00220 #elif  defined (__NDPX__)
00221   file_ptr=creat(cmpdif_file_name, O_RDWR);
00222 #else
00223   file_ptr=open(cmpdif_file_name, O_RDWR | O_CREAT | O_TRUNC |
00224        O_BINARY, 0777);
00225 #endif
00226 
00227   if (file_ptr == -1)
00228   {
00229     if (ad_printf) (*ad_printf)("Error opening temporary gradient"
00230         " file %s\n", cmpdif_file_name );
00231     ad_exit(1);
00232   }
00233 }
00237 DF_FILE::~DF_FILE()
00238 {
00239   delete [] buff;
00240   buff=0;
00241 
00242   int repfs = option_match(ad_comm::argc,ad_comm::argv,"-fsize");
00243 
00244   if (ad_comm::global_logfile && repfs)
00245   {
00246     off_t pos = lseek(file_ptr, 0, SEEK_END);
00247     *ad_comm::global_logfile << "size of file " << cmpdif_file_name
00248         << " = " << pos << endl;
00249   }
00250   if (close(file_ptr))
00251   {
00252     cerr << "Error closing file " << cmpdif_file_name << "\n";
00253   }
00254 #if !defined (_WIN32)
00255   unlink(cmpdif_file_name);
00256 #else
00257   adstring currentdir;
00258   ad_getcd(currentdir);
00259   int xxx=remove(cmpdif_file_name);
00260   if (xxx)
00261   {
00262     cerr << "Error trying to delete file " << cmpdif_file_name << endl;
00263     xxx=unlink(cmpdif_file_name);
00264     cout << xxx << endl;
00265   }
00266 #endif
00267 }
00272 void DF_FILE::fread(void* s,const size_t num_bytes)
00273 {
00274   if (toffset < num_bytes)
00275   {
00276     off_t lpos = lseek(file_ptr, -((off_t)buff_size), SEEK_CUR);
00277     read_cmpdif_stack_buffer(lpos);
00278     offset -= num_bytes;
00279     toffset = offset;
00280   }
00281   else
00282   {
00283     toffset-=num_bytes; //decrement the temporary offset count
00284   }
00285   byte_copy((char*)s, buff+toffset,num_bytes);
00286   offset=toffset;
00287 }
00292 void DF_FILE::fwrite(const void* s, const size_t num_bytes)
00293 {
00294 #ifdef NO_DERIVS
00295   if (gradient_structure::no_derivatives)
00296   {
00297     return;
00298   }
00299 #endif
00300   toffset+=num_bytes; //increment the temporary offset count
00301   if (toffset>buff_end)
00302   {
00303     if (num_bytes > buff_end)
00304     {
00305       const size_t us = toffset + sizeof(size_t) + 2L;
00306       cerr << "Need to increase gradient_structure::CMPDIF_BUFFER_SIZE "
00307        "to at least" << us << endl;
00308     }
00309     write_cmpdif_stack_buffer();
00310     toffset=num_bytes;
00311     offset=0;
00312   }
00313   byte_copy(buff+offset,(char *) s,num_bytes);
00314   offset=toffset;
00315 }
00320 void DF_FILE::read_cmpdif_stack_buffer(off_t& lpos)
00321 {
00322   if (lpos == -1L)
00323   {
00324     cerr << "Error rewinding file in DF_FILE:fread"<<endl;
00325     ad_exit(1);
00326   }
00327 #if defined(__MINGW64__) || (defined(_WIN64) && defined(_MSC_VER))
00328   assert(buff_size <= UINT_MAX);
00329   if (read(file_ptr, buff, (unsigned int)buff_size) < 0)
00330 #else
00331   if (read(file_ptr, buff, buff_size) < 0)
00332 #endif
00333   {
00334     cerr << "End of file trying to read "<< cmpdif_file_name << endl;
00335     ad_exit(1);
00336   }
00337   lpos = lseek(file_ptr, -((off_t)buff_size),SEEK_CUR);
00338   for (size_t i = 0;i < sizeof(size_t); i++)
00339   {
00340     fourb[i] = *(buff+buff_end+1+i);
00341   }
00342 }
00347 void DF_FILE::write_cmpdif_stack_buffer(void)
00348 {
00349   // save the offset at the end of the used part of the buffer
00350   for (size_t i = 0; i < sizeof(size_t); i++)
00351   {
00352     *(buff+buff_end+1+i) = fourb[i];
00353   }
00354 #if defined(__MINGW64__) || (defined(_WIN64) && defined(_MSC_VER))
00355   assert(buff_size <= UINT_MAX);
00356   if (write(file_ptr, buff, (unsigned int)buff_size) < 0)
00357 #else
00358   if (write(file_ptr, buff, buff_size) < 0)
00359 #endif
00360   {
00361     cerr << "End of file trying to write to file "<< cmpdif_file_name << endl;
00362     cerr << "There is probably no more room on the TMP1 (if defined) device\n"
00363     "If possible set TMP1 environment string to a device with more room\n";
00364     ad_exit(1);
00365   }
00366 }