Commit bb457896ff0324f28e9459f04fc331796dcc208a

Authored by David Mayerich
1 parent b66bbf3f

improved error messages, defaulted to read-only ENVI files

stim/envi/agilent_binary.h
@@ -225,7 +225,7 @@ public: @@ -225,7 +225,7 @@ public:
225 225
226 //#ifdef CUDA_FOUND 226 //#ifdef CUDA_FOUND
227 /// Perform an FFT and return a binary file with bands in the specified range 227 /// Perform an FFT and return a binary file with bands in the specified range
228 - agilent_binary<T> fft(double band_min, double band_max, double ELWN = 15798, int UDR = 2){ 228 + agilent_binary<T> fft(double band_min, double band_max, double ELWN = 15798, int UDR = 2, int device = 0){
229 auto total_start = std::chrono::high_resolution_clock::now(); 229 auto total_start = std::chrono::high_resolution_clock::now();
230 230
231 auto start = std::chrono::high_resolution_clock::now(); 231 auto start = std::chrono::high_resolution_clock::now();
@@ -240,6 +240,29 @@ public: @@ -240,6 +240,29 @@ public:
240 // std::cout << "Transpose data: " << diff.count() << " s\n"; 240 // std::cout << "Transpose data: " << diff.count() << " s\n";
241 241
242 start = std::chrono::high_resolution_clock::now(); 242 start = std::chrono::high_resolution_clock::now();
  243 + if (device >= 0) { //if a CUDA device is specified
  244 + int dev_count;
  245 + HANDLE_ERROR(cudaGetDeviceCount(&dev_count)); //get the number of CUDA devices
  246 + std::cout << "Number of CUDA devices: " << dev_count << std::endl; //output the number of CUDA devices
  247 + cudaDeviceProp prop;
  248 + std::cout << "CUDA devices----" << std::endl;
  249 + for (int d = 0; d < dev_count; d++) { //for each CUDA device
  250 + cudaGetDeviceProperties(&prop, d); //get the property of the first device
  251 + //float cc = prop.major + prop.minor / 10.0f; //calculate the compute capability
  252 + std::cout << d << ": [" << prop.major << "." << prop.minor << "] " << prop.name << std::endl; //display the device information
  253 + //if(cc > best_device_cc){
  254 + // best_device_cc = cc; //if this is better than the previous device, use it
  255 + // best_device_id = d;
  256 + //}
  257 + }
  258 + if (dev_count > 0 && dev_count > device) { //if the first device is not an emulator
  259 + cudaGetDeviceProperties(&prop, device); //get the property of the requested CUDA device
  260 + if (prop.major != 9999) {
  261 + std::cout << "Using device " << device << std::endl;
  262 + HANDLE_ERROR(cudaSetDevice(device));
  263 + }
  264 + }
  265 + }
243 cufftHandle plan; //allocate space for a cufft plan 266 cufftHandle plan; //allocate space for a cufft plan
244 cufftReal* gpu_data; //create a pointer to the data 267 cufftReal* gpu_data; //create a pointer to the data
245 size_t batch = R[0] * R[1]; //calculate the batch size (X * Y) 268 size_t batch = R[0] * R[1]; //calculate the batch size (X * Y)
@@ -55,11 +55,12 @@ public: @@ -55,11 +55,12 @@ public:
55 unsigned long long Y, 55 unsigned long long Y,
56 unsigned long long B, 56 unsigned long long B,
57 unsigned long long header_offset, 57 unsigned long long header_offset,
58 - std::vector<double> wavelengths){ 58 + std::vector<double> wavelengths,
  59 + stim::iotype io = stim::io_in){
59 60
60 w = wavelengths; 61 w = wavelengths;
61 62
62 - return open(filename, vec<unsigned long long>(X, B, Y), header_offset); 63 + return open(filename, vec<unsigned long long>(X, B, Y), header_offset, io);
63 64
64 } 65 }
65 66
stim/envi/binary.h
@@ -143,6 +143,8 @@ public: @@ -143,6 +143,8 @@ public:
143 * @param T is the data type used to store data to disk (generally float or double) 143 * @param T is the data type used to store data to disk (generally float or double)
144 * @param D is the dimension of the data (default 3) 144 * @param D is the dimension of the data (default 3)
145 */ 145 */
  146 +
  147 +enum iotype {io_in, io_out};
