Skip to content

Commit 18a9032

Browse files
author
Carsten Griwodz
committed
[popsift] test whether image fits into CUDA textures
1 parent 149de05 commit 18a9032

5 files changed

Lines changed: 469 additions & 17 deletions

File tree

src/popsift/common/debug_macros.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,14 @@ class BriefDuration
138138
std::cerr << __FILE__ << ":" << __LINE__ << std::endl << " " << s << std::endl; \
139139
}
140140

141+
#define POP_WARN(s) { \
142+
std::cerr << __FILE__ << ":" << __LINE__ << std::endl; \
143+
std::cerr << " WARNING: " << s << std::endl; \
144+
}
145+
#define POP_CUDA_WARN(err,s) { \
146+
std::cerr << __FILE__ << ":" << __LINE__ << std::endl; \
147+
std::cerr << " WARNING: " << s << cudaGetErrorString(err) << std::endl; \
148+
}
141149
#define POP_CUDA_FATAL(err,s) { \
142150
std::cerr << __FILE__ << ":" << __LINE__ << std::endl; \
143151
std::cerr << " " << s << cudaGetErrorString(err) << std::endl; \

src/popsift/common/device_prop.cu

Lines changed: 226 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,24 @@ using namespace std;
1717

1818
device_prop_t::device_prop_t( )
1919
{
20+
int currentDevice;
2021
cudaError_t err;
2122

23+
err = cudaGetDevice( &currentDevice );
24+
POP_CUDA_FATAL_TEST( err, "Cannot get the current CUDA device" );
25+
2226
err = cudaGetDeviceCount( &_num_devices );
2327
POP_CUDA_FATAL_TEST( err, "Cannot count devices" );
2428

29+
_properties.resize(_num_devices);
30+
2531
for( int n=0; n<_num_devices; n++ ) {
26-
cudaDeviceProp* p;
27-
_properties.push_back( p = new cudaDeviceProp );
28-
err = cudaGetDeviceProperties( p, n );
32+
_properties[n] = new cudaDeviceProp;
33+
err = cudaGetDeviceProperties( _properties[n], n );
2934
POP_CUDA_FATAL_TEST( err, "Cannot get properties for a device" );
3035
}
31-
err = cudaSetDevice( 0 );
36+
37+
err = cudaSetDevice( currentDevice );
3238
POP_CUDA_FATAL_TEST( err, "Cannot set device 0" );
3339
}
3440

@@ -86,5 +92,221 @@ device_prop_t::~device_prop_t( )
8692
}
8793
}
8894

