Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/popsift/common/debug_macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,14 @@ class BriefDuration
std::cerr << __FILE__ << ":" << __LINE__ << std::endl << " " << s << std::endl; \
}

#define POP_WARN(s) { \
std::cerr << __FILE__ << ":" << __LINE__ << std::endl; \
std::cerr << " WARNING: " << s << std::endl; \
}
#define POP_CUDA_WARN(err,s) { \
std::cerr << __FILE__ << ":" << __LINE__ << std::endl; \
std::cerr << " WARNING: " << s << cudaGetErrorString(err) << std::endl; \
}
#define POP_CUDA_FATAL(err,s) { \
std::cerr << __FILE__ << ":" << __LINE__ << std::endl; \
std::cerr << " " << s << cudaGetErrorString(err) << std::endl; \
Expand Down
232 changes: 227 additions & 5 deletions src/popsift/common/device_prop.cu
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,24 @@ using namespace std;

device_prop_t::device_prop_t( )
{
int currentDevice;
cudaError_t err;

err = cudaGetDevice( &currentDevice );
POP_CUDA_FATAL_TEST( err, "Cannot get the current CUDA device" );

err = cudaGetDeviceCount( &_num_devices );
POP_CUDA_FATAL_TEST( err, "Cannot count devices" );

for( int n=0; n<_num_devices; n++ ) {
cudaDeviceProp* p;
_properties.push_back( p = new cudaDeviceProp );
err = cudaGetDeviceProperties( p, n );
_properties.resize(_num_devices);

for( int n=0; n<_num_devices; ++n ) {
_properties[n] = new cudaDeviceProp;
err = cudaGetDeviceProperties( _properties[n], n );
POP_CUDA_FATAL_TEST( err, "Cannot get properties for a device" );
}
err = cudaSetDevice( 0 );

err = cudaSetDevice( currentDevice );
POP_CUDA_FATAL_TEST( err, "Cannot set device 0" );
}

Expand Down Expand Up @@ -86,5 +92,221 @@ device_prop_t::~device_prop_t( )
}
}

bool device_prop_t::checkLimit_2DtexLinear( int& width, int& height, bool printWarn ) const
{
bool returnSuccess = true;
int currentDevice;
cudaError_t err;

err = cudaGetDevice( &currentDevice );
if( err != cudaSuccess )
{
POP_CUDA_WARN( err, "Cannot get current CUDA device" );
return true;
}

if( currentDevice >= _properties.size() )
{
POP_WARN( "CUDA device was not registered at program start" );
return true;
}

const cudaDeviceProp* ptr = _properties[currentDevice];
if( width > ptr->maxTexture2DLayered[0] )
{
if( printWarn )
{
std::cerr << __FILE__ << ":" << __LINE__
<< ": CUDA device " << currentDevice << std::endl
<< " does not support 2D linear textures " << width
<< " pixels wide." << endl;
}
width = ptr->maxTexture2DLayered[0];
returnSuccess = false;
}
if( height > ptr->maxTexture2DLayered[1] )
{
if( returnSuccess && printWarn )
{
std::cerr << __FILE__ << ":" << __LINE__
<< ": CUDA device " << currentDevice << std::endl
<< " does not support 2D linear textures " << height
<< " pixels high." << endl;
}
height = ptr->maxTexture2DLayered[1];
returnSuccess = false;
}

return returnSuccess;
}

bool device_prop_t::checkLimit_2DtexArray( int& width, int& height, bool printWarn ) const
{
bool returnSuccess = true;
int currentDevice;
cudaError_t err;

err = cudaGetDevice( &currentDevice );
if( err != cudaSuccess )
{
POP_CUDA_WARN( err, "Cannot get current CUDA device" );
return true;
}

if( currentDevice >= _properties.size() )
{
POP_WARN( "CUDA device was not registered at program start" );
return true;
}

const cudaDeviceProp* ptr = _properties[currentDevice];
if( width > ptr->maxTexture2D[0] )
{
if( printWarn )
{
std::cerr << __FILE__ << ":" << __LINE__
<< ": CUDA device " << currentDevice << std::endl
<< " does not support 2D array textures " << width
<< " pixels wide." << endl;
}
width = ptr->maxTexture2D[0];
returnSuccess = false;
}
if( height > ptr->maxTexture2D[1] )
{
if( returnSuccess && printWarn )
{
std::cerr << __FILE__ << ":" << __LINE__
<< ": CUDA device " << currentDevice << std::endl
<< " does not support 2D array textures " << height
<< " pixels high." << endl;
}
height = ptr->maxTexture2D[1];
returnSuccess = false;
}

return returnSuccess;
}

bool device_prop_t::checkLimit_2DtexLayered( int& width, int& height, int& layers, bool printWarn ) const
{
bool returnSuccess = true;
int currentDevice;
cudaError_t err;

err = cudaGetDevice( &currentDevice );
if( err != cudaSuccess )
{
POP_CUDA_WARN( err, "Cannot get current CUDA device" );
return true;
}

if( currentDevice >= _properties.size() )
{
POP_WARN( "CUDA device was not registered at program start" );
return true;
}

const cudaDeviceProp* ptr = _properties[currentDevice];
if( width > ptr->maxTexture2DLayered[0] )
{
if( printWarn )
{
std::cerr << __FILE__ << ":" << __LINE__
<< ": CUDA device " << currentDevice << std::endl
<< " does not support 2D array textures " << width
<< " pixels wide." << endl;
}
width = ptr->maxTexture2DLayered[0];
returnSuccess = false;
}
if( height > ptr->maxTexture2DLayered[1] )
{
if( returnSuccess && printWarn )
{
std::cerr << __FILE__ << ":" << __LINE__
<< ": CUDA device " << currentDevice << std::endl
<< " does not support 2D array textures " << height
<< " pixels high." << endl;
}
height = ptr->maxTexture2DLayered[1];
returnSuccess = false;
}
if( layers > ptr->maxTexture2DLayered[2] )
{
if( returnSuccess && printWarn )
{
std::cerr << __FILE__ << ":" << __LINE__
<< ": CUDA device " << currentDevice << std::endl
<< " does not support 2D array textures " << layers
<< " pixels deep." << endl;
}
layers = ptr->maxTexture2DLayered[2];
returnSuccess = false;
}

return returnSuccess;
}