146 template< typename T, unsigned int D = 3 > 148 template< typename T, unsigned int D = 3 >
147 class binary{ 149 class binary{
148 150
@@ -205,19 +207,21 @@ protected: @@ -205,19 +207,21 @@ protected:
205 /// Private helper file that opens a specified binary file. 207 /// Private helper file that opens a specified binary file.
206 208
207 /// @param filename is the name of the binary file to stream 209 /// @param filename is the name of the binary file to stream
208 - bool open_file(std::string filename){ 210 + bool open_file(std::string filename, stim::iotype io = io_in){
209 //open the file as binary for reading and writing 211 //open the file as binary for reading and writing
210 - file.open(filename.c_str(), std::ios::in | std::ios::out | std::ios::binary);  
211 -  
212 - //if the file isn't open, the user may only have read access  
213 - if(!file.is_open()){  
214 - std::cout<<"class STIM::BINARY - failed to open file, trying for read only"<<std::endl; 212 + if(io == io_in)
215 file.open(filename.c_str(), std::ios::in | std::ios::binary); 213 file.open(filename.c_str(), std::ios::in | std::ios::binary);
216 - if(!file.is_open()){  
217 - std::cout<<" still unable to load the file"<<std::endl; 214 + else if (io == io_out) {
  215 + file.open(filename.c_str(), std::ios::out | std::ios::binary);
  216 + if (!file.is_open()) {
  217 + std::cout << "stim::binary ERROR - unable to open file for writing: " << filename << std::endl;
218 return false; 218 return false;
219 } 219 }
220 } 220 }
  221 + else {
  222 + std::cout << "stim::binary ERROR - unrecognized IO format" << std::endl;
  223 + return false;
  224 + }
221 225
222 //if the file is successful 226 //if the file is successful
223 if(file){ 227 if(file){
@@ -275,14 +279,14 @@ public: @@ -275,14 +279,14 @@ public:
275 /// @param filename is the name of the binary file 279 /// @param filename is the name of the binary file
276 /// @param r is a STIM vector specifying the size of the binary file along each dimension 280 /// @param r is a STIM vector specifying the size of the binary file along each dimension
277 /// @param h is the length (in bytes) of any header file (default zero) 281 /// @param h is the length (in bytes) of any header file (default zero)
278 - bool open(std::string filename, vec<unsigned long long> r, unsigned long long h = 0){ 282 + bool open(std::string filename, vec<unsigned long long> r, unsigned long long h = 0, stim::iotype io = stim::io_in){
279 283
280 for(unsigned long long i = 0; i < D; i++) //set the dimensions of the binary file object 284 for(unsigned long long i = 0; i < D; i++) //set the dimensions of the binary file object
281 R[i] = r[i]; 285 R[i] = r[i];
282 286
283 header = h; //save the header size 287 header = h; //save the header size
284 288
285 - if(!open_file(filename)) return false; //open the binary file 289 + if(!open_file(filename), io) return false; //open the binary file
286 290
287 //reset(); 291 //reset();
288 292
@@ -65,14 +65,15 @@ public: @@ -65,14 +65,15 @@ public:
65 unsigned long long Y, 65 unsigned long long Y,
66 unsigned long long B, 66 unsigned long long B,
67 unsigned long long header_offset, 67 unsigned long long header_offset,
68 - std::vector<double> wavelengths){ 68 + std::vector<double> wavelengths,
  69 + stim::iotype io = stim::io_in){
69 70
70 //copy the wavelengths to the BSQ file structure 71 //copy the wavelengths to the BSQ file structure
71 w = wavelengths; 72 w = wavelengths;
72 //copy the offset to the structure 73 //copy the offset to the structure
73 offset = header_offset; 74 offset = header_offset;
74 75
75 - return open(filename, vec<unsigned long long>(B, X, Y), header_offset); 76 + return open(filename, vec<unsigned long long>(B, X, Y), header_offset, io);
76 77
77 } 78 }
78 79
@@ -64,14 +64,15 @@ public: @@ -64,14 +64,15 @@ public:
64 unsigned long long Y, 64 unsigned long long Y,
65 unsigned long long B, 65 unsigned long long B,
66 unsigned long long header_offset, 66 unsigned long long header_offset,
67 - std::vector<double> wavelengths){ 67 + std::vector<double> wavelengths,
  68 + stim::iotype io = stim::io_in){
68 69
69 //copy the wavelengths to the BSQ file structure 70 //copy the wavelengths to the BSQ file structure
70 w = wavelengths; 71 w = wavelengths;
71 //copy the wavelengths to the structure 72 //copy the wavelengths to the structure
72 offset = header_offset; 73 offset = header_offset;
73 74
74 - return open(filename, vec<unsigned long long>(X, Y, B), header_offset); 75 + return open(filename, vec<unsigned long long>(X, Y, B), header_offset, io);
75 } 76 }
76 77
77 /// Retrieve a single band (based on index) and stores it in pre-allocated memory. 78 /// Retrieve a single band (based on index) and stores it in pre-allocated memory.
@@ -363,7 +363,7 @@ public: @@ -363,7 +363,7 @@ public:
363 } 363 }
364 364
365 /// Open a previously opened ENVI file 365 /// Open a previously opened ENVI file
366 - bool open(){ 366 + bool open(stim::iotype io = stim::io_in){
367 367
368 //load the file 368 //load the file
369 if(header.interleave == envi_header::BSQ) { //if the infile is bsq file 369 if(header.interleave == envi_header::BSQ) { //if the infile is bsq file
@@ -451,7 +451,7 @@ public: @@ -451,7 +451,7 @@ public:
451 451
452 /// @param filename is the name of the ENVI binary file 452 /// @param filename is the name of the ENVI binary file
453 /// @param header is an ENVI header structure 453 /// @param header is an ENVI header structure
454 - bool open(std::string filename, stim::envi_header h){ 454 + bool open(std::string filename, stim::envi_header h, stim::iotype io = stim::io_in){
455 455
456 456
457 header = h; //store the header 457 header = h; //store the header
@@ -459,7 +459,7 @@ public: @@ -459,7 +459,7 @@ public:
459 459
460 allocate(); 460 allocate();
461 461
462 - return open(); //open the ENVI file; 462 + return open(io); //open the ENVI file;
463 463
464 464
465 } 465 }
@@ -468,18 +468,21 @@ public: @@ -468,18 +468,21 @@ public:
468 468
469 /// @param filename is the name of the ENVI binary file 469 /// @param filename is the name of the ENVI binary file
470 /// @param headername is the name of the ENVI header file 470 /// @param headername is the name of the ENVI header file
471 - bool open(std::string filename, std::string headername){ 471 + bool open(std::string filename, std::string headername, stim::iotype io = stim::io_in){
472 472
473 //allocate memory 473 //allocate memory
474 //allocate(); 474 //allocate();
475 475
476 stim::envi_header h; 476 stim::envi_header h;
477 - h.load(headername); 477 + if (!h.load(headername)) {
  478 + std::cout << "Error loading header file: " << headername << std::endl;
  479 + return false;
  480 + }
478 481
479 //load the header 482 //load the header
480 //header.load(headername); 483 //header.load(headername);
481 484
482 - return open(filename, h); 485 + return open(filename, h, io);
483 } 486 }
484 487
485 /// Normalize a hyperspectral ENVI file given a band number and threshold. 488 /// Normalize a hyperspectral ENVI file given a band number and threshold.