Home | History | Annotate | Download | only in api
      1 //
      2 // Copyright 2012 Francisco Jerez
      3 //
      4 // Permission is hereby granted, free of charge, to any person obtaining a
      5 // copy of this software and associated documentation files (the "Software"),
      6 // to deal in the Software without restriction, including without limitation
      7 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8 // and/or sell copies of the Software, and to permit persons to whom the
      9 // Software is furnished to do so, subject to the following conditions:
     10 //
     11 // The above copyright notice and this permission notice shall be included in
     12 // all copies or substantial portions of the Software.
     13 //
     14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17 // THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
     18 // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
     19 // OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     20 // SOFTWARE.
     21 //
     22 
     23 #ifndef __CL_UTIL_HPP__
     24 #define __CL_UTIL_HPP__
     25 
     26 #include <cstdint>
     27 #include <cstring>
     28 #include <algorithm>
     29 #include <map>
     30 
     31 #include "core/base.hpp"
     32 #include "pipe/p_compiler.h"
     33 
     34 namespace clover {
     35    ///
     36    /// Return a matrix (a container of containers) in \a buf with
     37    /// argument and bounds checking.  Intended to be used by
     38    /// implementations of \a clGetXXXInfo().
     39    ///
     40    template<typename T, typename V>
     41    cl_int
     42    matrix_property(void *buf, size_t size, size_t *size_ret, const V& v) {
     43       if (buf && size < sizeof(T *) * v.size())
     44          return CL_INVALID_VALUE;
     45 
     46       if (size_ret)
     47          *size_ret = sizeof(T *) * v.size();
     48 
     49       if (buf)
     50          for_each([](typename V::value_type src, T *dst) {
     51                if (dst)
     52                   std::copy(src.begin(), src.end(), dst);
     53             },
     54             v.begin(), v.end(), (T **)buf);
     55 
     56       return CL_SUCCESS;
     57    }
     58 
     59    ///
     60    /// Return a vector in \a buf with argument and bounds checking.
     61    /// Intended to be used by implementations of \a clGetXXXInfo().
     62    ///
     63    template<typename T, typename V>
     64    cl_int
     65    vector_property(void *buf, size_t size, size_t *size_ret, const V& v) {
     66       if (buf && size < sizeof(T) * v.size())
     67          return CL_INVALID_VALUE;
     68 
     69       if (size_ret)
     70          *size_ret = sizeof(T) * v.size();
     71       if (buf)
     72          std::copy(v.begin(), v.end(), (T *)buf);
     73 
     74       return CL_SUCCESS;
     75    }
     76 
     77    ///
     78    /// Return a scalar in \a buf with argument and bounds checking.
     79    /// Intended to be used by implementations of \a clGetXXXInfo().
     80    ///
     81    template<typename T>
     82    cl_int
     83    scalar_property(void *buf, size_t size, size_t *size_ret, T v) {
     84       return vector_property<T>(buf, size, size_ret, std::vector<T>(1, v));
     85    }
     86 
     87    ///
     88    /// Return a string in \a buf with argument and bounds checking.
     89    /// Intended to be used by implementations of \a clGetXXXInfo().
     90    ///
     91    inline cl_int
     92    string_property(void *buf, size_t size, size_t *size_ret,
     93                    const std::string &v) {
     94       if (buf && size < v.size() + 1)
     95          return CL_INVALID_VALUE;
     96 
     97       if (size_ret)
     98          *size_ret = v.size() + 1;
     99       if (buf)
    100          std::strcpy((char *)buf, v.c_str());
    101 
    102       return CL_SUCCESS;
    103    }
    104 
    105    ///
    106    /// Convert a NULL-terminated property list into an std::map.
    107    ///
    108    template<typename T>
    109    std::map<T, T>
    110    property_map(const T *props) {
    111       std::map<T, T> m;
    112 
    113       while (props && *props) {
    114          T key = *props++;
    115          T value = *props++;
    116 
    117          if (m.count(key))
    118             throw clover::error(CL_INVALID_PROPERTY);
    119 
    120          m.insert({ key, value });
    121       }
    122 
    123       return m;
    124    }
    125 
    126    ///
    127    /// Convert an std::map into a NULL-terminated property list.
    128    ///
    129    template<typename T>
    130    std::vector<T>
    131    property_vector(const std::map<T, T> &m) {
    132       std::vector<T> v;
    133 
    134       for (auto &p : m) {
    135          v.push_back(p.first);
    136          v.push_back(p.second);
    137       }
    138 
    139       v.push_back(0);
    140       return v;
    141    }
    142 
    143    ///
    144    /// Return an error code in \a p if non-zero.
    145    ///
    146    inline void
    147    ret_error(cl_int *p, const clover::error &e) {
    148       if (p)
    149          *p = e.get();
    150    }
    151 
    152    ///
    153    /// Return a reference-counted object in \a p if non-zero.
    154    /// Otherwise release object ownership.
    155    ///
    156    template<typename T, typename S>
    157    void
    158    ret_object(T p, S v) {
    159       if (p)
    160          *p = v;
    161       else
    162          v->release();
    163    }
    164 }
    165 
    166 #endif
    167