ViennaCL - The Vienna Computing Library  1.5.2
viennacl/device_specific/database.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_DEVICE_SPECIFIC_DATABASE_HPP_
00002 #define VIENNACL_DEVICE_SPECIFIC_DATABASE_HPP_
00003 
00004 #include "viennacl/ocl/device_utils.hpp"
00005 #include "viennacl/device_specific/forwards.h"
00006 #include "viennacl/device_specific/templates/vector_axpy_template.hpp"
00007 #include "viennacl/device_specific/templates/matrix_axpy_template.hpp"
00008 #include "viennacl/device_specific/templates/reduction_template.hpp"
00009 #include "viennacl/scheduler/forwards.h"
00010 
00011 namespace viennacl{
00012 
00013   namespace device_specific{
00014 
00015     namespace database{
00016 
00017 
00021       static database_type<vector_axpy_template::parameters> vector_axpy = database_type<vector_axpy_template::parameters>
00022           (unknown_id, CL_DEVICE_TYPE_GPU, UNKNOWN, "", UINT_TYPE, vector_axpy_template::parameters("uint",1,128,128,true))
00023           (unknown_id, CL_DEVICE_TYPE_GPU, UNKNOWN, "", INT_TYPE, vector_axpy_template::parameters("int",1,128,128,true))
00024           (unknown_id, CL_DEVICE_TYPE_GPU, UNKNOWN, "", ULONG_TYPE, vector_axpy_template::parameters("ulong",1,128,128,true))
00025           (unknown_id, CL_DEVICE_TYPE_GPU, UNKNOWN, "", LONG_TYPE, vector_axpy_template::parameters("long",1,128,128,true))
00026           (unknown_id, CL_DEVICE_TYPE_GPU, UNKNOWN, "", FLOAT_TYPE, vector_axpy_template::parameters("float",1,128,128,true))
00027           (unknown_id, CL_DEVICE_TYPE_GPU, UNKNOWN, "", DOUBLE_TYPE, vector_axpy_template::parameters("double",1,128,128,true));
00028 
00029 
00033       static database_type<reduction_template::parameters> reduction = database_type<reduction_template::parameters>
00034           (unknown_id, CL_DEVICE_TYPE_GPU, UNKNOWN, "", UINT_TYPE, reduction_template::parameters("uint",1,128,128,true))
00035           (unknown_id, CL_DEVICE_TYPE_GPU, UNKNOWN, "", INT_TYPE, reduction_template::parameters("int",1,128,128,true))
00036           (unknown_id, CL_DEVICE_TYPE_GPU, UNKNOWN, "", ULONG_TYPE, reduction_template::parameters("ulong",1,128,128,true))
00037           (unknown_id, CL_DEVICE_TYPE_GPU, UNKNOWN, "", LONG_TYPE, reduction_template::parameters("long",1,128,128,true))
00038           (unknown_id, CL_DEVICE_TYPE_GPU, UNKNOWN, "", FLOAT_TYPE, reduction_template::parameters("float",1,128,128,true))
00039           (unknown_id, CL_DEVICE_TYPE_GPU, UNKNOWN, "", DOUBLE_TYPE, reduction_template::parameters("double",1,128,128,true));
00040 
00044       static database_type<matrix_axpy_template::parameters> matrix_axpy = database_type<matrix_axpy_template::parameters>
00045           (unknown_id, CL_DEVICE_TYPE_GPU, UNKNOWN, "", UINT_TYPE, matrix_axpy_template::parameters("uint",1,8,8,8,8,true))
00046           (unknown_id, CL_DEVICE_TYPE_GPU, UNKNOWN, "", INT_TYPE, matrix_axpy_template::parameters("int",1,8,8,8,8,true))
00047           (unknown_id, CL_DEVICE_TYPE_GPU, UNKNOWN, "", ULONG_TYPE, matrix_axpy_template::parameters("ulong",1,8,8,8,8,true))
00048           (unknown_id, CL_DEVICE_TYPE_GPU, UNKNOWN, "", LONG_TYPE, matrix_axpy_template::parameters("long",1,8,8,8,8,true))
00049           (unknown_id, CL_DEVICE_TYPE_GPU, UNKNOWN, "", FLOAT_TYPE, matrix_axpy_template::parameters("float",1,8,8,8,8,true))
00050           (unknown_id, CL_DEVICE_TYPE_GPU, UNKNOWN, "", DOUBLE_TYPE, matrix_axpy_template::parameters("double",1,8,8,8,8,true));
00051 
00052 
00054       template<class ParamT>
00055       inline ParamT const & handle_failure(database_type<ParamT> const & database, viennacl::ocl::device const & device, scheduler::statement_node_numeric_type numeric_type, ParamT const & params)
00056       {
00057         //Returns default if the profile is invalid
00058         if(params.is_invalid())
00059           return database.map.at(ocl::unknown_id).at(device.type()).at(ocl::UNKNOWN).at("").at(numeric_type);
00060         return params;
00061       }
00062 
00064       template<class T, class ParamT>
00065       inline ParamT const & get(database_type<ParamT> const & database)
00066       {
00067         viennacl::ocl::device const & device = viennacl::ocl::current_device();
00068         scheduler::statement_node_numeric_type numeric_type = scheduler::statement_node_numeric_type(scheduler::result_of::numeric_type_id<T>::value);
00069 
00070         device_type dev_type = device.type();
00071         vendor_id_type vendor_id = device.vendor_id();
00072         ocl::device_architecture_family device_architecture = device.architecture_family();
00073         std::string const & device_name = device.name();
00074 
00075         //std::cout << "Looking up vendor ID..." << std::endl;
00076         /*-Vendor ID-*/
00077         typename database_type<ParamT>::map_type::const_iterator vendor_it = database.map.find(vendor_id);
00078         //Vendor not recognized => global default:
00079         if(vendor_it==database.map.end())
00080           return handle_failure(database, device, numeric_type, database.map.at(ocl::unknown_id).at(dev_type).at(ocl::UNKNOWN).at("").at(numeric_type));
00081 
00082         /*-Device Type-*/
00083         //std::cout << "Looking up device type..." << std::endl;
00084         typename database_type<ParamT>::device_type_map::const_iterator device_type_it = vendor_it->second.find(dev_type);
00085         //Device type not recognized for this vendor => global default
00086         if(device_type_it==vendor_it->second.end())
00087           return handle_failure(database, device, numeric_type, database.map.at(ocl::unknown_id).at(dev_type).at(ocl::UNKNOWN).at("").at(numeric_type));
00088 
00089         /*-Device Architecture-*/
00090         //std::cout << "Looking up device architecture..." << std::endl;
00091         typename database_type<ParamT>::device_architecture_map::const_iterator architecture_it = device_type_it->second.find(device_architecture);
00092         if(architecture_it==device_type_it->second.end())
00093           return handle_failure(database, device, numeric_type, database.map.at(ocl::unknown_id).at(dev_type).at(ocl::UNKNOWN).at("").at(numeric_type));
00094 
00095         /*-Device Name-*/
00096         //std::cout << "Looking up device name..." << std::endl;
00097         typename database_type<ParamT>::device_name_map::const_iterator device_name_it = architecture_it->second.find(device_name);
00098         //Name not found => Vendor default
00099         if(device_name_it==architecture_it->second.end())
00100           return handle_failure(database, device, numeric_type, database.map.at(vendor_id).at(dev_type).at(device_architecture).at("").at(numeric_type));
00101 
00102         //std::cout << "Looking up expression name.." << std::endl;
00103         /*-Expression-*/
00104         typename database_type<ParamT>::expression_map::const_iterator expression_it = device_name_it->second.find(numeric_type);
00105         //Expression not found => Vendor default
00106         if(expression_it==device_name_it->second.end())
00107           return handle_failure(database, device, numeric_type, database.map.at(vendor_id).at(dev_type).at(device_architecture).at("").at(numeric_type));
00108 
00109         //std::cout << "Device found in the database! Getting profile..." << std::endl;
00110         //Everything okay. Return specific profile//
00111         return handle_failure(database, device, numeric_type, database.map.at(vendor_id).at(dev_type).at(device_architecture).at(device_name).at(numeric_type));
00112       }
00113 
00114 
00115     }
00116 
00117   }
00118 
00119 }
00120 #endif