ADMB Documentation  11.1.1932
 All Classes Files Functions Variables Typedefs Friends Defines
gradstak.cpp
Go to the documentation of this file.
00001 /*
00002  * $Id: gradstak.cpp 1912 2014-04-17 23:51:20Z johnoel $
00003  *
00004  * Author: David Fournier
00005  * Copyright (c) 2008-2012 Regents of the University of California
00006  */
00011 #include <iostream>
00012 using namespace std;
00013 #include <fcntl.h>
00014 #include "fvar.hpp"
00015 #include <adstring.hpp>
00016 
00017 #if defined (__WAT32__)
00018   #include <io.h>
00019 #endif
00020 
00021 #ifdef _MSC_VER
00022   #define lseek _lseek
00023   #define  read _read
00024   #define write _write
00025   #define open _open
00026   #define close _close
00027   #include <sys\stat.h>
00028 #else
00029   #include <sys/stat.h>
00030   #include <sys/types.h>
00031   #include <unistd.h>
00032 #endif
00033 
00034 #if defined(__TURBOC__)
00035   #pragma hdrstop
00036   #include <iostream.h>
00037   #include <iomanip.h>
00038   #include <sys\stat.h>
00039 #endif
00040 
00041 #ifdef __ZTC__
00042   #include <iostream.hpp>
00043   #define S_IREAD 0000400
00044   #define S_IWRITE 0000200
00045 #endif
00046 
00047 #ifdef __NDPX__
00048   #define O_RDONLY 0
00049   #define O_WRONLY 1
00050   #define O_RDWR 2
00051   extern "C"
00052   {
00053     int lseek(int, int, int);
00054     int open(const char*, int);
00055     int creat(const char*, int);
00056     int close(int);
00057     int write(int, char*, int);
00058   };
00059 #endif
00060 
00061 #include <stdlib.h>
00062 #include <stdio.h>
00063 #include <string.h>
00064 #include <time.h>
00065 
00066 char lastchar(char *);
00067 char ad_random_part[6]="tmp";
00068 
00069 void fill_ad_random_part(void)
00070 {
00071 /*
00072   time_t t,tt;
00073   time(&t);
00074   tt=t;
00075   int div=1;
00076   for (int i=0;i<6;i++)
00077   {
00078     ad_random_part[i]=(tt/div)%10+48;
00079     div*=10;
00080   }
00081 */
00082 }
00086 grad_stack::grad_stack()
00087 {
00088   gradient_structure::TOTAL_BYTES = 0;
00089   gradient_structure::PREVIOUS_TOTAL_BYTES=0;
00090   true_length = gradient_structure::GRADSTACK_BUFFER_SIZE;
00091   length = true_length;
00092   if ((true_ptr_first = new grad_stack_entry[(size_t)length]) == 0)
00093   {
00094     cerr << "Memory allocation error in grad_stack constructor\n"
00095          << " trying to allocate "
00096          << length * sizeof(grad_stack_entry)<<" bytes\n";
00097     ad_exit(1);
00098   }
00099 
00100   test_the_pointer();
00101 
00102   ptr_first=true_ptr_first;
00103   ptr = ptr_first;
00104   ptr_last=ptr_first+(length-1);
00105   //table=new lvector(-128,250);
00106 
00107   _GRADFILE_PTR = -1; // set to illegal value for later checking
00108   end_pos  = 0;
00109   end_pos1 = 0;
00110   end_pos2 = 0;
00111 
00112   char* path = getenv("ADTMP"); // NULL if not defined
00113 
00114 #if defined(USE_ADPVM)
00115   adstring string_path;
00116   if (path) string_path=path;
00117   int on=0;
00118   int nopt=0;
00119   adstring currdir;
00120   ad_getcd(currdir);
00121   if (ad_comm::pvm_manager)
00122   {
00123     if ((on = option_match(ad_comm::argc, ad_comm::argv, "-slave", nopt)) > -1)
00124     {
00125       if (nopt ==1)
00126       {
00127         int ierr=make_sub_directory(ad_comm::argv[on+1]);
00128         ad_comm::subdir=ad_comm::argv[on+1];
00129         string_path+=ad_comm::subdir;
00130         path=(char*) string_path;
00131       }
00132       else
00133       {
00134         cerr << "Wrong number of options to -slave -- must be 1"
00135             " you have " << nopt << endl;
00136         ad_exit(1);
00137       }
00138     }
00139   }
00140 #endif
00141 
00142   if (path != NULL)
00143   {
00144 #if !defined (_WIN32)
00145     sprintf(&gradfile_name1[0],"%s/gradfil1.%s", path, ad_random_part);
00146 #else
00147     if (lastchar(path) != '\\')
00148     {
00149       sprintf(&gradfile_name1[0], "%s\\gradfil1.%s", path, ad_random_part);
00150     }
00151     else
00152     {
00153       sprintf(&gradfile_name1[0], "%sgradfil1.%s", path, ad_random_part);
00154     }
00155 #endif
00156   }
00157   else
00158   {
00159     sprintf(&gradfile_name1[0], "gradfil1.%s", ad_random_part);
00160   }
00161 
00162   path = getenv("ADTMP1"); // NULL if not defined
00163 #if defined(USE_ADPVM)
00164   adstring string_path2;
00165   if (path) string_path2=path;
00166   string_path2+=ad_comm::subdir;
00167   path=(char*) string_path2;
00168 #endif
00169   if (path != NULL)
00170   {
00171 #if !defined (_WIN32)
00172     if (strlen(path) > 0)
00173     {
00174       sprintf(&var_store_file_name[0],"%s/varssave.%s",path, ad_random_part);
00175       sprintf(&gradfile_name2[0],"%s/gradfil2.%s", path, ad_random_part);
00176     }
00177     else
00178     {
00179       sprintf(&var_store_file_name[0],"varssave.tmp");
00180       sprintf(&gradfile_name2[0],"gradfil2.tmp");
00181     }
00182 #else
00183     if (lastchar(path)!='\\')
00184     {
00185       sprintf(&gradfile_name2[0], "%s\\gradfil2.%s", path, ad_random_part);
00186       sprintf(&var_store_file_name[0], "%s\\varssave.%s", path, ad_random_part);
00187     }
00188     else
00189     {
00190       sprintf(&gradfile_name2[0], "%sgradfil2.%s", path, ad_random_part);
00191       sprintf(&var_store_file_name[0], "%svarssave.%s", path, ad_random_part);
00192     }
00193 #endif
00194   }
00195   else
00196   {
00197     sprintf(&gradfile_name2[0], "gradfil2.%s", ad_random_part);
00198     sprintf(&var_store_file_name[0], "varssave.%s", ad_random_part);
00199   }
00200 
00201   create_gradfile();
00202 
00203   strcpy(gradfile_name, gradfile_name1);
00204   _GRADFILE_PTR = _GRADFILE_PTR1;
00205 }
00209 grad_stack::~grad_stack()
00210 {
00211   const int repfs = option_match(ad_comm::argc, ad_comm::argv, "-fsize");
00212   if (ad_comm::global_logfile && repfs)
00213   {
00214      int pos = lseek(_GRADFILE_PTR1, 0, SEEK_END);
00215      *ad_comm::global_logfile << "size of file " << gradfile_name1
00216        << " = " << pos << endl;
00217 
00218      pos = lseek(_GRADFILE_PTR2, 0, SEEK_END);
00219      *ad_comm::global_logfile << "size of file " << gradfile_name2
00220        << " = " << pos << endl;
00221 
00222      pos = lseek(_VARSSAV_PTR, 0, SEEK_END);
00223      *ad_comm::global_logfile << "size of file " << var_store_file_name
00224        << " = " << pos << endl;
00225   }
00226   if (close(_GRADFILE_PTR1))
00227   {
00228     cerr << "Error closing file " << gradfile_name1 << "\n";
00229   }
00230   if (close(_GRADFILE_PTR2))
00231   {
00232     cerr << "Error closing file " << gradfile_name2 << "\n";
00233   }
00234   if (close(_VARSSAV_PTR))
00235   {
00236     cerr << "Error closing file " << var_store_file_name << "\n";
00237   }
00238 #if !defined (_MSC_VER)
00239   unlink(gradfile_name1);
00240   unlink(gradfile_name2);
00241   unlink(var_store_file_name);
00242 #else
00243   remove(gradfile_name1);
00244   remove(gradfile_name2);
00245   remove(var_store_file_name);
00246 #endif
00247 
00248   delete [] true_ptr_first;
00249   true_ptr_first = 0;
00250 }
00251 
00256   void  grad_stack::write_grad_stack_buffer()
00257   {
00258     unsigned int ierr;
00259 
00260     #ifdef GRAD_DIAG
00261       cout << "Grad_stack size exceeded\n ";
00262       cout << "Writing to temporary file -- \n";
00263     #endif
00264 
00265     ptr--;
00266 
00267     #ifdef GRAD_DIAG
00268       {
00269       long int lpos = lseek(_GRADFILE_PTR,0L,SEEK_CUR);
00270       cout << "Offset in file before write is " << lpos
00271                               << " bytes from the beginning\n";
00272       }
00273     #endif
00274 
00275     // if the buffer is really large only write the end of it
00276     set_gbuffer_pointers();
00277     unsigned nbw = (unsigned) sizeof(grad_stack_entry)* (unsigned) length;
00278 
00279     char * ttmp = (char *) ptr_first;
00280     ttmp--;
00281 
00282     // save the current end of file in case we can't write the whole buffer
00283     end_pos = lseek(_GRADFILE_PTR,0L,SEEK_CUR);
00284 #if defined(_MSC_VER)
00285     ierr = write(_GRADFILE_PTR, ptr_first, nbw);
00286 #else
00287     ierr = write(_GRADFILE_PTR, (char*)ptr_first, nbw);
00288 #endif
00289 
00290     if  (ierr != nbw)
00291     {
00292        cout << "Wrote " << ierr <<" not " << nbw << endl;
00293       lseek(_GRADFILE_PTR,end_pos,SEEK_SET);
00294       //save the end of file for this file so we can reposition later
00295       end_pos1 = end_pos;
00296       increment_current_gradfile_ptr();
00297 #if defined(_MSC_VER)
00298       ierr = write(_GRADFILE_PTR, ptr_first, nbw);
00299 #else
00300       ierr = write(_GRADFILE_PTR, (char*)ptr_first, nbw);
00301 #endif
00302 
00303       if  (ierr != nbw)
00304       {
00305         perror("Error writing to temporary gradient stack file");
00306         cerr <<"   File name: " << gradfile_name << "\n";
00307 #if defined(_MSC_VER)
00308         cerr <<"   File length: "
00309              << filelength(_GRADFILE_PTR)
00310              << " bytes.\n";
00311 #endif
00312         cerr <<"   Attempting to write " << nbw <<" bytes; wrote " << ierr
00313         << ".\n";
00314         exit(1);
00315       }
00316     }
00317     else
00318     {
00319       #ifdef GRAD_DIAG
00320       cout << "Wrote " << ierr << "bytes into temp. grad. file\n";
00321       #endif
00322     }
00323 
00324     #ifdef GRAD_DIAG
00325     {
00326       long int lpos = lseek(gradient_structure::_GRADFILE_PTR,0L,SEEK_CUR);
00327       cout << "Offset in file after write is " << lpos
00328            << " bytes from the beginning\n";
00329     }
00330     #endif
00331     //keep track of the size of the grad_stack
00332     gradient_structure::TOTAL_BYTES+=nbw;
00333     ptr = ptr_first;
00334   }
00335 
00340 void grad_stack::create_gradfile()
00341 {
00342   #if defined (__TURBOC__)
00343    _GRADFILE_PTR1=open(gradfile_name1, O_RDWR | O_CREAT |
00344        O_TRUNC | O_BINARY, S_IREAD | S_IWRITE);
00345    _VARSSAV_PTR=open(var_store_file_name, O_RDWR | O_CREAT |
00346        O_TRUNC | O_BINARY, S_IREAD | S_IWRITE);
00347   #elif defined (__ZTC__)
00348     _GRADFILE_PTR1=open(gradfile_name1, O_RDWR | O_CREAT |
00349       O_TRUNC , S_IREAD | S_IWRITE);
00350     _VARSSAV_PTR=open(var_store_file_name, O_RDWR | O_CREAT
00351       | O_TRUNC,  S_IREAD | S_IWRITE);
00352   #elif defined (__NDPX__)
00353     _GRADFILE_PTR1=creat(gradfile_name1, O_RDWR);
00354      _VARSSAV_PTR=creat(var_store_file_name, O_RDWR);
00355   #elif defined (__WAT32__)
00356    _GRADFILE_PTR1=open(gradfile_name1, O_RDWR | O_CREAT |
00357        O_TRUNC | O_BINARY, S_IREAD | S_IWRITE);
00358    _VARSSAV_PTR=open(var_store_file_name, O_RDWR | O_CREAT |
00359        O_TRUNC | O_BINARY, S_IREAD | S_IWRITE);
00360   #else
00361     _GRADFILE_PTR1=open(gradfile_name1, O_RDWR | O_CREAT | O_TRUNC |
00362       O_BINARY , 0777);
00363     _VARSSAV_PTR=open(var_store_file_name, O_RDWR |
00364       O_CREAT | O_TRUNC | O_BINARY, 0777);
00365   #endif
00366 
00367   if (_GRADFILE_PTR1 == -1)
00368   {
00369     if (ad_printf) (*ad_printf)("Error opening temporary gradient file"
00370      " %s\n",gradfile_name1);
00371     ad_exit(1);
00372   }
00373 
00374   if (_VARSSAV_PTR == -1)
00375   {
00376     perror("Error opening temporary gradient file");
00377     cerr <<"  Attempting to open " << var_store_file_name <<"\n";
00378     ad_exit(1);
00379   }
00380 
00381   #if defined (__TURBOC__)
00382     _GRADFILE_PTR2=open(gradfile_name2, O_RDWR | O_CREAT | O_TRUNC |
00383       O_BINARY, S_IREAD | S_IWRITE);
00384   #elif defined (__ZTC__)
00385     _GRADFILE_PTR2=open(gradfile_name2, O_RDWR | O_CREAT | O_TRUNC ,
00386       S_IREAD | S_IWRITE);
00387   #elif defined (__NDPX__)
00388     _GRADFILE_PTR2=creat(gradfile_name2, O_RDWR);
00389   #elif defined (_MSC_VER)
00390     _GRADFILE_PTR2=open(gradfile_name2, O_RDWR | O_CREAT | O_TRUNC |
00391       O_BINARY, S_IREAD | S_IWRITE);
00392   #elif defined (__WAT32__)
00393     _GRADFILE_PTR2=open(gradfile_name2, O_RDWR | O_CREAT | O_TRUNC |
00394       O_BINARY, S_IREAD | S_IWRITE);
00395   #else
00396     _GRADFILE_PTR2=open(gradfile_name2, O_RDWR | O_CREAT | O_TRUNC |
00397       O_BINARY , 0777);
00398   #endif
00399 
00400   if (_GRADFILE_PTR2 == -1)
00401   {
00402     perror("Error opening temporary gradient file");
00403     cerr <<"  Attempting to open " << gradfile_name2 <<"\n";
00404     ad_exit(1);
00405   }
00406 }
00411 void grad_stack::increment_current_gradfile_ptr()
00412 {
00413   if (_GRADFILE_PTR == _GRADFILE_PTR2)
00414   {
00415     cerr << "Attempted to open a third gradient file -- There is\n"
00416       "probably no more room on the TMP1 (if defined) device\n"
00417       "if possible set TMP1 environment string to a device with more room\n";
00418     ad_exit(1);
00419   }
00420    strcpy(gradfile_name, gradfile_name2);
00421   _GRADFILE_PTR = _GRADFILE_PTR2;
00422 }
00427 int grad_stack::decrement_current_gradfile_ptr()
00428 {
00429   if (_GRADFILE_PTR == _GRADFILE_PTR1)
00430   {
00431     return -1;
00432   }
00433 
00434   strcpy(gradfile_name, gradfile_name1);
00435   _GRADFILE_PTR = _GRADFILE_PTR1;
00436 
00437   return 0;
00438 }
00439 #ifdef _MSC_VER
00440 int grad_stack::gradfile_handle()
00441 #else
00442 int& grad_stack::gradfile_handle()
00443 #endif
00444 {
00445   return _GRADFILE_PTR;
00446 }
00451 char* grad_stack::get_gradfile_name()
00452 {
00453   return gradfile_name;
00454 }
00459 void grad_stack::set_gbuffer_pointers()
00460 {
00461   if (length > 10000L)
00462   {
00463     //make the buffer end_buf_size
00464     unsigned int end_buf_size=5000L;
00465     ptr_first+=length-end_buf_size;
00466     length=end_buf_size;
00467   }
00468 }
00473 void grad_stack::set_gradient_stack0(void (* func)(void),double * dep_addr)
00474 {
00475 #ifdef NO_DERIVS
00476   if (!gradient_structure::no_derivatives)
00477   {
00478 #endif
00479     if (ptr > ptr_last)
00480     {
00481       // current buffer is full -- write it to disk and reset pointer
00482       // and counter
00483       this->write_grad_stack_buffer();
00484     }
00485     ptr->func = func;
00486     ptr->dep_addr = dep_addr;
00487     ptr++;
00488 #ifdef NO_DERIVS
00489   }
00490 #endif
00491 }