| 1099 | } |
| 1100 | |
| 1101 | class CUDAKernel { |
| 1102 | std::vector<std::string> _link_files; |
| 1103 | std::vector<std::string> _link_paths; |
| 1104 | CUlinkState _link_state; |
| 1105 | CUmodule _module; |
| 1106 | CUfunction _kernel; |
| 1107 | std::string _func_name; |
| 1108 | std::string _ptx; |
| 1109 | std::map<std::string, std::string> _global_map; |
| 1110 | std::vector<CUjit_option> _opts; |
| 1111 | std::vector<void*> _optvals; |
| 1112 | #ifdef JITIFY_PRINT_LINKER_LOG |
| 1113 | static const unsigned int _log_size = 8192; |
| 1114 | char _error_log[_log_size]; |
| 1115 | char _info_log[_log_size]; |
| 1116 | #endif |
| 1117 | |
| 1118 | inline void cuda_safe_call(CUresult res) const { |
| 1119 | if (res != CUDA_SUCCESS) { |
| 1120 | const char* msg; |
| 1121 | cuGetErrorName(res, &msg); |
| 1122 | throw std::runtime_error(msg); |
| 1123 | } |
| 1124 | } |
| 1125 | inline void create_module(std::vector<std::string> link_files, |
| 1126 | std::vector<std::string> link_paths) { |
| 1127 | CUresult result; |
| 1128 | #ifndef JITIFY_PRINT_LINKER_LOG |
| 1129 | // WAR since linker log does not seem to be constructed using a single call |
| 1130 | // to cuModuleLoadDataEx. |
| 1131 | if (link_files.empty()) { |
| 1132 | result = |
| 1133 | cuModuleLoadDataEx(&_module, _ptx.c_str(), (unsigned)_opts.size(), |
| 1134 | _opts.data(), _optvals.data()); |
| 1135 | } else |
| 1136 | #endif |
| 1137 | { |
| 1138 | cuda_safe_call(cuLinkCreate((unsigned)_opts.size(), _opts.data(), |
| 1139 | _optvals.data(), &_link_state)); |
| 1140 | cuda_safe_call(cuLinkAddData(_link_state, CU_JIT_INPUT_PTX, |
| 1141 | (void*)_ptx.c_str(), _ptx.size(), |
| 1142 | "jitified_source.ptx", 0, 0, 0)); |
| 1143 | for (int i = 0; i < (int)link_files.size(); ++i) { |
| 1144 | std::string link_file = link_files[i]; |
| 1145 | CUjitInputType jit_input_type; |
| 1146 | if (link_file == ".") { |
| 1147 | // Special case for linking to current executable. |
| 1148 | link_file = get_current_executable_path(); |
| 1149 | jit_input_type = CU_JIT_INPUT_OBJECT; |
| 1150 | } else { |
| 1151 | // Infer based on filename. |
| 1152 | jit_input_type = get_cuda_jit_input_type(&link_file); |
| 1153 | } |
| 1154 | CUresult result = cuLinkAddFile(_link_state, jit_input_type, |
| 1155 | link_file.c_str(), 0, 0, 0); |
| 1156 | int path_num = 0; |
| 1157 | while (result == CUDA_ERROR_FILE_NOT_FOUND && |
| 1158 | path_num < (int)link_paths.size()) { |
nothing calls this directly
no test coverage detected