Francisco Jerez | c6db1b3 | 2012-04-20 16:56:19 +0200 | [diff] [blame] | 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 |
Kenneth Graunke | f0cb66b | 2013-04-21 13:52:08 -0700 | [diff] [blame] | 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. |
Francisco Jerez | c6db1b3 | 2012-04-20 16:56:19 +0200 | [diff] [blame] | 21 | // |
| 22 | |
Karol Herbst | 1befaf4 | 2019-05-10 09:27:06 +0200 | [diff] [blame] | 23 | #include "core/compiler.hpp" |
Francisco Jerez | c6db1b3 | 2012-04-20 16:56:19 +0200 | [diff] [blame] | 24 | #include "core/program.hpp" |
Francisco Jerez | c6db1b3 | 2012-04-20 16:56:19 +0200 | [diff] [blame] | 25 | |
| 26 | using namespace clover; |
| 27 | |
Francisco Jerez | c4578d2 | 2014-02-18 15:07:11 +0100 | [diff] [blame] | 28 | program::program(clover::context &ctx, const std::string &source) : |
Pierre Moreau | 25d4e65 | 2018-01-27 18:11:17 +0100 | [diff] [blame] | 29 | has_source(true), context(ctx), _devices(ctx.devices()), _source(source), |
| 30 | _kernel_ref_counter(0) { |
Francisco Jerez | c6db1b3 | 2012-04-20 16:56:19 +0200 | [diff] [blame] | 31 | } |
| 32 | |
Francisco Jerez | c4578d2 | 2014-02-18 15:07:11 +0100 | [diff] [blame] | 33 | program::program(clover::context &ctx, |
Francisco Jerez | 35307f5 | 2013-09-17 23:20:11 -0700 | [diff] [blame] | 34 | const ref_vector<device> &devs, |
| 35 | const std::vector<module> &binaries) : |
Francisco Jerez | c4578d2 | 2014-02-18 15:07:11 +0100 | [diff] [blame] | 36 | has_source(false), context(ctx), |
Francisco Jerez | e9a4e74 | 2014-08-16 16:25:34 +0300 | [diff] [blame] | 37 | _devices(devs), _kernel_ref_counter(0) { |
Francisco Jerez | 35307f5 | 2013-09-17 23:20:11 -0700 | [diff] [blame] | 38 | for_each([&](device &dev, const module &bin) { |
Francisco Jerez | 1942490 | 2016-05-17 16:03:13 +0200 | [diff] [blame] | 39 | _builds[&dev] = { bin }; |
Francisco Jerez | c6db1b3 | 2012-04-20 16:56:19 +0200 | [diff] [blame] | 40 | }, |
Francisco Jerez | 7d61769 | 2013-10-06 13:49:05 -0700 | [diff] [blame] | 41 | devs, binaries); |
Francisco Jerez | c6db1b3 | 2012-04-20 16:56:19 +0200 | [diff] [blame] | 42 | } |
| 43 | |
| 44 | void |
Francisco Jerez | 010918f | 2016-05-17 16:03:14 +0200 | [diff] [blame] | 45 | program::compile(const ref_vector<device> &devs, const std::string &opts, |
| 46 | const header_map &headers) { |
Francisco Jerez | 5662602 | 2014-01-14 21:55:29 +0100 | [diff] [blame] | 47 | if (has_source) { |
Francisco Jerez | c4578d2 | 2014-02-18 15:07:11 +0100 | [diff] [blame] | 48 | _devices = devs; |
| 49 | |
Francisco Jerez | 5662602 | 2014-01-14 21:55:29 +0100 | [diff] [blame] | 50 | for (auto &dev : devs) { |
EdB | 5ca9b23 | 2015-04-24 12:59:55 +0200 | [diff] [blame] | 51 | std::string log; |
Matt Arsenault | 2ab44f6 | 2014-06-09 22:21:52 -0700 | [diff] [blame] | 52 | |
Francisco Jerez | 5662602 | 2014-01-14 21:55:29 +0100 | [diff] [blame] | 53 | try { |
Karol Herbst | 1befaf4 | 2019-05-10 09:27:06 +0200 | [diff] [blame] | 54 | const module m = |
| 55 | compiler::compile_program(_source, headers, dev, opts, log); |
Francisco Jerez | 1942490 | 2016-05-17 16:03:13 +0200 | [diff] [blame] | 56 | _builds[&dev] = { m, opts, log }; |
| 57 | } catch (...) { |
| 58 | _builds[&dev] = { module(), opts, log }; |
Francisco Jerez | 5662602 | 2014-01-14 21:55:29 +0100 | [diff] [blame] | 59 | throw; |
| 60 | } |
Francisco Jerez | c6db1b3 | 2012-04-20 16:56:19 +0200 | [diff] [blame] | 61 | } |
| 62 | } |
| 63 | } |
| 64 | |
Francisco Jerez | 010918f | 2016-05-17 16:03:14 +0200 | [diff] [blame] | 65 | void |
| 66 | program::link(const ref_vector<device> &devs, const std::string &opts, |
| 67 | const ref_vector<program> &progs) { |
| 68 | _devices = devs; |
| 69 | |
| 70 | for (auto &dev : devs) { |
| 71 | const std::vector<module> ms = map([&](const program &prog) { |
| 72 | return prog.build(dev).binary; |
| 73 | }, progs); |
| 74 | std::string log = _builds[&dev].log; |
| 75 | |
| 76 | try { |
Karol Herbst | 1befaf4 | 2019-05-10 09:27:06 +0200 | [diff] [blame] | 77 | const module m = compiler::link_program(ms, dev, opts, log); |
Francisco Jerez | 010918f | 2016-05-17 16:03:14 +0200 | [diff] [blame] | 78 | _builds[&dev] = { m, opts, log }; |
| 79 | } catch (...) { |
| 80 | _builds[&dev] = { module(), opts, log }; |
| 81 | throw; |
| 82 | } |
| 83 | } |
| 84 | } |
| 85 | |
Francisco Jerez | c6db1b3 | 2012-04-20 16:56:19 +0200 | [diff] [blame] | 86 | const std::string & |
Francisco Jerez | 35307f5 | 2013-09-17 23:20:11 -0700 | [diff] [blame] | 87 | program::source() const { |
Francisco Jerez | 8e14b82 | 2013-09-17 23:13:48 -0700 | [diff] [blame] | 88 | return _source; |
Francisco Jerez | c6db1b3 | 2012-04-20 16:56:19 +0200 | [diff] [blame] | 89 | } |
| 90 | |
Francisco Jerez | 7a9bbff | 2013-09-16 21:50:40 -0700 | [diff] [blame] | 91 | program::device_range |
| 92 | program::devices() const { |
Francisco Jerez | c4578d2 | 2014-02-18 15:07:11 +0100 | [diff] [blame] | 93 | return map(evals(), _devices); |
Francisco Jerez | 7a9bbff | 2013-09-16 21:50:40 -0700 | [diff] [blame] | 94 | } |
| 95 | |
Francisco Jerez | c6db1b3 | 2012-04-20 16:56:19 +0200 | [diff] [blame] | 96 | cl_build_status |
Francisco Jerez | 1942490 | 2016-05-17 16:03:13 +0200 | [diff] [blame] | 97 | program::build::status() const { |
| 98 | if (!binary.secs.empty()) |
Francisco Jerez | 7a9bbff | 2013-09-16 21:50:40 -0700 | [diff] [blame] | 99 | return CL_BUILD_SUCCESS; |
Francisco Jerez | 1942490 | 2016-05-17 16:03:13 +0200 | [diff] [blame] | 100 | else if (log.size()) |
Tom Stellard | fda7558 | 2015-03-24 17:17:22 +0000 | [diff] [blame] | 101 | return CL_BUILD_ERROR; |
Francisco Jerez | 7a9bbff | 2013-09-16 21:50:40 -0700 | [diff] [blame] | 102 | else |
| 103 | return CL_BUILD_NONE; |
Francisco Jerez | c6db1b3 | 2012-04-20 16:56:19 +0200 | [diff] [blame] | 104 | } |
| 105 | |
Serge Martin | cc49505 | 2016-10-30 17:21:15 -0700 | [diff] [blame] | 106 | cl_program_binary_type |
| 107 | program::build::binary_type() const { |
| 108 | if (any_of(type_equals(module::section::text_intermediate), binary.secs)) |
| 109 | return CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT; |
| 110 | else if (any_of(type_equals(module::section::text_library), binary.secs)) |
| 111 | return CL_PROGRAM_BINARY_TYPE_LIBRARY; |
| 112 | else if (any_of(type_equals(module::section::text_executable), binary.secs)) |
| 113 | return CL_PROGRAM_BINARY_TYPE_EXECUTABLE; |
| 114 | else |
| 115 | return CL_PROGRAM_BINARY_TYPE_NONE; |
| 116 | } |
| 117 | |
Francisco Jerez | 1942490 | 2016-05-17 16:03:13 +0200 | [diff] [blame] | 118 | const struct program::build & |
| 119 | program::build(const device &dev) const { |
| 120 | static const struct build null; |
| 121 | return _builds.count(&dev) ? _builds.find(&dev)->second : null; |
Francisco Jerez | c6db1b3 | 2012-04-20 16:56:19 +0200 | [diff] [blame] | 122 | } |
Francisco Jerez | 7a9bbff | 2013-09-16 21:50:40 -0700 | [diff] [blame] | 123 | |
EdB | d8f817a | 2015-04-23 20:13:51 +0200 | [diff] [blame] | 124 | const std::vector<module::symbol> & |
Francisco Jerez | 7a9bbff | 2013-09-16 21:50:40 -0700 | [diff] [blame] | 125 | program::symbols() const { |
Francisco Jerez | 1942490 | 2016-05-17 16:03:13 +0200 | [diff] [blame] | 126 | if (_builds.empty()) |
Francisco Jerez | 7a9bbff | 2013-09-16 21:50:40 -0700 | [diff] [blame] | 127 | throw error(CL_INVALID_PROGRAM_EXECUTABLE); |
| 128 | |
Francisco Jerez | 1942490 | 2016-05-17 16:03:13 +0200 | [diff] [blame] | 129 | return _builds.begin()->second.binary.syms; |
Francisco Jerez | 7a9bbff | 2013-09-16 21:50:40 -0700 | [diff] [blame] | 130 | } |
Francisco Jerez | e9a4e74 | 2014-08-16 16:25:34 +0300 | [diff] [blame] | 131 | |
| 132 | unsigned |
| 133 | program::kernel_ref_count() const { |
| 134 | return _kernel_ref_counter.ref_count(); |
| 135 | } |