bool device_prop_t::checkLimit_2DsurfLayered( int& width, int& height, int& layers, bool printWarn ) const
{
bool returnSuccess = true;
int currentDevice;
cudaError_t err;

err = cudaGetDevice( &currentDevice );
if( err != cudaSuccess )
{
POP_CUDA_WARN( err, "Cannot get current CUDA device" );
return true;
}

if( currentDevice >= _properties.size() )
{
POP_WARN( "CUDA device was not registered at program start" );
return true;
}

const cudaDeviceProp* ptr = _properties[currentDevice];
if( width > ptr->maxSurface2DLayered[0] )
{
if( printWarn )
{
std::cerr << __FILE__ << ":" << __LINE__
<< ": CUDA device " << currentDevice << std::endl
<< " does not support layered 2D surfaces " << width
<< " bytes wide." << endl;
}
width = ptr->maxSurface2DLayered[0];
returnSuccess = false;
}
if( height > ptr->maxSurface2DLayered[1] )
{
if( returnSuccess && printWarn )
{
std::cerr << __FILE__ << ":" << __LINE__
<< ": CUDA device " << currentDevice << std::endl
<< " does not support layered 2D surfaces " << height
<< " pixels high." << endl;
}
height = ptr->maxSurface2DLayered[1];
returnSuccess = false;
}
if( layers > ptr->maxSurface2DLayered[2] )
{
if( returnSuccess && printWarn )
{
std::cerr << __FILE__ << ":" << __LINE__
<< ": CUDA device " << currentDevice << std::endl
<< " does not support layered 2D surfaces " << layers
<< " pixels deep." << endl;
}
layers = ptr->maxSurface2DLayered[2];
returnSuccess = false;
}

return returnSuccess;
}

}}

66 changes: 66 additions & 0 deletions src/popsift/common/device_prop.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,78 @@ class device_prop_t
{
int _num_devices;
std::vector<cudaDeviceProp*> _properties;

public:
enum {
do_warn = true,
dont_warn = false
};

public:
device_prop_t( );
~device_prop_t( );

void print( );
void set( int n, bool print_choice = false );

/** Check if a request exceeds the current CUDA device's limit in
* texture2Dlinear dimensions. texture2Dlinear is based on CUDA memory that
* can be accessed directly (i.e. no CudaArray).
* @param[in,out] width Desired width of the texture.
* @param[in,out] height Desired height of the texture.
* @param[in] printWarn if true, print warnings to cerr if desired width
* or height exceeds limits.
* @return { true if the desired width and height are possible.
* false if one or both of the desired width and height are impossible.
* The desired width or height (or both) are replaced by the limit.}
*/
bool checkLimit_2DtexLinear( int& width, int& height, bool printWarn ) const;

/** Check if a request exceeds the current CUDA device's limit in
* texture2D dimensions. texture2D is based on CUDA Arrays, which have
* invisible layout and can only be filled with cudaMemcpy.
* @param[in,out] width Desired width of the texture.
* @param[in,out] height Desired height of the texture.
* @param[in] printWarn if true, print warnings to cerr if desired width
* or height exceeds limits.
* @return { true if the desired width and height are possible.
* false if one or both of the desired width and height are impossible.
* The desired width or height (or both) are replaced by the limit.}
*/
bool checkLimit_2DtexArray( int& width, int& height, bool printWarn ) const;

/** Check if a request exceeds the current CUDA device's limit in
* texture2DLayered dimensions. texture2DLayered refers to a 3D structure, where
* interpolation happens only in 3D, effectively creating layers.
* @param[in,out] width Desired width of the texture.
* @param[in,out] height Desired height of the texture.
* @param[in,out] layers Desired depth of the texture.
* @param[in] printWarn if true, print warnings to cerr if desired width
* or height exceeds limits.
* @return { true if the desired width, height and depth are possible.
* false if one or both of the desired width and height are impossible.
* The desired width, height and layers are replaced by the limit
* if they exceed it.}
*/
bool checkLimit_2DtexLayered( int& width, int& height, int& layers,
bool printWarn ) const;

/** Check if a request exceeds the current CUDA device's limit in
* surface2DLayered dimensions. surface2DLayered is the writable equivalent
* to texture2DLayered, but the width must be given in bytes, not elements.
* Since we use float, images cannot be as wide as expected.
* @param[in,out] width Desired width of the texture.
* @param[in,out] height Desired height of the texture.
* @param[in,out] layers Desired depth of the texture.
* @param[in] printWarn if true, print warnings to cerr if desired width
* or height exceeds limits.
* @return { true if the desired width, height and depth are possible.
* false if one or both of the desired width and height are impossible.
* The desired width, height and layers are replaced by the limit
* if they exceed it.}
*/
bool checkLimit_2DsurfLayered( int& width, int& height, int& layers,
bool printWarn ) const;
};

}}
Expand Down
Loading