blob: 526e06a26c34bcdd5e8bfad1349128b76bbebc88 [file] [log] [blame]
Francisco Jerezc6db1b32012-04-20 16:56:19 +02001//
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 Graunkef0cb66b2013-04-21 13:52:08 -070017// 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 Jerezc6db1b32012-04-20 16:56:19 +020021//
22
Karol Herbst1befaf42019-05-10 09:27:06 +020023#include "core/compiler.hpp"
Francisco Jerezc6db1b32012-04-20 16:56:19 +020024#include "core/program.hpp"
Francisco Jerezc6db1b32012-04-20 16:56:19 +020025
26using namespace clover;
27
Francisco Jerezc4578d22014-02-18 15:07:11 +010028program::program(clover::context &ctx, const std::string &source) :
Pierre Moreau25d4e652018-01-27 18:11:17 +010029 has_source(true), context(ctx), _devices(ctx.devices()), _source(source),
30 _kernel_ref_counter(0) {
Francisco Jerezc6db1b32012-04-20 16:56:19 +020031}
32
Francisco Jerezc4578d22014-02-18 15:07:11 +010033program::program(clover::context &ctx,
Francisco Jerez35307f52013-09-17 23:20:11 -070034 const ref_vector<device> &devs,
35 const std::vector<module> &binaries) :
Francisco Jerezc4578d22014-02-18 15:07:11 +010036 has_source(false), context(ctx),
Francisco Jereze9a4e742014-08-16 16:25:34 +030037 _devices(devs), _kernel_ref_counter(0) {
Francisco Jerez35307f52013-09-17 23:20:11 -070038 for_each([&](device &dev, const module &bin) {
Francisco Jerez19424902016-05-17 16:03:13 +020039 _builds[&dev] = { bin };
Francisco Jerezc6db1b32012-04-20 16:56:19 +020040 },
Francisco Jerez7d617692013-10-06 13:49:05 -070041 devs, binaries);
Francisco Jerezc6db1b32012-04-20 16:56:19 +020042}
43
44void
Francisco Jerez010918f2016-05-17 16:03:14 +020045program::compile(const ref_vector<device> &devs, const std::string &opts,
46 const header_map &headers) {
Francisco Jerez56626022014-01-14 21:55:29 +010047 if (has_source) {
Francisco Jerezc4578d22014-02-18 15:07:11 +010048 _devices = devs;
49
Francisco Jerez56626022014-01-14 21:55:29 +010050 for (auto &dev : devs) {
EdB5ca9b232015-04-24 12:59:55 +020051 std::string log;
Matt Arsenault2ab44f62014-06-09 22:21:52 -070052
Francisco Jerez56626022014-01-14 21:55:29 +010053 try {
Karol Herbst1befaf42019-05-10 09:27:06 +020054 const module m =
55 compiler::compile_program(_source, headers, dev, opts, log);
Francisco Jerez19424902016-05-17 16:03:13 +020056 _builds[&dev] = { m, opts, log };
57 } catch (...) {
58 _builds[&dev] = { module(), opts, log };
Francisco Jerez56626022014-01-14 21:55:29 +010059 throw;
60 }
Francisco Jerezc6db1b32012-04-20 16:56:19 +020061 }
62 }
63}
64
Francisco Jerez010918f2016-05-17 16:03:14 +020065void
66program::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 Herbst1befaf42019-05-10 09:27:06 +020077 const module m = compiler::link_program(ms, dev, opts, log);
Francisco Jerez010918f2016-05-17 16:03:14 +020078 _builds[&dev] = { m, opts, log };
79 } catch (...) {
80 _builds[&dev] = { module(), opts, log };
81 throw;
82 }
83 }
84}
85
Francisco Jerezc6db1b32012-04-20 16:56:19 +020086const std::string &
Francisco Jerez35307f52013-09-17 23:20:11 -070087program::source() const {
Francisco Jerez8e14b822013-09-17 23:13:48 -070088 return _source;
Francisco Jerezc6db1b32012-04-20 16:56:19 +020089}
90
Francisco Jerez7a9bbff2013-09-16 21:50:40 -070091program::device_range
92program::devices() const {
Francisco Jerezc4578d22014-02-18 15:07:11 +010093 return map(evals(), _devices);
Francisco Jerez7a9bbff2013-09-16 21:50:40 -070094}
95
Francisco Jerezc6db1b32012-04-20 16:56:19 +020096cl_build_status
Francisco Jerez19424902016-05-17 16:03:13 +020097program::build::status() const {
98 if (!binary.secs.empty())
Francisco Jerez7a9bbff2013-09-16 21:50:40 -070099 return CL_BUILD_SUCCESS;
Francisco Jerez19424902016-05-17 16:03:13 +0200100 else if (log.size())
Tom Stellardfda75582015-03-24 17:17:22 +0000101 return CL_BUILD_ERROR;
Francisco Jerez7a9bbff2013-09-16 21:50:40 -0700102 else
103 return CL_BUILD_NONE;
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200104}
105
Serge Martincc495052016-10-30 17:21:15 -0700106cl_program_binary_type
107program::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 Jerez19424902016-05-17 16:03:13 +0200118const struct program::build &
119program::build(const device &dev) const {
120 static const struct build null;
121 return _builds.count(&dev) ? _builds.find(&dev)->second : null;
Francisco Jerezc6db1b32012-04-20 16:56:19 +0200122}
Francisco Jerez7a9bbff2013-09-16 21:50:40 -0700123
EdBd8f817a2015-04-23 20:13:51 +0200124const std::vector<module::symbol> &
Francisco Jerez7a9bbff2013-09-16 21:50:40 -0700125program::symbols() const {
Francisco Jerez19424902016-05-17 16:03:13 +0200126 if (_builds.empty())
Francisco Jerez7a9bbff2013-09-16 21:50:40 -0700127 throw error(CL_INVALID_PROGRAM_EXECUTABLE);
128
Francisco Jerez19424902016-05-17 16:03:13 +0200129 return _builds.begin()->second.binary.syms;
Francisco Jerez7a9bbff2013-09-16 21:50:40 -0700130}
Francisco Jereze9a4e742014-08-16 16:25:34 +0300131
132unsigned
133program::kernel_ref_count() const {
134 return _kernel_ref_counter.ref_count();
135}