Skip to content

Commit

Permalink
Driver: Better architecture checking
Browse files Browse the repository at this point in the history
  • Loading branch information
ptillet committed Jan 26, 2017
1 parent 40715d2 commit 640e1d6
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 115 deletions.
8 changes: 8 additions & 0 deletions include/isaac/exception/driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,14 @@ namespace isaac
namespace exception
{

class ISAACAPI unknown_architecture: public std::exception{
public:
unknown_architecture(std::string const & msg): msg_("Unrecognized architecture: " + msg){}
const char * what() const throw(){ return msg_.c_str(); }
private:
std::string msg_;
};

namespace nvrtc
{

Expand Down
204 changes: 92 additions & 112 deletions lib/driver/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <memory>

#include "isaac/driver/device.h"
#include "isaac/exception/driver.h"
#include "helpers/ocl/infos.hpp"
#include "isaac/tools/sys/cpuid.hpp"

Expand Down Expand Up @@ -72,119 +73,98 @@ Device::Vendor Device::vendor() const

Device::Architecture Device::architecture() const
{
switch(vendor())
{
case Vendor::INTEL:
{
std::string brand = tools::cpu_brand();
size_t idx = brand.find('-');
if(idx!=std::string::npos){
if(brand[idx+1]=='4')
return Architecture::HASWELL;
if(brand[idx+1]=='5')
return Architecture::BROADWELL;
if(brand[idx+1]=='6')
return Architecture::SKYLAKE;
if(brand[idx+1]=='7')
return Architecture::KABYLAKE;
}
return Architecture::UNKNOWN;
}
case Vendor::NVIDIA:
{
std::pair<unsigned int, unsigned int> sm = nv_compute_capability();
switch(sm.first)
{
case 6:
switch(sm.second)
{
case 0: return Architecture::SM_6_0;
case 1: return Architecture::SM_6_1;
}

case 5:
switch(sm.second)
{
case 0: return Architecture::SM_5_0;
case 2: return Architecture::SM_5_2;
default: return Architecture::UNKNOWN;
}

case 3:
switch(sm.second)
{
case 0: return Architecture::SM_3_0;
case 5: return Architecture::SM_3_5;
case 7: return Architecture::SM_3_7;
default: return Architecture::UNKNOWN;
}

case 2:
switch(sm.second)
{
case 0: return Architecture::SM_2_0;
case 1: return Architecture::SM_2_1;
default: return Architecture::UNKNOWN;
}

default: return Architecture::UNKNOWN;
}
}
case Vendor::AMD:
{
//No simple way to query TeraScale/GCN version. Enumerate...
std::string device_name = name();

#define MAP_DEVICE(device,arch)if (device_name.find(device,0)!=std::string::npos) return Architecture::arch;
//TERASCALE 2
MAP_DEVICE("Barts",TERASCALE_2);
MAP_DEVICE("Cedar",TERASCALE_2);
MAP_DEVICE("Redwood",TERASCALE_2);
MAP_DEVICE("Juniper",TERASCALE_2);
MAP_DEVICE("Cypress",TERASCALE_2);
MAP_DEVICE("Hemlock",TERASCALE_2);
MAP_DEVICE("Caicos",TERASCALE_2);
MAP_DEVICE("Turks",TERASCALE_2);
MAP_DEVICE("WinterPark",TERASCALE_2);
MAP_DEVICE("BeaverCreek",TERASCALE_2);

//TERASCALE 3
MAP_DEVICE("Cayman",TERASCALE_3);
MAP_DEVICE("Antilles",TERASCALE_3);
MAP_DEVICE("Scrapper",TERASCALE_3);
MAP_DEVICE("Devastator",TERASCALE_3);

//GCN 1
MAP_DEVICE("Cape",GCN_1);
MAP_DEVICE("Pitcairn",GCN_1);
MAP_DEVICE("Tahiti",GCN_1);
MAP_DEVICE("New Zealand",GCN_1);
MAP_DEVICE("Curacao",GCN_1);
MAP_DEVICE("Malta",GCN_1);

//GCN 2
MAP_DEVICE("Bonaire",GCN_2);
MAP_DEVICE("Hawaii",GCN_2);
MAP_DEVICE("Vesuvius",GCN_2);
MAP_DEVICE("gfx701",GCN_3);

//GCN 3
MAP_DEVICE("Tonga",GCN_3);
MAP_DEVICE("Fiji",GCN_3);
MAP_DEVICE("gfx801",GCN_3);
MAP_DEVICE("gfx802",GCN_3);
MAP_DEVICE("gfx803",GCN_3);

//GCN 4
MAP_DEVICE("Polaris",GCN_4);
#undef MAP_DEVICE

}
default:
{
return Architecture::UNKNOWN;
}
Vendor vdr = vendor();
//Intel
if(vdr==Vendor::INTEL){
std::string brand = tools::cpu_brand();
if(brand.find("Xeon")!=std::string::npos){
if(brand.find("v3")!=std::string::npos)
return Architecture::HASWELL;
if(brand.find("v4")!=std::string::npos)
return Architecture::BROADWELL;
if(brand.find("v5")!=std::string::npos)
return Architecture::SKYLAKE;
if(brand.find("v6")!=std::string::npos)
return Architecture::KABYLAKE;
}
size_t idx = brand.find('-');
if(idx!=std::string::npos){
if(brand[idx+1]=='4')
return Architecture::HASWELL;
if(brand[idx+1]=='5')
return Architecture::BROADWELL;
if(brand[idx+1]=='6')
return Architecture::SKYLAKE;
if(brand[idx+1]=='7')
return Architecture::KABYLAKE;
}
}
//NVidia
if(vdr==Vendor::NVIDIA){
std::pair<unsigned int, unsigned int> sm = nv_compute_capability();
if(sm.first==2 && sm.second==0) return Architecture::SM_2_0;
if(sm.first==2 && sm.second==1) return Architecture::SM_2_1;

if(sm.first==3 && sm.second==0) return Architecture::SM_3_0;
if(sm.first==3 && sm.second==5) return Architecture::SM_3_5;
if(sm.first==3 && sm.second==7) return Architecture::SM_3_7;

if(sm.first==5 && sm.second==0) return Architecture::SM_5_0;
if(sm.first==5 && sm.second==2) return Architecture::SM_5_2;

if(sm.first==6 && sm.second==0) return Architecture::SM_6_0;
if(sm.first==6 && sm.second==1) return Architecture::SM_6_1;
}
//AMD
if(vdr==Vendor::AMD){
//No simple way to query TeraScale/GCN version. Enumerate...
std::string device_name = name();

#define MAP_DEVICE(device,arch)if (device_name.find(device,0)!=std::string::npos) return Architecture::arch;
//TERASCALE 2
MAP_DEVICE("Barts",TERASCALE_2);
MAP_DEVICE("Cedar",TERASCALE_2);
MAP_DEVICE("Redwood",TERASCALE_2);
MAP_DEVICE("Juniper",TERASCALE_2);
MAP_DEVICE("Cypress",TERASCALE_2);
MAP_DEVICE("Hemlock",TERASCALE_2);
MAP_DEVICE("Caicos",TERASCALE_2);
MAP_DEVICE("Turks",TERASCALE_2);
MAP_DEVICE("WinterPark",TERASCALE_2);
MAP_DEVICE("BeaverCreek",TERASCALE_2);

//TERASCALE 3
MAP_DEVICE("Cayman",TERASCALE_3);
MAP_DEVICE("Antilles",TERASCALE_3);
MAP_DEVICE("Scrapper",TERASCALE_3);
MAP_DEVICE("Devastator",TERASCALE_3);

//GCN 1
MAP_DEVICE("Cape",GCN_1);
MAP_DEVICE("Pitcairn",GCN_1);
MAP_DEVICE("Tahiti",GCN_1);
MAP_DEVICE("New Zealand",GCN_1);
MAP_DEVICE("Curacao",GCN_1);
MAP_DEVICE("Malta",GCN_1);

//GCN 2
MAP_DEVICE("Bonaire",GCN_2);
MAP_DEVICE("Hawaii",GCN_2);
MAP_DEVICE("Vesuvius",GCN_2);
MAP_DEVICE("gfx701",GCN_3);

//GCN 3
MAP_DEVICE("Tonga",GCN_3);
MAP_DEVICE("Fiji",GCN_3);
MAP_DEVICE("gfx801",GCN_3);
MAP_DEVICE("gfx802",GCN_3);
MAP_DEVICE("gfx803",GCN_3);

//GCN 4
MAP_DEVICE("Polaris",GCN_4);
#undef MAP_DEVICE
}
throw exception::unknown_architecture(name());
}

backend_type Device::backend() const
Expand Down
2 changes: 1 addition & 1 deletion lib/runtime/database.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ namespace runtime
const profiles::presets_type profiles::presets_ =
{
//DEFAULT
DATABASE_ENTRY(UNKNOWN, UNKNOWN, UNKNOWN, database::nvidia::sm_6_1),
DATABASE_ENTRY(UNKNOWN, UNKNOWN, UNKNOWN, database::intel::broadwell),

//INTEL
DATABASE_ENTRY(GPU, INTEL, HASWELL, database::intel::broadwell),
Expand Down
4 changes: 2 additions & 2 deletions lib/runtime/profiles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -195,8 +195,8 @@ profiles::map_type& profiles::init(driver::CommandQueue const & queue)
{
map_type & map = cache_[queue];
driver::Device const & device = queue.device();
// Default
// import(presets_.at(std::make_tuple(driver::Device::Type::UNKNOWN, driver::Device::Vendor::UNKNOWN, driver::Device::Architecture::UNKNOWN)), queue);
//Default
import(presets_.at(std::make_tuple(driver::Device::Type::UNKNOWN, driver::Device::Vendor::UNKNOWN, driver::Device::Architecture::UNKNOWN)), queue);
//Database profile
presets_type::const_iterator it = presets_.find(std::make_tuple(device.type(), device.vendor(), device.architecture()));
if(it!=presets_.end())
Expand Down

0 comments on commit 640e1d6

Please sign in to comment.