Skip to content

Commit f872278

Browse files
committed
Replace exit() call with thrown exceptions
Address #139 Previously, exit() function was called when popsift encountered errors (e.g. out of memory). This error handling made graceful error handling within the application using popsift difficult. This commit replaces all the exit() call with throwing a runtime error instead.
1 parent 4c22d41 commit f872278

File tree

9 files changed

+138
-149
lines changed

9 files changed

+138
-149
lines changed

src/popsift/common/debug_macros.cu

Lines changed: 24 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,7 @@ void pop_sync_check_last_error( const char* file, size_t line )
2020
void pop_check_last_error( const char* file, size_t line )
2121
{
2222
cudaError_t err = cudaGetLastError( );
23-
if( err != cudaSuccess ) {
24-
std::cerr << __FILE__ << ":" << __LINE__ << std::endl
25-
<< " called from " << file << ":" << line << std::endl
26-
<< " cudaGetLastError failed: " << cudaGetErrorString(err) << std::endl;
27-
exit( -__LINE__ );
28-
}
23+
POP_CUDA_FATAL_TEST(err, "cudaGetLastError failed: ");
2924
}
3025

3126
namespace popsift { namespace cuda {
@@ -34,11 +29,7 @@ void malloc_dev( void** ptr, int sz,
3429
{
3530
cudaError_t err;
3631
err = cudaMalloc( ptr, sz );
37-
if( err != cudaSuccess ) {
38-
std::cerr << file << ":" << line << std::endl
39-
<< " cudaMalloc failed: " << cudaGetErrorString(err) << std::endl;
40-
exit( -__LINE__ );
41-
}
32+
POP_CUDA_FATAL_TEST(err, "cudaMalloc failed: ");
4233
#ifdef DEBUG_INIT_DEVICE_ALLOCATIONS
4334
popsift::cuda::memset_sync( *ptr, 0, sz, file, line );
4435
#endif // NDEBUG
@@ -51,11 +42,7 @@ void malloc_hst( void** ptr, int sz,
5142
{
5243
cudaError_t err;
5344
err = cudaMallocHost( ptr, sz );
54-
if( err != cudaSuccess ) {
55-
std::cerr << file << ":" << line << std::endl
56-
<< " cudaMallocHost failed: " << cudaGetErrorString(err) << std::endl;
57-
exit( -__LINE__ );
58-
}
45+
POP_CUDA_FATAL_TEST(err, "cudaMallocHost failed: ");
5946
#ifdef DEBUG_INIT_DEVICE_ALLOCATIONS
6047
memset( *ptr, 0, sz );
6148
#endif // NDEBUG
@@ -74,16 +61,13 @@ void memcpy_async( void* dst, const void* src, size_t sz,
7461
cudaError_t err;
7562
err = cudaMemcpyAsync( dst, src, sz, type, stream );
7663
if( err != cudaSuccess ) {
77-
cerr << file << ":" << line << endl
78-
<< " " << "Failed to copy "
79-
<< (type==cudaMemcpyHostToDevice?"host-to-device":"device-to-host")
80-
<< ": ";
81-
cerr << cudaGetErrorString(err) << endl;
82-
cerr << " src ptr=" << hex << (size_t)src << dec << endl
83-
<< " dst ptr=" << hex << (size_t)dst << dec << endl;
84-
exit( -__LINE__ );
64+
std::stringstream ss;
65+
ss << "Failed to copy " << (type == cudaMemcpyHostToDevice ? "host-to-device" : "device-to-host") << ": ";
66+
ss << cudaGetErrorString(err) << endl;
67+
ss << " src ptr=" << hex << (size_t)src << dec << endl
68+
<< " dst ptr=" << hex << (size_t)dst << dec << endl;
69+
POP_FATAL(ss.str());
8570
}
86-
POP_CUDA_FATAL_TEST( err, "Failed to copy host-to-device: " );
8771
}
8872

8973
void memcpy_sync( void* dst, const void* src, size_t sz, cudaMemcpyKind type, const char* file, size_t line )
@@ -95,37 +79,27 @@ void memcpy_sync( void* dst, const void* src, size_t sz, cudaMemcpyKind type, co
9579
cudaError_t err;
9680
err = cudaMemcpy( dst, src, sz, type );
9781
if( err != cudaSuccess ) {
98-
cerr << " " << "Failed to copy "
99-
<< (type==cudaMemcpyHostToDevice?"host-to-device":"device-to-host")
100-
<< ": ";
101-
cerr << cudaGetErrorString(err) << endl;
102-
cerr << " src ptr=" << hex << (size_t)src << dec << endl
103-
<< " dst ptr=" << hex << (size_t)dst << dec << endl;
104-
exit( -__LINE__ );
82+
std::stringstream ss;
83+
ss << "Failed to copy " << (type == cudaMemcpyHostToDevice ? "host-to-device" : "device-to-host") << ": ";
84+
ss << cudaGetErrorString(err) << endl;
85+
ss << " src ptr=" << hex << (size_t)src << dec << endl
86+
<< " dst ptr=" << hex << (size_t)dst << dec << endl;
87+
POP_FATAL(ss.str())
10588
}
106-
POP_CUDA_FATAL_TEST( err, "Failed to copy host-to-device: " );
10789
}
10890

10991
void memset_async( void* ptr, int value, size_t bytes, cudaStream_t stream, const char* file, size_t line )
11092
{
11193
cudaError_t err;
11294
err = cudaMemsetAsync( ptr, value, bytes, stream );
113-
if( err != cudaSuccess ) {
114-
std::cerr << file << ":" << line << std::endl
115-
<< " cudaMemsetAsync failed: " << cudaGetErrorString(err) << std::endl;
116-
exit( -__LINE__ );
117-
}
95+
POP_CUDA_FATAL_TEST(err, "cudaMemsetAsync failed: ");
11896
}
11997

12098
void memset_sync( void* ptr, int value, size_t bytes, const char* file, size_t line )
12199
{
122100
cudaError_t err;
123101
err = cudaMemset( ptr, value, bytes );
124-
if( err != cudaSuccess ) {
125-
std::cerr << file << ":" << line << std::endl
126-
<< " cudaMemset failed: " << cudaGetErrorString(err) << std::endl;
127-
exit( -__LINE__ );
128-
}
102+
POP_CUDA_FATAL_TEST(err, "cudaMemset failed: ");
129103
}
130104
} }
131105

@@ -135,68 +109,44 @@ cudaStream_t stream_create( const char* file, size_t line )
135109
cudaStream_t stream;
136110
cudaError_t err;
137111
err = cudaStreamCreate( &stream );
138-
if( err != cudaSuccess ) {
139-
std::cerr << file << ":" << line << std::endl
140-
<< " cudaStreamCreate failed: " << cudaGetErrorString(err) << std::endl;
141-
exit( -__LINE__ );
142-
}
112+
POP_CUDA_FATAL_TEST(err, "cudaStreamCreate failed: ");
143113
return stream;
144114
}
145115
void stream_destroy( cudaStream_t s, const char* file, size_t line )
146116
{
147117
cudaError_t err;
148118
err = cudaStreamDestroy( s );
149-
if( err != cudaSuccess ) {
150-
std::cerr << file << ":" << line << std::endl
151-
<< " cudaStreamDestroy failed: " << cudaGetErrorString(err) << std::endl;
152-
exit( -__LINE__ );
153-
}
119+
POP_CUDA_FATAL_TEST(err, "cudaStreamDestroy failed: ");
154120
}
155121
cudaEvent_t event_create( const char* file, size_t line )
156122
{
157123
cudaEvent_t ev;
158124
cudaError_t err;
159125
err = cudaEventCreate( &ev );
160-
if( err != cudaSuccess ) {
161-
std::cerr << file << ":" << line << std::endl
162-
<< " cudaEventCreate failed: " << cudaGetErrorString(err) << std::endl;
163-
exit( -__LINE__ );
164-
}
126+
POP_CUDA_FATAL_TEST(err, "cudaEventCreate failed: ");
165127
return ev;
166128
}
167129
void event_destroy( cudaEvent_t ev, const char* file, size_t line )
168130
{
169131
cudaError_t err;
170132
err = cudaEventDestroy( ev );
171-
if( err != cudaSuccess ) {
172-
std::cerr << file << ":" << line << std::endl
173-
<< " cudaEventDestroy failed: " << cudaGetErrorString(err) << std::endl;
174-
exit( -__LINE__ );
175-
}
133+
POP_CUDA_FATAL_TEST(err, "cudaEventDestroy failed: ");
176134
}
177135
void event_record( cudaEvent_t ev, cudaStream_t s, const char* file, size_t line )
178136
{
179137
cudaError_t err;
180138
err = cudaEventRecord( ev, s );
181-
if( err != cudaSuccess ) {
182-
std::cerr << file << ":" << line << std::endl
183-
<< " cudaEventRecord failed: " << cudaGetErrorString(err) << std::endl;
184-
exit( -__LINE__ );
185-
}
139+
POP_CUDA_FATAL_TEST(err, "cudaEventRecord failed: ");
186140
}
187141
void event_wait( cudaEvent_t ev, cudaStream_t s, const char* file, size_t line )
188142
{
189143
cudaError_t err;
190144
err = cudaStreamWaitEvent( s, ev, 0 );
191-
if( err != cudaSuccess ) {
192-
std::cerr << file << ":" << line << std::endl
193-
<< " cudaStreamWaitEvent failed: " << cudaGetErrorString(err) << std::endl;
194-
exit( -__LINE__ );
195-
}
145+
POP_CUDA_FATAL_TEST(err, "cudaStreamWaitEvent failed: ");
196146
}
197147

198148
float event_diff( cudaEvent_t from, cudaEvent_t to )
199-
{
149+
{
200150
float ms;
201151
cudaEventElapsedTime( &ms, from, to );
202152
return ms;

src/popsift/common/debug_macros.h

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <cstdlib>
1414
#include <iomanip>
1515
#include <iostream>
16+
#include <stdexcept>
1617
#include <string>
1718

1819
// synchronize device and check for an error
@@ -117,14 +118,18 @@ class BriefDuration
117118
};
118119
};
119120

120-
#define POP_FATAL(s) { \
121-
std::cerr << __FILE__ << ":" << __LINE__ << std::endl << " " << s << std::endl; \
122-
exit( -__LINE__ ); \
121+
#define POP_FATAL(s) \
122+
{ \
123+
std::stringstream ss; \
124+
ss << __FILE__ << ":" << __LINE__ << std::endl << " " << s; \
125+
throw std::runtime_error{ss.str()}; \
123126
}
124127

125-
#define POP_FATAL_FL(s,file,line) { \
126-
std::cerr << file << ":" << line << std::endl << " " << s << std::endl; \
127-
exit( -__LINE__ ); \
128+
#define POP_FATAL_FL(s, file, line) \
129+
{ \
130+
std::stringstream ss; \
131+
ss << file << ":" << line << std::endl << " " << s << std::endl; \
132+
throw std::runtime_error{ss.str()}; \
128133
}
129134

130135
#define POP_CHECK_NON_NULL(ptr,s) if( ptr == 0 ) { POP_FATAL_FL(s,__FILE__,__LINE__); }
@@ -147,10 +152,12 @@ class BriefDuration
147152
std::cerr << __FILE__ << ":" << __LINE__ << std::endl; \
148153
std::cerr << " WARNING: " << s << cudaGetErrorString(err) << std::endl; \
149154
}
150-
#define POP_CUDA_FATAL(err,s) { \
151-
std::cerr << __FILE__ << ":" << __LINE__ << std::endl; \
152-
std::cerr << " " << s << cudaGetErrorString(err) << std::endl; \
153-
exit( -__LINE__ ); \
155+
#define POP_CUDA_FATAL(err,s) \
156+
{ \
157+
std::stringstream ss; \
158+
ss << __FILE__ << ":" << __LINE__ << std::endl; \
159+
ss << " " << s << cudaGetErrorString(err) << std::endl; \
160+
throw std::runtime_error{ss.str()}; \
154161
}
155162
#define POP_CUDA_FATAL_TEST(err,s) if( err != cudaSuccess ) { POP_CUDA_FATAL(err,s); }
156163

src/popsift/common/plane_2d.cu

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <cstdlib>
1616
#include <cstring>
1717
#include <iostream>
18+
#include <sstream>
1819
#ifndef _WIN32
1920
#include <unistd.h>
2021
#else
@@ -65,11 +66,11 @@ void* PlaneBase::allocHost2D( int w, int h, int elemSize, PlaneMapMode m )
6566
#else
6667
const char *buf = strerror(errno);
6768
#endif
68-
cerr << __FILE__ << ":" << __LINE__ << endl
69-
<< " Failed to allocate " << sz << " bytes of unaligned host memory." << endl
70-
<< " Cause: " << buf << endl;
71-
exit( -1 );
72-
} else if( m == PageAligned ) {
69+
stringstream ss;
70+
ss << "Failed to allocate " << sz << " bytes of unaligned host memory." << endl
71+
<< "Cause: " << buf;
72+
POP_FATAL(ss.str());
73+
} else if(m == PageAligned) {
7374
void* ptr = memalign(getPageSize(), sz);
7475
if(ptr)
7576
return ptr;
@@ -93,9 +94,7 @@ void* PlaneBase::allocHost2D( int w, int h, int elemSize, PlaneMapMode m )
9394
POP_CUDA_FATAL_TEST( err, "Failed to allocate aligned and pinned host memory: " );
9495
return ptr;
9596
} else {
96-
cerr << __FILE__ << ":" << __LINE__ << endl
97-
<< " Alignment not correctly specified in host plane allocation" << endl;
98-
exit( -1 );
97+
POP_FATAL("Alignment not correctly specified in host plane allocation");
9998
}
10099
}
101100