95+
bool device_prop_t::checkLimit_2DtexLinear( int& width, int& height, bool printWarn ) const
96+
{
97+
bool returnSuccess = true;
98+
int currentDevice;
99+
cudaError_t err;
100+
101+
err = cudaGetDevice( &currentDevice );
102+
if( err != cudaSuccess )
103+
{
104+
POP_CUDA_WARN( err, "Cannot get current CUDA device" );
105+
return true;
106+
}
107+
108+
if( currentDevice >= _properties.size() )
109+
{
110+
POP_WARN( "CUDA device was not registered at program start" );
111+
return true;
112+
}
113+
114+
const cudaDeviceProp* ptr = _properties[currentDevice];
115+
if( width > ptr->maxTexture2DLayered[0] )
116+
{
117+
if( printWarn )
118+
{
119+
std::cerr << __FILE__ << ":" << __LINE__
120+
<< ": CUDA device " << currentDevice << std::endl
121+
<< " does not support 2D linear textures " << width
122+
<< " pixels wide." << endl;
123+
}
124+
width = ptr->maxTexture2DLayered[0];
125+
returnSuccess = false;
126+
}
127+
if( height > ptr->maxTexture2DLayered[1] )
128+
{
129+
if( returnSuccess && printWarn )
130+
{
131+
std::cerr << __FILE__ << ":" << __LINE__
132+
<< ": CUDA device " << currentDevice << std::endl
133+
<< " does not support 2D linear textures " << height
134+
<< " pixels high." << endl;
135+
}
136+
height = ptr->maxTexture2DLayered[1];
137+
returnSuccess = false;
138+
}
139+
140+
return returnSuccess;
141+
}
142+
143+
bool device_prop_t::checkLimit_2DtexArray( int& width, int& height, bool printWarn ) const
144+
{
145+
bool returnSuccess = true;
146+
int currentDevice;
147+
cudaError_t err;
148+
149+
err = cudaGetDevice( &currentDevice );
150+
if( err != cudaSuccess )
151+
{
152+
POP_CUDA_WARN( err, "Cannot get current CUDA device" );
153+
return true;
154+
}
155+
156+
if( currentDevice >= _properties.size() )
157+
{
158+
POP_WARN( "CUDA device was not registered at program start" );
159+
return true;
160+
}
161+
162+
const cudaDeviceProp* ptr = _properties[currentDevice];
163+
if( width > ptr->maxTexture2D[0] )
164+
{
165+
if( printWarn )
166+
{
167+
std::cerr << __FILE__ << ":" << __LINE__
168+
<< ": CUDA device " << currentDevice << std::endl
169+
<< " does not support 2D array textures " << width
170+
<< " pixels wide." << endl;
171+
}
172+
width = ptr->maxTexture2D[0];
173+
returnSuccess = false;
174+
}
175+
if( height > ptr->maxTexture2D[1] )
176+
{
177+
if( returnSuccess && printWarn )
178+
{
179+
std::cerr << __FILE__ << ":" << __LINE__
180+
<< ": CUDA device " << currentDevice << std::endl
181+
<< " does not support 2D array textures " << height
182+
<< " pixels high." << endl;
183+
}
184+
height = ptr->maxTexture2D[1];
185+
returnSuccess = false;
186+
}
187+
188+
return returnSuccess;
189+
}
190+
191+
bool device_prop_t::checkLimit_2DtexLayered( int& width, int& height, int& layers, bool printWarn ) const
192+
{
193+
bool returnSuccess = true;
194+
int currentDevice;
195+
cudaError_t err;
196+
197+
err = cudaGetDevice( &currentDevice );
198+
if( err != cudaSuccess )
199+
{
200+
POP_CUDA_WARN( err, "Cannot get current CUDA device" );
201+
return true;
202+
}
203+
204+
if( currentDevice >= _properties.size() )
205+
{
206+
POP_WARN( "CUDA device was not registered at program start" );
207+
return true;
208+
}
209+
210+
const cudaDeviceProp* ptr = _properties[currentDevice];
211+
if( width > ptr->maxTexture2DLayered[0] )
212+
{
213+
if( printWarn )
214+
{
215+
std::cerr << __FILE__ << ":" << __LINE__
216+
<< ": CUDA device " << currentDevice << std::endl
217+
<< " does not support 2D array textures " << width
218+
<< " pixels wide." << endl;
219+
}
220+
width = ptr->maxTexture2DLayered[0];
221+
returnSuccess = false;
222+
}
223+
if( height > ptr->maxTexture2DLayered[1] )
224+
{
225+
if( returnSuccess && printWarn )
226+
{
227+
std::cerr << __FILE__ << ":" << __LINE__
228+
<< ": CUDA device " << currentDevice << std::endl
229+
<< " does not support 2D array textures " << height
230+
<< " pixels high." << endl;
231+
}
232+
height = ptr->maxTexture2DLayered[1];
233+
returnSuccess = false;
234+
}
235+
if( layers > ptr->maxTexture2DLayered[2] )
236+
{
237+
if( returnSuccess && printWarn )
238+
{
239+
std::cerr << __FILE__ << ":" << __LINE__
240+
<< ": CUDA device " << currentDevice << std::endl
241+
<< " does not support 2D array textures " << layers
242+
<< " pixels deep." << endl;
243+
}
244+
layers = ptr->maxTexture2DLayered[2];
245+
returnSuccess = false;
246+
}
247+
248+
return returnSuccess;
249+
}
250+
251+
bool device_prop_t::checkLimit_2DsurfLayered( int& width, int& height, int& layers, bool printWarn ) const
252+
{
253+
bool returnSuccess = true;
254+
int currentDevice;
255+
cudaError_t err;
256+
257+
err = cudaGetDevice( &currentDevice );
258+
if( err != cudaSuccess )
259+
{
260+
POP_CUDA_WARN( err, "Cannot get current CUDA device" );
261+
return true;
262+
}
263+
264+
if( currentDevice >= _properties.size() )
265+
{
266+
POP_WARN( "CUDA device was not registered at program start" );
267+
return true;
268+
}
269+
270+
const cudaDeviceProp* ptr = _properties[currentDevice];
271+
if( width > ptr->maxSurface2DLayered[0] )
272+
{
273+
if( printWarn )
274+
{
275+
std::cerr << __FILE__ << ":" << __LINE__
276+
<< ": CUDA device " << currentDevice << std::endl
277+
<< " does not support layered 2D surfaces " << width
278+
<< " bytes wide." << endl;
279+
}
280+
width = ptr->maxSurface2DLayered[0];
281+
returnSuccess = false;
282+
}
283+
if( height > ptr->maxSurface2DLayered[1] )
284+
{
285+
if( returnSuccess && printWarn )
286+
{
287+
std::cerr << __FILE__ << ":" << __LINE__
288+
<< ": CUDA device " << currentDevice << std::endl
289+
<< " does not support layered 2D surfaces " << height
290+
<< " pixels high." << endl;
291+
}
292+
height = ptr->maxSurface2DLayered[1];
293+
returnSuccess = false;
294+
}
295+
if( layers > ptr->maxSurface2DLayered[2] )
296+
{
297+
if( returnSuccess && printWarn )
298+
{
299+
std::cerr << __FILE__ << ":" << __LINE__
300+
<< ": CUDA device " << currentDevice << std::endl
301+
<< " does not support layered 2D surfaces " << layers
302+
<< " pixels deep." << endl;
303+
}
304+
layers = ptr->maxSurface2DLayered[2];
305+
returnSuccess = false;
306+
}
307+
308+
return returnSuccess;
309+
}
310+
89311
}}
90312

