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