src/popsift/common/plane_2d.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
#include <sstream>
1717
#include <stdexcept>
1818

19+
#include "debug_macros.h"
20+
1921
#define PLANE2D_CUDA_OP_DEBUG
2022

2123
#ifndef NDEBUG
@@ -407,14 +409,16 @@ __host__
407409
inline void Plane2D<T>::memcpyToDevice( Plane2D<T>& devPlane, cudaStream_t stream )
408410
{
409411
if( devPlane._cols != this->_cols ) {
410-
std::cerr << __FILE__ << ":" << __LINE__ << std::endl
411-
<< " Error: source columns (" << this->_cols << ") and dest columns (" << devPlane._cols << ") must be identical" << std::endl;
412-
exit( -1 );
412+
std::stringstream ss;
413+
ss << "Error: source columns (" << this->_cols << ") and dest columns (" << devPlane._cols
414+
<< ") must be identical";
415+
POP_FATAL(ss.str());
413416
}
414417
if( devPlane._rows != this->_rows ) {
415-
std::cerr << __FILE__ << ":" << __LINE__ << std::endl
416-
<< " Error: source rows (" << this->_rows << ") and dest rows (" << devPlane._rows << ") must be identical" << std::endl;
417-
exit( -1 );
418+
std::stringstream ss;
419+
ss << "Error: source rows (" << this->_rows << ") and dest rows (" << devPlane._rows
420+
<< ") must be identical";
421+
POP_FATAL(ss.str());
418422
}
419423
PitchPlane2D<T>::memcpyToDevice( devPlane, this->_cols, this->_rows, stream );
420424
}

