ViennaCL - The Vienna Computing Library  1.5.2
viennacl/ocl/device.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_OCL_DEVICE_HPP_
00002 #define VIENNACL_OCL_DEVICE_HPP_
00003 
00004 /* =========================================================================
00005    Copyright (c) 2010-2014, Institute for Microelectronics,
00006                             Institute for Analysis and Scientific Computing,
00007                             TU Wien.
00008    Portions of this software are copyright by UChicago Argonne, LLC.
00009 
00010                             -----------------
00011                   ViennaCL - The Vienna Computing Library
00012                             -----------------
00013 
00014    Project Head:    Karl Rupp                   rupp@iue.tuwien.ac.at
00015 
00016    (A list of authors and contributors can be found in the PDF manual)
00017 
00018    License:         MIT (X11), see file LICENSE in the base directory
00019 ============================================================================= */
00020 
00025 #ifdef __APPLE__
00026 #include <OpenCL/cl.h>
00027 #else
00028 #include <CL/cl.h>
00029 #endif
00030 
00031 #include<stdio.h>
00032 
00033 #include <vector>
00034 #include <string>
00035 #include <sstream>
00036 #include <assert.h>
00037 #include "viennacl/ocl/device_utils.hpp"
00038 #include "viennacl/ocl/handle.hpp"
00039 #include "viennacl/ocl/error.hpp"
00040 
00041 namespace viennacl
00042 {
00043   namespace ocl
00044   {
00045 
00049     class device
00050     {
00051       public:
00052         explicit device() : device_(0) { flush_cache(); }
00053 
00054         explicit device(cl_device_id dev) : device_(dev)
00055         {
00056           #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_DEVICE)
00057           std::cout << "ViennaCL: Creating device object (CTOR with cl_device_id)" << std::endl;
00058           #endif
00059           flush_cache();
00060         }
00061 
00062         device(const device & other) : device_(0)
00063         {
00064           #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_DEVICE)
00065           std::cout << "ViennaCL: Creating device object (Copy CTOR)" << std::endl;
00066           #endif
00067           if (device_ != other.device_)
00068           {
00069             device_ = other.device_;
00070             flush_cache();
00071           }
00072         }
00073 
00075         cl_uint address_bits() const
00076         {
00077           if (!address_bits_valid_)
00078           {
00079             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_ADDRESS_BITS, sizeof(cl_uint), static_cast<void *>(&address_bits_), NULL);
00080             VIENNACL_ERR_CHECK(err);
00081             address_bits_valid_ = true;
00082           }
00083           return address_bits_;
00084         }
00085 
00087         cl_bool available() const
00088         {
00089           if (!available_valid_)
00090           {
00091             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_AVAILABLE, sizeof(cl_bool), static_cast<void *>(&available_), NULL);
00092             VIENNACL_ERR_CHECK(err);
00093             available_valid_ = true;
00094           }
00095           return available_;
00096         }
00097 
00099         cl_bool compiler_available() const
00100         {
00101           if (!compiler_available_valid_)
00102           {
00103             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_COMPILER_AVAILABLE , sizeof(cl_bool), static_cast<void *>(&compiler_available_), NULL);
00104             VIENNACL_ERR_CHECK(err);
00105             compiler_available_valid_ = true;
00106           }
00107           return compiler_available_;
00108         }
00109 
00110 #ifdef CL_DEVICE_DOUBLE_FP_CONFIG
00111 
00124         cl_device_fp_config double_fp_config() const
00125         {
00126           if (!double_fp_config_valid_)
00127           {
00128             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_DOUBLE_FP_CONFIG, sizeof(cl_device_fp_config), static_cast<void *>(&double_fp_config_), NULL);
00129             VIENNACL_ERR_CHECK(err);
00130             double_fp_config_valid_ = true;
00131           }
00132           return double_fp_config_;
00133         }
00134 #endif
00135 
00137         cl_bool endian_little() const
00138         {
00139           if (!endian_little_valid_)
00140           {
00141             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_ENDIAN_LITTLE, sizeof(cl_bool), static_cast<void *>(&endian_little_), NULL);
00142             VIENNACL_ERR_CHECK(err);
00143             endian_little_valid_ = true;
00144           }
00145           return endian_little_;
00146         }
00147 
00149         cl_bool error_correction_support() const
00150         {
00151           if (!error_correction_support_valid_)
00152           {
00153             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_ERROR_CORRECTION_SUPPORT , sizeof(cl_bool), static_cast<void *>(&error_correction_support_), NULL);
00154             VIENNACL_ERR_CHECK(err);
00155             error_correction_support_valid_ = true;
00156           }
00157           return error_correction_support_;
00158         }
00159 
00167         cl_device_exec_capabilities execution_capabilities() const
00168         {
00169           if (!execution_capabilities_valid_)
00170           {
00171             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_EXECUTION_CAPABILITIES  , sizeof(cl_device_exec_capabilities), static_cast<void *>(&execution_capabilities_), NULL);
00172             VIENNACL_ERR_CHECK(err);
00173             execution_capabilities_valid_ = true;
00174           }
00175           return execution_capabilities_;
00176         }
00177 
00189         std::string extensions() const
00190         {
00191           if (!extensions_valid_)
00192           {
00193             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_EXTENSIONS, sizeof(char) * 2048, static_cast<void *>(&extensions_), NULL);
00194             VIENNACL_ERR_CHECK(err);
00195             extensions_valid_ = true;
00196           }
00197           return extensions_;
00198         }
00199 
00201         cl_ulong global_mem_cache_size() const
00202         {
00203           if (!global_mem_cache_size_valid_)
00204           {
00205             cl_int err = clGetDeviceInfo(device_,  CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, sizeof(cl_ulong), static_cast<void *>(&global_mem_cache_size_), NULL);
00206             VIENNACL_ERR_CHECK(err);
00207             global_mem_cache_size_valid_ = true;
00208           }
00209           return global_mem_cache_size_;
00210         }
00211 
00213         cl_device_mem_cache_type global_mem_cache_type() const
00214         {
00215           if (!global_mem_cache_type_valid_)
00216           {
00217             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, sizeof(cl_device_mem_cache_type), static_cast<void *>(&global_mem_cache_type_), NULL);
00218             VIENNACL_ERR_CHECK(err);
00219             global_mem_cache_type_valid_ = true;
00220           }
00221           return global_mem_cache_type_;
00222         }
00223 
00225         cl_uint global_mem_cacheline_size() const
00226         {
00227           if (!global_mem_cacheline_size_valid_)
00228           {
00229             cl_int err = clGetDeviceInfo(device_,  CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, sizeof(cl_uint), static_cast<void *>(&global_mem_cacheline_size_), NULL);
00230             VIENNACL_ERR_CHECK(err);
00231             global_mem_cacheline_size_valid_ = true;
00232           }
00233           return global_mem_cacheline_size_;
00234         }
00235 
00237         cl_ulong global_mem_size() const
00238         {
00239           if (!global_mem_size_valid_)
00240           {
00241             cl_int err = clGetDeviceInfo(device_,  CL_DEVICE_GLOBAL_MEM_SIZE, sizeof(cl_ulong), static_cast<void *>(&global_mem_size_), NULL);
00242             VIENNACL_ERR_CHECK(err);
00243             global_mem_size_valid_ = true;
00244           }
00245           return global_mem_size_;
00246         }
00247 
00248 #ifdef CL_DEVICE_HALF_FP_CONFIG
00249 
00261         cl_device_fp_config half_fp_config() const
00262         {
00263           if (!half_fp_config_valid_)
00264           {
00265             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_HALF_FP_CONFIG, sizeof(cl_device_fp_config), static_cast<void *>(&half_fp_config_), NULL);
00266             VIENNACL_ERR_CHECK(err);
00267             half_fp_config_valid_ = true;
00268           }
00269           return half_fp_config_;
00270         }
00271 #endif
00272 
00274 #ifdef CL_DEVICE_HOST_UNIFIED_MEMORY
00275         cl_bool host_unified_memory() const
00276         {
00277           if (!host_unified_memory_valid_)
00278           {
00279             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_HOST_UNIFIED_MEMORY, sizeof(cl_bool), static_cast<void *>(&host_unified_memory_), NULL);
00280             VIENNACL_ERR_CHECK(err);
00281             host_unified_memory_valid_ = true;
00282           }
00283           return host_unified_memory_;
00284         }
00285 #endif
00286 
00288         cl_bool image_support() const
00289         {
00290           if (!image_support_valid_)
00291           {
00292             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_IMAGE_SUPPORT, sizeof(cl_bool), static_cast<void *>(&image_support_), NULL);
00293             VIENNACL_ERR_CHECK(err);
00294             image_support_valid_ = true;
00295           }
00296           return image_support_;
00297         }
00298 
00300         size_t image2d_max_height() const
00301         {
00302           if (!image2d_max_height_valid_)
00303           {
00304             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_IMAGE2D_MAX_HEIGHT, sizeof(size_t), static_cast<void *>(&image2d_max_height_), NULL);
00305             VIENNACL_ERR_CHECK(err);
00306             image2d_max_height_valid_ = true;
00307           }
00308           return image2d_max_height_;
00309         }
00310 
00312         size_t image2d_max_width() const
00313         {
00314           if (!image2d_max_width_valid_)
00315           {
00316             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_IMAGE2D_MAX_WIDTH, sizeof(size_t), static_cast<void *>(&image2d_max_width_), NULL);
00317             VIENNACL_ERR_CHECK(err);
00318             image2d_max_width_valid_ = true;
00319           }
00320           return image2d_max_width_;
00321         }
00322 
00324         size_t image3d_max_depth() const
00325         {
00326           if (!image3d_max_depth_valid_)
00327           {
00328             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_IMAGE3D_MAX_DEPTH, sizeof(size_t), static_cast<void *>(&image3d_max_depth_), NULL);
00329             VIENNACL_ERR_CHECK(err);
00330             image3d_max_depth_valid_ = true;
00331           }
00332           return image3d_max_depth_;
00333         }
00334 
00336         size_t image3d_max_height() const
00337         {
00338           if (!image3d_max_height_valid_)
00339           {
00340             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_IMAGE3D_MAX_HEIGHT, sizeof(size_t), static_cast<void *>(&image3d_max_height_), NULL);
00341             VIENNACL_ERR_CHECK(err);
00342             image3d_max_height_valid_ = true;
00343           }
00344           return image3d_max_height_;
00345         }
00346 
00348         size_t image3d_max_width() const
00349         {
00350           if (!image3d_max_width_valid_)
00351           {
00352             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_IMAGE3D_MAX_WIDTH, sizeof(size_t), static_cast<void *>(&image3d_max_width_), NULL);
00353             VIENNACL_ERR_CHECK(err);
00354             image3d_max_width_valid_ = true;
00355           }
00356           return image3d_max_width_;
00357         }
00358 
00360         cl_ulong local_mem_size() const
00361         {
00362           if (!local_mem_size_valid_)
00363           {
00364             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_LOCAL_MEM_SIZE, sizeof(cl_ulong), static_cast<void *>(&local_mem_size_), NULL);
00365             VIENNACL_ERR_CHECK(err);
00366             local_mem_size_valid_ = true;
00367           }
00368           return local_mem_size_;
00369         }
00370 
00372         cl_device_local_mem_type local_mem_type() const
00373         {
00374           if (!local_mem_type_valid_)
00375           {
00376             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_LOCAL_MEM_TYPE, sizeof(cl_device_local_mem_type), static_cast<void *>(&local_mem_type_), NULL);
00377             VIENNACL_ERR_CHECK(err);
00378             local_mem_type_valid_ = true;
00379           }
00380           return local_mem_type_;
00381         }
00382 
00384         cl_uint max_clock_frequency() const
00385         {
00386           if (!max_clock_frequency_valid_)
00387           {
00388             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(cl_uint), static_cast<void *>(&max_clock_frequency_), NULL);
00389             VIENNACL_ERR_CHECK(err);
00390             max_clock_frequency_valid_ = true;
00391           }
00392           return max_clock_frequency_;
00393         }
00394 
00396         cl_uint max_compute_units() const
00397         {
00398           if (!max_compute_units_valid_)
00399           {
00400             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(cl_uint), static_cast<void *>(&max_compute_units_), NULL);
00401             VIENNACL_ERR_CHECK(err);
00402             max_compute_units_valid_ = true;
00403           }
00404           return max_compute_units_;
00405         }
00406 
00408         cl_uint max_constant_args() const
00409         {
00410           if (!max_constant_args_valid_)
00411           {
00412             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_MAX_CONSTANT_ARGS, sizeof(cl_uint), static_cast<void *>(&max_constant_args_), NULL);
00413             VIENNACL_ERR_CHECK(err);
00414             max_constant_args_valid_ = true;
00415           }
00416           return max_constant_args_;
00417         }
00418 
00420         cl_ulong max_constant_buffer_size() const
00421         {
00422           if (!max_constant_buffer_size_valid_)
00423           {
00424             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, sizeof(cl_ulong), static_cast<void *>(&max_constant_buffer_size_), NULL);
00425             VIENNACL_ERR_CHECK(err);
00426             max_constant_buffer_size_valid_ = true;
00427           }
00428           return max_constant_buffer_size_;
00429         }
00430 
00432         cl_ulong max_mem_alloc_size() const
00433         {
00434           if (!max_mem_alloc_size_valid_)
00435           {
00436             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), static_cast<void *>(&max_mem_alloc_size_), NULL);
00437             VIENNACL_ERR_CHECK(err);
00438             max_mem_alloc_size_valid_ = true;
00439           }
00440           return max_mem_alloc_size_;
00441         }
00442 
00447         size_t max_parameter_size() const
00448         {
00449           if (!max_parameter_size_valid_)
00450           {
00451             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_MAX_PARAMETER_SIZE, sizeof(size_t), static_cast<void *>(&max_parameter_size_), NULL);
00452             VIENNACL_ERR_CHECK(err);
00453             max_parameter_size_valid_ = true;
00454           }
00455           return max_parameter_size_;
00456         }
00457 
00459         cl_uint max_read_image_args() const
00460         {
00461           if (!max_read_image_args_valid_)
00462           {
00463             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_MAX_READ_IMAGE_ARGS, sizeof(cl_uint), static_cast<void *>(&max_read_image_args_), NULL);
00464             VIENNACL_ERR_CHECK(err);
00465             max_read_image_args_valid_ = true;
00466           }
00467           return max_read_image_args_;
00468         }
00469 
00471         cl_uint max_samplers() const
00472         {
00473           if (!max_samplers_valid_)
00474           {
00475             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_MAX_SAMPLERS, sizeof(cl_uint), static_cast<void *>(&max_samplers_), NULL);
00476             VIENNACL_ERR_CHECK(err);
00477             max_samplers_valid_ = true;
00478           }
00479           return max_samplers_;
00480         }
00481 
00483         size_t max_work_group_size() const
00484         {
00485           if (!max_work_group_size_valid_)
00486           {
00487             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size_t), static_cast<void *>(&max_work_group_size_), NULL);
00488             VIENNACL_ERR_CHECK(err);
00489             max_work_group_size_valid_ = true;
00490           }
00491           return max_work_group_size_;
00492         }
00493 
00495         cl_uint max_work_item_dimensions() const
00496         {
00497           if (!max_work_item_dimensions_valid_)
00498           {
00499             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof(cl_uint), static_cast<void *>(&max_work_item_dimensions_), NULL);
00500             VIENNACL_ERR_CHECK(err);
00501             max_work_item_dimensions_valid_ = true;
00502           }
00503           return max_work_item_dimensions_;
00504         }
00505 
00510         std::vector<size_t> max_work_item_sizes() const
00511         {
00512           std::vector<size_t> result(max_work_item_dimensions());
00513 
00514           assert(result.size() < 16 && bool("Supported work item dimensions exceed available capacity!"));
00515 
00516           if (!max_work_item_sizes_valid_)
00517           {
00518             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_MAX_WORK_ITEM_SIZES, sizeof(size_t) * 16, static_cast<void *>(&max_work_item_sizes_), NULL);
00519             VIENNACL_ERR_CHECK(err);
00520             max_work_item_sizes_valid_ = true;
00521           }
00522 
00523           for (vcl_size_t i=0; i<result.size(); ++i)
00524             result[i] = max_work_item_sizes_[i];
00525 
00526           return result;
00527         }
00528 
00530         cl_uint max_write_image_args() const
00531         {
00532           if (!max_write_image_args_valid_)
00533           {
00534             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_MAX_WRITE_IMAGE_ARGS, sizeof(cl_uint), static_cast<void *>(&max_write_image_args_), NULL);
00535             VIENNACL_ERR_CHECK(err);
00536             max_write_image_args_valid_ = true;
00537           }
00538           return max_write_image_args_;
00539         }
00540 
00542         cl_uint mem_base_addr_align() const
00543         {
00544           if (!mem_base_addr_align_valid_)
00545           {
00546             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_MEM_BASE_ADDR_ALIGN, sizeof(cl_uint), static_cast<void *>(&mem_base_addr_align_), NULL);
00547             VIENNACL_ERR_CHECK(err);
00548             mem_base_addr_align_valid_ = true;
00549           }
00550           return mem_base_addr_align_;
00551         }
00552 
00554         cl_uint min_data_type_align_size() const
00555         {
00556           if (!min_data_type_align_size_valid_)
00557           {
00558             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, sizeof(cl_uint), static_cast<void *>(&min_data_type_align_size_), NULL);
00559             VIENNACL_ERR_CHECK(err);
00560             min_data_type_align_size_valid_ = true;
00561           }
00562           return min_data_type_align_size_;
00563         }
00564 
00566         std::string name() const
00567         {
00568           if (!name_valid_)
00569           {
00570             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_NAME, sizeof(char) * 256, static_cast<void *>(name_), NULL);
00571             VIENNACL_ERR_CHECK(err);
00572             name_valid_ = true;
00573           }
00574           return name_;
00575         }
00576 
00578         device_architecture_family architecture_family() const
00579         {
00580           if( !architecture_family_valid_)
00581           {
00582             architecture_family_ = get_device_architecture(vendor_id(), name());
00583             architecture_family_valid_ = true;
00584           }
00585           return architecture_family_;
00586         }
00587 
00588 #ifdef CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR
00589 
00590         cl_uint native_vector_width_char() const
00591         {
00592           if (!native_vector_width_char_valid_)
00593           {
00594             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR, sizeof(cl_uint), static_cast<void *>(&native_vector_width_char_), NULL);
00595             VIENNACL_ERR_CHECK(err);
00596             native_vector_width_char_valid_ = true;
00597           }
00598           return native_vector_width_char_;
00599         }
00600 #endif
00601 
00602 #ifdef CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT
00603 
00604         cl_uint native_vector_width_short() const
00605         {
00606           if (!native_vector_width_short_valid_)
00607           {
00608             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT, sizeof(cl_uint), static_cast<void *>(&native_vector_width_short_), NULL);
00609             VIENNACL_ERR_CHECK(err);
00610             native_vector_width_short_valid_ = true;
00611           }
00612           return native_vector_width_short_;
00613         }
00614 #endif
00615 
00616 #ifdef CL_DEVICE_NATIVE_VECTOR_WIDTH_INT
00617 
00618         cl_uint native_vector_width_int() const
00619         {
00620           if (!native_vector_width_int_valid_)
00621           {
00622             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_NATIVE_VECTOR_WIDTH_INT, sizeof(cl_uint), static_cast<void *>(&native_vector_width_int_), NULL);
00623             VIENNACL_ERR_CHECK(err);
00624             native_vector_width_int_valid_ = true;
00625           }
00626           return native_vector_width_int_;
00627         }
00628 #endif
00629 
00630 #ifdef CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG
00631 
00632         cl_uint native_vector_width_long() const
00633         {
00634           if (!native_vector_width_long_valid_)
00635           {
00636             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG, sizeof(cl_uint), static_cast<void *>(&native_vector_width_long_), NULL);
00637             VIENNACL_ERR_CHECK(err);
00638             native_vector_width_long_valid_ = true;
00639           }
00640           return native_vector_width_long_;
00641         }
00642 #endif
00643 
00644 #ifdef CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT
00645 
00646         cl_uint native_vector_width_float() const
00647         {
00648           if (!native_vector_width_float_valid_)
00649           {
00650             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT, sizeof(cl_uint), static_cast<void *>(&native_vector_width_float_), NULL);
00651             VIENNACL_ERR_CHECK(err);
00652             native_vector_width_float_valid_ = true;
00653           }
00654           return native_vector_width_float_;
00655         }
00656 #endif
00657 
00658 #ifdef CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE
00659 
00663         cl_uint native_vector_width_double() const
00664         {
00665           if (!native_vector_width_double_valid_)
00666           {
00667             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE, sizeof(cl_uint), static_cast<void *>(&native_vector_width_double_), NULL);
00668             VIENNACL_ERR_CHECK(err);
00669             native_vector_width_double_valid_ = true;
00670           }
00671           return native_vector_width_double_;
00672         }
00673 #endif
00674 
00675 #ifdef CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF
00676 
00680         cl_uint native_vector_width_half() const
00681         {
00682           if (!native_vector_width_half_valid_)
00683           {
00684             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF, sizeof(cl_uint), static_cast<void *>(&native_vector_width_half_), NULL);
00685             VIENNACL_ERR_CHECK(err);
00686             native_vector_width_half_valid_ = true;
00687           }
00688           return native_vector_width_half_;
00689         }
00690 #endif
00691 
00692 #if CL_DEVICE_OPENCL_C_VERSION
00693 
00701         std::string opencl_c_version() const
00702         {
00703           if (!opencl_c_version_valid_)
00704           {
00705             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_OPENCL_C_VERSION, sizeof(char) * 128, static_cast<void *>(opencl_c_version_), NULL);
00706             VIENNACL_ERR_CHECK(err);
00707             opencl_c_version_valid_ = true;
00708           }
00709           return opencl_c_version_;
00710         }
00711 #endif
00712 
00714         cl_platform_id platform() const
00715         {
00716           if (!platform_valid_)
00717           {
00718             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_PLATFORM, sizeof(cl_platform_id), static_cast<void *>(&platform_), NULL);
00719             VIENNACL_ERR_CHECK(err);
00720             platform_valid_ = true;
00721           }
00722           return platform_;
00723         }
00724 
00726         cl_uint preferred_vector_width_char() const
00727         {
00728           if (!preferred_vector_width_char_valid_)
00729           {
00730             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, sizeof(cl_uint), static_cast<void *>(&preferred_vector_width_char_), NULL);
00731             VIENNACL_ERR_CHECK(err);
00732             preferred_vector_width_char_valid_ = true;
00733           }
00734           return preferred_vector_width_char_;
00735         }
00736 
00738         cl_uint preferred_vector_width_short() const
00739         {
00740           if (!preferred_vector_width_short_valid_)
00741           {
00742             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, sizeof(cl_uint), static_cast<void *>(&preferred_vector_width_short_), NULL);
00743             VIENNACL_ERR_CHECK(err);
00744             preferred_vector_width_short_valid_ = true;
00745           }
00746           return preferred_vector_width_short_;
00747         }
00748 
00750         cl_uint preferred_vector_width_int() const
00751         {
00752           if (!preferred_vector_width_int_valid_)
00753           {
00754             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, sizeof(cl_uint), static_cast<void *>(&preferred_vector_width_int_), NULL);
00755             VIENNACL_ERR_CHECK(err);
00756             preferred_vector_width_int_valid_ = true;
00757           }
00758           return preferred_vector_width_int_;
00759         }
00760 
00762         cl_uint preferred_vector_width_long() const
00763         {
00764           if (!preferred_vector_width_long_valid_)
00765           {
00766             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, sizeof(cl_uint), static_cast<void *>(&preferred_vector_width_long_), NULL);
00767             VIENNACL_ERR_CHECK(err);
00768             preferred_vector_width_long_valid_ = true;
00769           }
00770           return preferred_vector_width_long_;
00771         }
00772 
00774         cl_uint preferred_vector_width_float() const
00775         {
00776           if (!preferred_vector_width_float_valid_)
00777           {
00778             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, sizeof(cl_uint), static_cast<void *>(&preferred_vector_width_float_), NULL);
00779             VIENNACL_ERR_CHECK(err);
00780             preferred_vector_width_float_valid_ = true;
00781           }
00782           return preferred_vector_width_float_;
00783         }
00784 
00789         cl_uint preferred_vector_width_double() const
00790         {
00791           if (!preferred_vector_width_double_valid_)
00792           {
00793             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, sizeof(cl_uint), static_cast<void *>(&preferred_vector_width_double_), NULL);
00794             VIENNACL_ERR_CHECK(err);
00795             preferred_vector_width_double_valid_ = true;
00796           }
00797           return preferred_vector_width_double_;
00798         }
00799 
00804 #ifdef CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF
00805         cl_uint preferred_vector_width_half() const
00806         {
00807           if (!preferred_vector_width_half_valid_)
00808           {
00809             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF, sizeof(cl_uint), static_cast<void *>(&preferred_vector_width_half_), NULL);
00810             VIENNACL_ERR_CHECK(err);
00811             preferred_vector_width_half_valid_ = true;
00812           }
00813           return preferred_vector_width_half_;
00814         }
00815 #endif
00816 
00823         std::string profile() const
00824         {
00825           if (!profile_valid_)
00826           {
00827             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_PROFILE, sizeof(char) * 32, static_cast<void *>(profile_), NULL);
00828             VIENNACL_ERR_CHECK(err);
00829             profile_valid_ = true;
00830           }
00831           return profile_;
00832         }
00833 
00835         size_t profiling_timer_resolution() const
00836         {
00837           if (!profiling_timer_resolution_valid_)
00838           {
00839             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_PROFILING_TIMER_RESOLUTION, sizeof(size_t), static_cast<void *>(&profiling_timer_resolution_), NULL);
00840             VIENNACL_ERR_CHECK(err);
00841             profiling_timer_resolution_valid_ = true;
00842           }
00843           return profiling_timer_resolution_;
00844         }
00845 
00854         cl_command_queue_properties queue_properties() const
00855         {
00856           if (!queue_properties_valid_)
00857           {
00858             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_QUEUE_PROPERTIES, sizeof(cl_command_queue_properties), static_cast<void *>(&queue_properties_), NULL);
00859             VIENNACL_ERR_CHECK(err);
00860             queue_properties_valid_ = true;
00861           }
00862           return queue_properties_;
00863         }
00864 
00878         cl_device_fp_config single_fp_config() const
00879         {
00880           if (!single_fp_config_valid_)
00881           {
00882             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_SINGLE_FP_CONFIG, sizeof(cl_device_fp_config), static_cast<void *>(&single_fp_config_), NULL);
00883             VIENNACL_ERR_CHECK(err);
00884             single_fp_config_valid_ = true;
00885           }
00886           return single_fp_config_;
00887         }
00888 
00893         cl_device_type type() const
00894         {
00895           if (!type_valid_)
00896           {
00897             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_TYPE, sizeof(cl_device_type), static_cast<void *>(&type_), NULL);
00898             VIENNACL_ERR_CHECK(err);
00899             type_valid_ = true;
00900           }
00901           return type_;
00902         }
00903 
00905         std::string vendor() const
00906         {
00907           if (!vendor_valid_)
00908           {
00909             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_VENDOR, sizeof(char) * 256, static_cast<void *>(vendor_), NULL);
00910             VIENNACL_ERR_CHECK(err);
00911             vendor_valid_ = true;
00912           }
00913           return vendor_;
00914         }
00915 
00917         cl_uint vendor_id() const
00918         {
00919           if (!vendor_id_valid_)
00920           {
00921             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_VENDOR_ID, sizeof(cl_uint), static_cast<void *>(&vendor_id_), NULL);
00922             VIENNACL_ERR_CHECK(err);
00923             vendor_id_valid_ = true;
00924           }
00925           return vendor_id_;
00926         }
00927 
00929         std::string version() const
00930         {
00931           if (!version_valid_)
00932           {
00933             cl_int err = clGetDeviceInfo(device_, CL_DEVICE_VERSION, sizeof(char) * 256, static_cast<void *>(version_), NULL);
00934             VIENNACL_ERR_CHECK(err);
00935             version_valid_ = true;
00936           }
00937           return version_;
00938         }
00939 
00941         std::string driver_version() const
00942         {
00943           if (!driver_version_valid_)
00944           {
00945             cl_int err = clGetDeviceInfo(device_, CL_DRIVER_VERSION, sizeof(char) * 256, static_cast<void *>(driver_version_), NULL);
00946             VIENNACL_ERR_CHECK(err);
00947             driver_version_valid_ = true;
00948           }
00949           return driver_version_;
00950         }
00951 
00953 
00954 
00956         bool double_support() const
00957         {
00958           std::string ext = extensions();
00959 
00960           if (ext.find("cl_khr_fp64") != std::string::npos || ext.find("cl_amd_fp64") != std::string::npos)
00961             return true;
00962 
00963           return false;
00964         }
00965 
00967         std::string double_support_extension() const
00968         {
00969           std::string ext = extensions();
00970 
00971           if (ext.find("cl_amd_fp64") != std::string::npos) //AMD extension
00972             return "cl_amd_fp64";
00973 
00974           if (ext.find("cl_khr_fp64") != std::string::npos) //Khronos-certified standard extension for double precision
00975             return "cl_khr_fp64";
00976 
00977           return "";
00978         }
00979 
00981         cl_device_id id() const
00982         {
00983           assert(device_ != 0 && bool("Device ID invalid!"));
00984           return device_;
00985         }
00986 
00995         std::string info(vcl_size_t indent = 0, char indent_char = ' ') const
00996         {
00997           std::string line_indent(indent, indent_char);
00998           std::ostringstream oss;
00999           oss << line_indent << "Name:                " << name() << std::endl;
01000           oss << line_indent << "Vendor:              " << vendor() << std::endl;
01001           oss << line_indent << "Type:                " << device_type_to_string(type()) << std::endl;
01002           oss << line_indent << "Available:           " << available() << std::endl;
01003           oss << line_indent << "Max Compute Units:   " << max_compute_units() << std::endl;
01004           oss << line_indent << "Max Work Group Size: " << max_work_group_size() << std::endl;
01005           oss << line_indent << "Global Mem Size:     " << global_mem_size() << std::endl;
01006           oss << line_indent << "Local Mem Size:      " << local_mem_size() << std::endl;
01007           oss << line_indent << "Local Mem Type:      " << local_mem_type() << std::endl;
01008 #ifdef CL_DEVICE_HOST_UNIFIED_MEMORY
01009           oss << line_indent << "Host Unified Memory: " << host_unified_memory() << std::endl;
01010 #endif
01011 
01012           return oss.str();
01013         }
01014 
01020         std::string full_info(vcl_size_t indent = 0, char indent_char = ' ') const
01021         {
01022           std::string line_indent(indent, indent_char);
01023           std::ostringstream oss;
01024           oss << line_indent << "Address Bits:                  " << address_bits() << std::endl;
01025           oss << line_indent << "Available:                     " << available() << std::endl;
01026           oss << line_indent << "Compiler Available:            " << compiler_available() << std::endl;
01027 #ifdef CL_DEVICE_DOUBLE_FP_CONFIG
01028           oss << line_indent << "Double FP Config:              " << fp_config_to_string(double_fp_config()) << std::endl;
01029 #endif
01030           oss << line_indent << "Endian Little:                 " << endian_little() << std::endl;
01031           oss << line_indent << "Error Correction Support:      " << error_correction_support() << std::endl;
01032           oss << line_indent << "Execution Capabilities:        " << exec_capabilities_to_string(execution_capabilities()) << std::endl;
01033           oss << line_indent << "Extensions:                    " << extensions() << std::endl;
01034           oss << line_indent << "Global Mem Cache Size:         " << global_mem_cache_size() << " Bytes" << std::endl;
01035           oss << line_indent << "Global Mem Cache Type:         " << mem_cache_type_to_string(global_mem_cache_type()) << std::endl;
01036           oss << line_indent << "Global Mem Cacheline Size:     " << global_mem_cacheline_size() << " Bytes" << std::endl;
01037           oss << line_indent << "Global Mem Size:               " << global_mem_size() << " Bytes" << std::endl;
01038 #ifdef CL_DEVICE_HALF_FP_CONFIG
01039           oss << line_indent << "Half PF Config:                " << fp_config_to_string(half_fp_config()) << std::endl;
01040 #endif
01041 #ifdef CL_DEVICE_HOST_UNIFIED_MEMORY
01042           oss << line_indent << "Host Unified Memory:           " << host_unified_memory() << std::endl;
01043 #endif
01044           oss << line_indent << "Image Support:                 " << image_support() << std::endl;
01045           oss << line_indent << "Image2D Max Height:            " << image2d_max_height() << std::endl;
01046           oss << line_indent << "Image2D Max Width:             " << image2d_max_width() << std::endl;
01047           oss << line_indent << "Image3D Max Depth:             " << image3d_max_depth() << std::endl;
01048           oss << line_indent << "Image3D Max Height:            " << image3d_max_height() << std::endl;
01049           oss << line_indent << "Image3D Max Width:             " << image3d_max_width() << std::endl;
01050           oss << line_indent << "Local Mem Size:                " << local_mem_size() << " Bytes" << std::endl;
01051           oss << line_indent << "Local Mem Type:                " << local_mem_type_to_string(local_mem_type()) << std::endl;
01052           oss << line_indent << "Max Clock Frequency:           " << max_clock_frequency() << " MHz" << std::endl;
01053           oss << line_indent << "Max Compute Units:             " << max_compute_units() << std::endl;
01054           oss << line_indent << "Max Constant Args:             " << max_constant_args() << std::endl;
01055           oss << line_indent << "Max Constant Buffer Size:      " << max_constant_buffer_size() << " Bytes" << std::endl;
01056           oss << line_indent << "Max Mem Alloc Size:            " << max_mem_alloc_size() << " Bytes" << std::endl;
01057           oss << line_indent << "Max Parameter Size:            " << max_parameter_size() << " Bytes" << std::endl;
01058           oss << line_indent << "Max Read Image Args:           " << max_read_image_args() << std::endl;
01059           oss << line_indent << "Max Samplers:                  " << max_samplers() << std::endl;
01060           oss << line_indent << "Max Work Group Size:           " << max_work_group_size() << std::endl;
01061           oss << line_indent << "Max Work Item Dimensions:      " << max_work_item_dimensions() << std::endl;
01062           oss << line_indent << "Max Work Item Sizes:           " << convert_to_string(max_work_item_sizes()) << std::endl;
01063           oss << line_indent << "Max Write Image Args:          " << max_write_image_args() << std::endl;
01064           oss << line_indent << "Mem Base Addr Align:           " << mem_base_addr_align() << std::endl;
01065           oss << line_indent << "Min Data Type Align Size:      " << min_data_type_align_size() << " Bytes" << std::endl;
01066           oss << line_indent << "Name:                          " << name() << std::endl;
01067 #ifdef CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR
01068           oss << line_indent << "Native Vector Width char:      " << native_vector_width_char() << std::endl;
01069 #endif
01070 #ifdef CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT
01071           oss << line_indent << "Native Vector Width short:     " << native_vector_width_short() << std::endl;
01072 #endif
01073 #ifdef CL_DEVICE_NATIVE_VECTOR_WIDTH_INT
01074           oss << line_indent << "Native Vector Width int:       " << native_vector_width_int() << std::endl;
01075 #endif
01076 #ifdef CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG
01077           oss << line_indent << "Native Vector Width long:      " << native_vector_width_long() << std::endl;
01078 #endif
01079 #ifdef CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT
01080           oss << line_indent << "Native Vector Width float:     " << native_vector_width_float() << std::endl;
01081 #endif
01082 #ifdef CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE
01083           oss << line_indent << "Native Vector Width double:    " << native_vector_width_double() << std::endl;
01084 #endif
01085 #ifdef CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF
01086           oss << line_indent << "Native Vector Width half:      " << native_vector_width_half() << std::endl;
01087 #endif
01088 #ifdef CL_DEVICE_OPENCL_C_VERSION
01089           oss << line_indent << "OpenCL C Version:              " << opencl_c_version() << std::endl;
01090 #endif
01091           oss << line_indent << "Platform:                      " << platform() << std::endl;
01092           oss << line_indent << "Preferred Vector Width char:   " << preferred_vector_width_char() << std::endl;
01093           oss << line_indent << "Preferred Vector Width short:  " << preferred_vector_width_short() << std::endl;
01094           oss << line_indent << "Preferred Vector Width int:    " << preferred_vector_width_int() << std::endl;
01095           oss << line_indent << "Preferred Vector Width long:   " << preferred_vector_width_long() << std::endl;
01096           oss << line_indent << "Preferred Vector Width float:  " << preferred_vector_width_float() << std::endl;
01097           oss << line_indent << "Preferred Vector Width double: " << preferred_vector_width_double() << std::endl;
01098 #ifdef CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF
01099           oss << line_indent << "Preferred Vector Width half:   " << preferred_vector_width_half() << std::endl;
01100 #endif
01101           oss << line_indent << "Profile:                       " << profile() << std::endl;
01102           oss << line_indent << "Profiling Timer Resolution:    " << profiling_timer_resolution() << " ns" << std::endl;
01103           oss << line_indent << "Queue Properties:              " << queue_properties_to_string(queue_properties()) << std::endl;
01104           oss << line_indent << "Single FP Config:              " << fp_config_to_string(single_fp_config()) << std::endl;
01105           oss << line_indent << "Type:                          " << device_type_to_string(type()) << std::endl;
01106           oss << line_indent << "Vendor:                        " << vendor() << std::endl;
01107           oss << line_indent << "Vendor ID:                     " << vendor_id() << std::endl;
01108           oss << line_indent << "Version:                       " << version() << std::endl;
01109           oss << line_indent << "Driver Version:                " << driver_version() << std::endl;
01110 
01111           return oss.str();
01112         }
01113 
01114         bool operator==(device const & other) const
01115         {
01116           return device_ == other.device_;
01117         }
01118 
01119         bool operator==(cl_device_id other) const
01120         {
01121           return device_ == other;
01122         }
01123 
01124       private:
01125 
01127         std::string fp_config_to_string(cl_device_fp_config conf) const
01128         {
01129           std::ostringstream oss;
01130           if (conf & CL_FP_DENORM)
01131             oss << "CL_FP_DENORM ";
01132           if (conf & CL_FP_INF_NAN)
01133             oss << "CL_FP_INF_NAN ";
01134           if (conf & CL_FP_ROUND_TO_NEAREST)
01135             oss << "CL_FP_ROUND_TO_NEAREST ";
01136           if (conf & CL_FP_ROUND_TO_ZERO)
01137             oss << "CL_FP_ROUND_TO_ZERO ";
01138           if (conf & CL_FP_ROUND_TO_INF)
01139             oss << "CL_FP_ROUND_TO_INF ";
01140           if (conf & CL_FP_FMA)
01141             oss << "CL_FP_FMA ";
01142 #ifdef CL_FP_SOFT_FLOAT
01143           if (conf & CL_FP_SOFT_FLOAT)
01144             oss << "CL_FP_SOFT_FLOAT ";
01145 #endif
01146 
01147           return oss.str();
01148         }
01149 
01150         std::string exec_capabilities_to_string(cl_device_exec_capabilities cap) const
01151         {
01152           std::ostringstream oss;
01153           if (cap & CL_EXEC_KERNEL)
01154             oss << "CL_EXEC_KERNEL ";
01155           if (cap & CL_EXEC_NATIVE_KERNEL)
01156             oss << "CL_EXEC_NATIVE_KERNEL ";
01157 
01158           return oss.str();
01159         }
01160 
01161         std::string mem_cache_type_to_string(cl_device_mem_cache_type cachetype) const
01162         {
01163           std::ostringstream oss;
01164           if (cachetype == CL_NONE)
01165             oss << "CL_NONE ";
01166           else if (cachetype == CL_READ_ONLY_CACHE)
01167             oss << "CL_READ_ONLY_CACHE ";
01168           else if (cachetype == CL_READ_WRITE_CACHE)
01169             oss << "CL_READ_WRITE_CACHE ";
01170 
01171           return oss.str();
01172         }
01173 
01174         std::string local_mem_type_to_string(cl_device_local_mem_type loc_mem_type) const
01175         {
01176           std::ostringstream oss;
01177           if (loc_mem_type & CL_LOCAL)
01178             oss << "CL_LOCAL ";
01179           if (loc_mem_type & CL_GLOBAL)
01180             oss << "CL_GLOBAL ";
01181 
01182           return oss.str();
01183         }
01184 
01185         std::string convert_to_string(std::vector<size_t> const & vec) const
01186         {
01187           std::ostringstream oss;
01188           for (vcl_size_t i=0; i<vec.size(); ++i)
01189             oss << vec[i] << " ";
01190 
01191           return oss.str();
01192         }
01193 
01194         std::string queue_properties_to_string(cl_command_queue_properties queue_prop) const
01195         {
01196           std::ostringstream oss;
01197           if (queue_prop & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE)
01198             oss << "CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE ";
01199           if (queue_prop & CL_QUEUE_PROFILING_ENABLE)
01200             oss << "CL_QUEUE_PROFILING_ENABLE ";
01201 
01202           return oss.str();
01203         }
01204 
01205         std::string device_type_to_string(cl_device_type dev_type) const
01206         {
01207           std::ostringstream oss;
01208           if (dev_type & CL_DEVICE_TYPE_GPU)
01209             oss << "GPU ";
01210           if (dev_type & CL_DEVICE_TYPE_CPU)
01211             oss << "CPU ";
01212           if (dev_type & CL_DEVICE_TYPE_ACCELERATOR)
01213             oss << "Accelerator ";
01214           if (dev_type & CL_DEVICE_TYPE_DEFAULT)
01215             oss << "(default)";
01216 
01217           return oss.str();
01218         }
01219 
01220         void flush_cache()
01221         {
01222           address_bits_valid_       = false;
01223           architecture_family_valid_ = false;
01224           available_valid_          = false;
01225           compiler_available_valid_ = false;
01226 #ifdef CL_DEVICE_DOUBLE_FP_CONFIG
01227           double_fp_config_valid_   = false;
01228 #endif
01229           endian_little_valid_      = false;
01230           error_correction_support_valid_  = false;
01231           execution_capabilities_valid_    = false;
01232           extensions_valid_                = false;
01233           global_mem_cache_size_valid_     = false;
01234           global_mem_cache_type_valid_     = false;
01235           global_mem_cacheline_size_valid_ = false;
01236           global_mem_size_valid_           = false;
01237 #ifdef CL_DEVICE_HALF_FP_CONFIG
01238           half_fp_config_valid_      = false;
01239 #endif
01240           host_unified_memory_valid_ = false;
01241           image_support_valid_       = false;
01242           image2d_max_height_valid_  = false;
01243           image2d_max_width_valid_   = false;
01244           image3d_max_depth_valid_   = false;
01245           image3d_max_height_valid_  = false;
01246           image3d_max_width_valid_   = false;
01247           local_mem_size_valid_      = false;
01248           local_mem_type_valid_      = false;
01249           max_clock_frequency_valid_ = false;
01250           max_compute_units_valid_   = false;
01251           max_constant_args_valid_   = false;
01252           max_constant_buffer_size_valid_ = false;
01253           max_mem_alloc_size_valid_  = false;
01254           max_parameter_size_valid_  = false;
01255           max_read_image_args_valid_ = false;
01256           max_samplers_valid_        = false;
01257           max_work_group_size_valid_ = false;
01258           max_work_item_dimensions_valid_ = false;
01259           max_work_item_sizes_valid_  = false;
01260           max_write_image_args_valid_ = false;
01261           mem_base_addr_align_valid_  = false;
01262           min_data_type_align_size_valid_ = false;
01263           name_valid_ = false;
01264           native_vector_width_char_valid_   = false;
01265           native_vector_width_short_valid_  = false;
01266           native_vector_width_int_valid_    = false;
01267           native_vector_width_long_valid_   = false;
01268           native_vector_width_float_valid_  = false;
01269           native_vector_width_double_valid_ = false;
01270           native_vector_width_half_valid_   = false;
01271           opencl_c_version_valid_ = false;
01272           platform_valid_ = false;
01273           preferred_vector_width_char_valid_   = false;
01274           preferred_vector_width_short_valid_  = false;
01275           preferred_vector_width_int_valid_    = false;
01276           preferred_vector_width_long_valid_   = false;
01277           preferred_vector_width_float_valid_  = false;
01278           preferred_vector_width_double_valid_ = false;
01279           preferred_vector_width_half_valid_   = false;
01280           profile_valid_ = false;
01281           profiling_timer_resolution_valid_ = false;
01282           queue_properties_valid_ = false;
01283           single_fp_config_valid_ = false;
01284           type_valid_             = false;
01285           vendor_valid_           = false;
01286           vendor_id_valid_        = false;
01287           version_valid_          = false;
01288           driver_version_valid_   = false;
01289         }
01290 
01291         cl_device_id    device_;
01292 
01293         //
01294         // Device information supported by OpenCL 1.0 to follow
01295         // cf. http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clGetDeviceInfo.html
01296         // Note that all members are declared 'mutable', as they represent a caching mechanism in order to circumvent repeated potentially expensive calls to the OpenCL SDK
01297         //
01298 
01299         mutable bool    address_bits_valid_;
01300         mutable cl_uint address_bits_;
01301 
01302         mutable bool    available_valid_;
01303         mutable cl_bool available_;
01304 
01305         mutable bool    compiler_available_valid_;
01306         mutable cl_bool compiler_available_;
01307 
01308 #ifdef CL_DEVICE_DOUBLE_FP_CONFIG
01309         mutable bool                double_fp_config_valid_;
01310         mutable cl_device_fp_config double_fp_config_;
01311 #endif
01312 
01313         mutable bool    endian_little_valid_;
01314         mutable cl_bool endian_little_;
01315 
01316         mutable bool    error_correction_support_valid_;
01317         mutable cl_bool error_correction_support_;
01318 
01319         mutable bool                        execution_capabilities_valid_;
01320         mutable cl_device_exec_capabilities execution_capabilities_;
01321 
01322         mutable bool extensions_valid_;
01323         mutable char extensions_[2048];    // don't forget to adjust member function accordingly when changing array size
01324 
01325         mutable bool     global_mem_cache_size_valid_;
01326         mutable cl_ulong global_mem_cache_size_;
01327 
01328         mutable bool                     global_mem_cache_type_valid_;
01329         mutable cl_device_mem_cache_type global_mem_cache_type_;
01330 
01331         mutable bool    global_mem_cacheline_size_valid_;
01332         mutable cl_uint global_mem_cacheline_size_;
01333 
01334         mutable bool     global_mem_size_valid_;
01335         mutable cl_ulong global_mem_size_;
01336 
01337 #ifdef CL_DEVICE_HALF_FP_CONFIG
01338         mutable bool                half_fp_config_valid_;
01339         mutable cl_device_fp_config half_fp_config_;
01340 #endif
01341 
01342         mutable bool    host_unified_memory_valid_;
01343         mutable cl_bool host_unified_memory_;
01344 
01345         mutable bool    image_support_valid_;
01346         mutable cl_bool image_support_;
01347 
01348         mutable bool   image2d_max_height_valid_;
01349         mutable size_t image2d_max_height_;
01350 
01351         mutable bool   image2d_max_width_valid_;
01352         mutable size_t image2d_max_width_;
01353 
01354         mutable bool   image3d_max_depth_valid_;
01355         mutable size_t image3d_max_depth_;
01356 
01357         mutable bool   image3d_max_height_valid_;
01358         mutable size_t image3d_max_height_;
01359 
01360         mutable bool   image3d_max_width_valid_;
01361         mutable size_t image3d_max_width_;
01362 
01363         mutable bool     local_mem_size_valid_;
01364         mutable cl_ulong local_mem_size_;
01365 
01366         mutable bool                     local_mem_type_valid_;
01367         mutable cl_device_local_mem_type local_mem_type_;
01368 
01369         mutable bool    max_clock_frequency_valid_;
01370         mutable cl_uint max_clock_frequency_;
01371 
01372         mutable bool    max_compute_units_valid_;
01373         mutable cl_uint max_compute_units_;
01374 
01375         mutable bool    max_constant_args_valid_;
01376         mutable cl_uint max_constant_args_;
01377 
01378         mutable bool     max_constant_buffer_size_valid_;
01379         mutable cl_ulong max_constant_buffer_size_;
01380 
01381         mutable bool     max_mem_alloc_size_valid_;
01382         mutable cl_ulong max_mem_alloc_size_;
01383 
01384         mutable bool   max_parameter_size_valid_;
01385         mutable size_t max_parameter_size_;
01386 
01387         mutable bool    max_read_image_args_valid_;
01388         mutable cl_uint max_read_image_args_;
01389 
01390         mutable bool    max_samplers_valid_;
01391         mutable cl_uint max_samplers_;
01392 
01393         mutable bool   max_work_group_size_valid_;
01394         mutable size_t max_work_group_size_;
01395 
01396         mutable bool    max_work_item_dimensions_valid_;
01397         mutable cl_uint max_work_item_dimensions_;
01398 
01399         mutable bool   max_work_item_sizes_valid_;
01400         mutable size_t max_work_item_sizes_[16];   //we do not support execution models with more than 16 dimensions. This should totally suffice in practice, though.
01401 
01402         mutable bool    max_write_image_args_valid_;
01403         mutable cl_uint max_write_image_args_;
01404 
01405         mutable bool    mem_base_addr_align_valid_;
01406         mutable cl_uint mem_base_addr_align_;
01407 
01408         mutable bool    min_data_type_align_size_valid_;
01409         mutable cl_uint min_data_type_align_size_;
01410 
01411         mutable bool name_valid_;
01412         mutable char name_[256];    // don't forget to adjust member function accordingly when changing array size
01413 
01414         mutable bool    native_vector_width_char_valid_;
01415         mutable cl_uint native_vector_width_char_;
01416 
01417         mutable bool    native_vector_width_short_valid_;
01418         mutable cl_uint native_vector_width_short_;
01419 
01420         mutable bool    native_vector_width_int_valid_;
01421         mutable cl_uint native_vector_width_int_;
01422 
01423         mutable bool    native_vector_width_long_valid_;
01424         mutable cl_uint native_vector_width_long_;
01425 
01426         mutable bool    native_vector_width_float_valid_;
01427         mutable cl_uint native_vector_width_float_;
01428 
01429         mutable bool    native_vector_width_double_valid_;
01430         mutable cl_uint native_vector_width_double_;
01431 
01432         mutable bool    native_vector_width_half_valid_;
01433         mutable cl_uint native_vector_width_half_;
01434 
01435         mutable bool opencl_c_version_valid_;
01436         mutable char opencl_c_version_[128];    // don't forget to adjust member function accordingly when changing array size
01437 
01438         mutable bool           platform_valid_;
01439         mutable cl_platform_id platform_;
01440 
01441         mutable bool    preferred_vector_width_char_valid_;
01442         mutable cl_uint preferred_vector_width_char_;
01443 
01444         mutable bool    preferred_vector_width_short_valid_;
01445         mutable cl_uint preferred_vector_width_short_;
01446 
01447         mutable bool    preferred_vector_width_int_valid_;
01448         mutable cl_uint preferred_vector_width_int_;
01449 
01450         mutable bool    preferred_vector_width_long_valid_;
01451         mutable cl_uint preferred_vector_width_long_;
01452 
01453         mutable bool    preferred_vector_width_float_valid_;
01454         mutable cl_uint preferred_vector_width_float_;
01455 
01456         mutable bool    preferred_vector_width_double_valid_;
01457         mutable cl_uint preferred_vector_width_double_;
01458 
01459         mutable bool    preferred_vector_width_half_valid_;
01460         mutable cl_uint preferred_vector_width_half_;
01461 
01462         mutable bool profile_valid_;
01463         mutable char profile_[32];    // don't forget to adjust member function accordingly when changing array size
01464 
01465         mutable bool   profiling_timer_resolution_valid_;
01466         mutable size_t profiling_timer_resolution_;
01467 
01468         mutable bool                        queue_properties_valid_;
01469         mutable cl_command_queue_properties queue_properties_;
01470 
01471         mutable bool                single_fp_config_valid_;
01472         mutable cl_device_fp_config single_fp_config_;
01473 
01474         mutable bool           type_valid_;
01475         mutable cl_device_type type_;
01476 
01477         mutable bool vendor_valid_;
01478         mutable char vendor_[256];    // don't forget to adjust member function accordingly when changing array size
01479 
01480         mutable bool    vendor_id_valid_;
01481         mutable cl_uint vendor_id_;
01482 
01483         mutable bool version_valid_;
01484         mutable char version_[256];    // don't forget to adjust member function accordingly when changing array size
01485 
01486         mutable bool driver_version_valid_;
01487         mutable char driver_version_[256];    // don't forget to adjust member function accordingly when changing array size
01488 
01489         mutable bool architecture_family_valid_;
01490         mutable device_architecture_family architecture_family_;
01491     };
01492 
01493   } //namespace ocl
01494 } //namespace viennacl
01495 
01496 #endif