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 OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 // OTHER DEALINGS IN THE SOFTWARE.
21 //
22 
23 #ifndef CLOVER_API_UTIL_HPP
24 #define CLOVER_API_UTIL_HPP
25 
26 #include <cassert>
27 #include <iostream>
28 
29 #include "core/error.hpp"
30 #include "core/property.hpp"
31 #include "util/algorithm.hpp"
32 #include "util/detect_os.h"
33 
34 #if DETECT_OS_WINDOWS
35 #define CLOVER_API
36 #define CLOVER_ICD_API
37 #elif HAVE_CLOVER_ICD
38 #define CLOVER_API
39 #define CLOVER_ICD_API PUBLIC
40 #else
41 #define CLOVER_API PUBLIC
42 #define CLOVER_ICD_API PUBLIC
43 #endif
44 
45 #define CLOVER_NOT_SUPPORTED_UNTIL(version)                    \
46    do {                                                        \
47       std::cerr << "CL user error: " << __func__               \
48                 << "() requires OpenCL version " << (version)  \
49                 << " or greater." << std::endl;                \
50    } while (0)
51 
52 namespace clover {
53    ///
54    /// Return an error code in \a p if non-zero.
55    ///
56    inline void
ret_error(cl_int * p,const clover::error & e)57    ret_error(cl_int *p, const clover::error &e) {
58       if (p)
59          *p = e.get();
60    }
61 
62    ///
63    /// Return a clover object in \a p if non-zero incrementing the
64    /// reference count of the object.
65    ///
66    template<typename T>
67    void
ret_object(typename T::descriptor_type ** p,const intrusive_ref<T> & v)68    ret_object(typename T::descriptor_type **p,
69               const intrusive_ref<T> &v) {
70       if (p) {
71          v().retain();
72          *p = desc(v());
73       }
74    }
75 
76    ///
77    /// Return an API object from an intrusive reference to a Clover object,
78    /// incrementing the reference count of the object.
79    ///
80    template<typename T>
81    typename T::descriptor_type *
ret_object(const intrusive_ref<T> & v)82    ret_object(const intrusive_ref<T> &v) {
83       v().retain();
84       return desc(v());
85    }
86 }
87 
88 #endif
89