| 37 | namespace fl { |
| 38 | |
| 39 | host_program::host_program(const device& dev_, program_map_type&& programs_) : |
| 40 | device_program(retrieve_unique_function_names(programs_)), dev(dev_), programs(std::move(programs_)), has_device_binary(!programs.empty()) { |
| 41 | if (programs.empty()) { |
| 42 | return; |
| 43 | } |
| 44 | |
| 45 | // create all functions of all device programs |
| 46 | // note that this essentially reshuffles the program "device -> functions" data to "functions -> devices" |
| 47 | functions.reserve(function_names.size()); |
| 48 | for (const auto& function_name : function_names) { |
| 49 | host_function::function_map_type function_map; |
| 50 | for (auto&& prog : programs) { |
| 51 | if (!prog.second.valid || !prog.second.program) { |
| 52 | continue; |
| 53 | } |
| 54 | |
| 55 | const auto& function_names = prog.second.program->get_function_names(); |
| 56 | if (function_names.empty()) { |
| 57 | continue; |
| 58 | } |
| 59 | |
| 60 | for (const auto& info : prog.second.functions) { |
| 61 | if (info.name != function_name) { |
| 62 | continue; |
| 63 | } |
| 64 | |
| 65 | const auto func_iter = find_if(function_names.begin(), function_names.end(), [&function_name](const auto& entry) { |
| 66 | return (entry == function_name); |
| 67 | }); |
| 68 | if (func_iter == function_names.end()) { |
| 69 | continue; |
| 70 | } |
| 71 | |
| 72 | if (should_ignore_function_for_device(*prog.first, info)) { |
| 73 | continue; |
| 74 | } |
| 75 | |
| 76 | host_function::host_function_entry entry; |
| 77 | entry.info = &info; |
| 78 | entry.program = prog.second.program; |
| 79 | if (info.has_valid_required_local_size()) { |
| 80 | const auto local_size_extent = info.required_local_size.extent(); |
| 81 | if (local_size_extent > host_limits::max_total_local_size) { |
| 82 | log_error("function $ required local size extent of $ is larger than the max supported local size of $", |
| 83 | info.name, local_size_extent, host_limits::max_total_local_size); |
| 84 | continue; |
| 85 | } |
| 86 | entry.max_local_size = info.required_local_size; |
| 87 | entry.max_total_local_size = local_size_extent; |
| 88 | } else { |
| 89 | // else: just assume the device/global default |
| 90 | entry.max_local_size = prog.first->max_local_size; |
| 91 | entry.max_total_local_size = host_limits::max_total_local_size; |
| 92 | } |
| 93 | |
| 94 | if (info.has_valid_required_simd_width()) { |
| 95 | entry.required_simd_width = info.required_simd_width; |
| 96 | } |
nothing calls this directly
no test coverage detected