src/popsift/common/device_prop.h

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,78 @@ class device_prop_t
1616
{
1717
int _num_devices;
1818
std::vector<cudaDeviceProp*> _properties;
19+
20+
public:
21+
enum {
22+
do_warn = true,
23+
dont_warn = false
24+
};
25+
1926
public:
2027
device_prop_t( );
2128
~device_prop_t( );
2229

2330
void print( );
2431
void set( int n, bool print_choice = false );
32+
33+
/** Check if a request exceeds the current CUDA device's limit in
34+
* texture2Dlinear dimensions. texture2Dlinear is based on CUDA memory that
35+
* can be accessed directly (i.e. no CudaArray).
36+
* @param[in,out] width Desired width of the texture.
37+
* @param[in,out] height Desired height of the texture.
38+
* @param[in] printWarn if true, print warnings to cerr if desired width
39+
* or height exceeds limits.
40+
* @return { true if the desired width and height are possible.
41+
* false if one or both of the desired width and height are impossible.
42+
* The desired width or height (or both) are replaced by the limit.}
43+
*/
44+
bool checkLimit_2DtexLinear( int& width, int& height, bool printWarn ) const;
45+
46+
/** Check if a request exceeds the current CUDA device's limit in
47+
* texture2D dimensions. texture2D is based on CUDA Arrays, which have
48+
* invisible layout and can only be filled with cudaMemcpy.
49+
* @param[in,out] width Desired width of the texture.
50+
* @param[in,out] height Desired height of the texture.
51+
* @param[in] printWarn if true, print warnings to cerr if desired width
52+
* or height exceeds limits.
53+
* @return { true if the desired width and height are possible.
54+
* false if one or both of the desired width and height are impossible.
55+
* The desired width or height (or both) are replaced by the limit.}
56+
*/
57+
bool checkLimit_2DtexArray( int& width, int& height, bool printWarn ) const;
58+
59+
/** Check if a request exceeds the current CUDA device's limit in
60+
* texture2DLayered dimensions. texture2DLayered refers to a 3D structure, where
61+
* interpolation happens only in 3D, effectively creating layers.
62+
* @param[in,out] width Desired width of the texture.
63+
* @param[in,out] height Desired height of the texture.
64+
* @param[in,out] layers Desired depth of the texture.
65+
* @param[in] printWarn if true, print warnings to cerr if desired width
66+
* or height exceeds limits.
67+
* @return { true if the desired width, height and depth are possible.
68+
* false if one or both of the desired width and height are impossible.
69+
* The desired width, height and layers are replaced by the limit
70+
* if they exceed it.}
71+
*/
72+
bool checkLimit_2DtexLayered( int& width, int& height, int& layers,
73+
bool printWarn ) const;
74+
75+
/** Check if a request exceeds the current CUDA device's limit in
76+
* surface2DLayered dimensions. surface2DLayered is the writable equivalent
77+
* to texture2DLayered, but the width must be given in bytes, not elements.
78+
* Since we use float, images cannot be as wide as expected.
79+
* @param[in,out] width Desired width of the texture.
80+
* @param[in,out] height Desired height of the texture.
81+
* @param[in,out] layers Desired depth of the texture.
82+
* @param[in] printWarn if true, print warnings to cerr if desired width
83+
* or height exceeds limits.
84+
* @return { true if the desired width, height and depth are possible.
85+
* false if one or both of the desired width and height are impossible.
86+
* The desired width, height and layers are replaced by the limit
87+
* if they exceed it.}
88+
*/
89+
bool checkLimit_2DsurfLayered( int& width, int& height, int& layers,
90+
bool printWarn ) const;
2591
};
2692

2793
}}

0 commit comments

Comments
 (0)