• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "core/compiler.hpp"
24 #include "core/program.hpp"
25 
26 using namespace clover;
27 
program(clover::context & ctx,std::string && source,enum il_type il_type)28 program::program(clover::context &ctx, std::string &&source,
29                  enum il_type il_type) :
30    context(ctx), _devices(ctx.devices()), _source(std::move(source)),
31    _kernel_ref_counter(0), _il_type(il_type) {
32 }
33 
program(clover::context & ctx,const ref_vector<device> & devs,const std::vector<binary> & binaries)34 program::program(clover::context &ctx,
35                  const ref_vector<device> &devs,
36                  const std::vector<binary> &binaries) :
37    context(ctx), _devices(devs), _kernel_ref_counter(0),
38    _il_type(il_type::none) {
39    for_each([&](device &dev, const binary &bin) {
40          _builds[&dev] = { bin };
41       },
42       devs, binaries);
43 }
44 
45 void
compile(const ref_vector<device> & devs,const std::string & opts,const header_map & headers)46 program::compile(const ref_vector<device> &devs, const std::string &opts,
47                  const header_map &headers) {
48    if (_il_type != il_type::none) {
49       _devices = devs;
50 
51       for (auto &dev : devs) {
52          std::string log;
53 
54          try {
55             const binary b =
56                compiler::compile_program(*this, headers, dev, opts, log);
57             _builds[&dev] = { b, opts, log };
58          } catch (...) {
59             _builds[&dev] = { binary(), opts, log };
60             throw;
61          }
62       }
63    }
64 }
65 
66 void
link(const ref_vector<device> & devs,const std::string & opts,const ref_vector<program> & progs)67 program::link(const ref_vector<device> &devs, const std::string &opts,
68               const ref_vector<program> &progs) {
69    _devices = devs;
70 
71    for (auto &dev : devs) {
72       const std::vector<binary> bs = map([&](const program &prog) {
73          return prog.build(dev).bin;
74          }, progs);
75       std::string log = _builds[&dev].log;
76 
77       try {
78          const binary b = compiler::link_program(bs, dev, opts, log);
79          _builds[&dev] = { b, opts, log };
80       } catch (...) {
81          _builds[&dev] = { binary(), opts, log };
82          throw;
83       }
84    }
85 }
86 
87 enum program::il_type
il_type() const88 program::il_type() const {
89    return _il_type;
90 }
91 
92 const std::string &
source() const93 program::source() const {
94    return _source;
95 }
96 
97 program::device_range
devices() const98 program::devices() const {
99    return map(evals(), _devices);
100 }
101 
102 cl_build_status
status() const103 program::build::status() const {
104    if (!bin.secs.empty())
105       return CL_BUILD_SUCCESS;
106    else if (log.size())
107       return CL_BUILD_ERROR;
108    else
109       return CL_BUILD_NONE;
110 }
111 
112 cl_program_binary_type
binary_type() const113 program::build::binary_type() const {
114    if (any_of(type_equals(binary::section::text_intermediate), bin.secs))
115       return CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT;
116    else if (any_of(type_equals(binary::section::text_library), bin.secs))
117       return CL_PROGRAM_BINARY_TYPE_LIBRARY;
118    else if (any_of(type_equals(binary::section::text_executable), bin.secs))
119       return CL_PROGRAM_BINARY_TYPE_EXECUTABLE;
120    else
121       return CL_PROGRAM_BINARY_TYPE_NONE;
122 }
123 
124 const struct program::build &
build(const device & dev) const125 program::build(const device &dev) const {
126    static const struct build null;
127    return _builds.count(&dev) ? _builds.find(&dev)->second : null;
128 }
129 
130 const std::vector<binary::symbol> &
symbols() const131 program::symbols() const {
132    if (_builds.empty())
133       throw error(CL_INVALID_PROGRAM_EXECUTABLE);
134 
135    return _builds.begin()->second.bin.syms;
136 }
137 
138 unsigned
kernel_ref_count() const139 program::kernel_ref_count() const {
140    return _kernel_ref_counter.ref_count();
141 }
142