src/popsift/features.cu

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <cstdlib>
1717
#include <iomanip>
1818
#include <iostream>
19+
#include <sstream>
1920

2021
using namespace std;
2122

@@ -61,19 +62,21 @@ void FeaturesHost::reset( int num_ext, int num_ori )
6162

6263
_ext = (Feature*)memalign( getPageSize(), num_ext * sizeof(Feature) );
6364
if( _ext == nullptr ) {
64-
cerr << __FILE__ << ":" << __LINE__ << " Runtime error:" << endl
65-
<< " Failed to (re)allocate memory for downloading " << num_ext << " features" << endl;
66-
if( errno == EINVAL ) cerr << " Alignment is not a power of two." << endl;
67-
if( errno == ENOMEM ) cerr << " Not enough memory." << endl;
68-
exit( -1 );
65+
std::stringstream ss;
66+
ss << "Runtime error:" << endl
67+
<< " Failed to (re)allocate memory for downloading " << num_ext << " features" << endl;
68+
if(errno == EINVAL) ss << " Alignment is not a power of two.";
69+
if(errno == ENOMEM) ss << " Not enough memory.";
70+
POP_FATAL(ss.str());
6971
}
7072
_ori = (Descriptor*)memalign( getPageSize(), num_ori * sizeof(Descriptor) );
71-
if( _ori == nullptr ) {
72-
cerr << __FILE__ << ":" << __LINE__ << " Runtime error:" << endl
73-
<< " Failed to (re)allocate memory for downloading " << num_ori << " descriptors" << endl;
74-
if( errno == EINVAL ) cerr << " Alignment is not a power of two." << endl;
75-
if( errno == ENOMEM ) cerr << " Not enough memory." << endl;
76-
exit( -1 );
73+
if(_ori == nullptr) {
74+
std::stringstream ss;
75+
ss << "Runtime error:" << endl
76+
<< " Failed to (re)allocate memory for downloading " << num_ori << " descriptors" << endl;
77+
if(errno == EINVAL) ss << " Alignment is not a power of two.";
78+
if(errno == ENOMEM) ss << " Not enough memory.";
79+
POP_FATAL(ss.str());
7780
}
7881

7982
setFeatureCount( num_ext );

src/popsift/gauss_filter.cu

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -130,17 +130,17 @@ void init_filter( const Config& conf,
130130
{
131131
if( sigma0 > 2.0 )
132132
{
133-
cerr << __FILE__ << ":" << __LINE__ << ", ERROR: "
134-
<< " Sigma > 2.0 is not supported. Re-size __constant__ array and recompile."
135-
<< endl;
136-
exit( -__LINE__ );
133+
stringstream ss;
134+
ss << "ERROR: "
135+
<< " Sigma > 2.0 is not supported. Re-size __constant__ array and recompile.";
136+
POP_FATAL(ss.str());
137137
}
138138
if( levels > GAUSS_LEVELS )
139139
{
140-
cerr << __FILE__ << ":" << __LINE__ << ", ERROR: "
141-
<< " More than " << GAUSS_LEVELS << " levels not supported. Re-size __constant__ array and recompile."
142-
<< endl;
143-
exit( -__LINE__ );
140+
stringstream ss;
141+
ss << "ERROR: "
142+
<< " More than " << GAUSS_LEVELS << " levels not supported. Re-size __constant__ array and recompile.";
143+
POP_FATAL(ss.str());
144144
}
145145

146146
if( conf.ifPrintGaussTables() ) {
@@ -291,10 +291,9 @@ int GaussInfo::getSpan( float sigma ) const
291291
case Config::Fixed15 :
292292
return 8;
293293
default :
294-
cerr << __FILE__ << ":" << __LINE__ << ", ERROR: "
295-
<< " The mode for computing Gauss filter scan is invalid"
296-
<< endl;
297-
exit( -__LINE__ );
294+
stringstream ss;
295+
ss << "ERROR: The mode for computing Gauss filter scan is invalid";
296+
POP_FATAL(ss.str());
298297
}
299298
}
300299

0 commit comments

Comments
 (0)