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