Prints a warning if the ptxas at ptxas_path has known bugs. Only prints a warning the first time it's called for a particular value of ptxas_path. Locks on entry.
| 66 | // |
| 67 | // Locks on entry. |
| 68 | static void WarnIfBadPtxasVersion(const string& ptxas_path) { |
| 69 | static tensorflow::mutex mu(tensorflow::LINKER_INITIALIZED); |
| 70 | static std::unordered_set<string>* seen_ptxas_paths GUARDED_BY(mu) = |
| 71 | new std::unordered_set<string>(); |
| 72 | |
| 73 | tensorflow::mutex_lock lock(mu); |
| 74 | if (!seen_ptxas_paths->insert(ptxas_path).second) { |
| 75 | // Already checked this ptx binary, nothing to do. |
| 76 | return; |
| 77 | } |
| 78 | |
| 79 | tensorflow::SubProcess ptxas; |
| 80 | ptxas.SetProgram(ptxas_path, {ptxas_path, "--version"}); |
| 81 | ptxas.SetChannelAction(tensorflow::CHAN_STDOUT, tensorflow::ACTION_PIPE); |
| 82 | if (!ptxas.Start()) { |
| 83 | LOG(WARNING) << "Couldn't invoke " << ptxas_path << " --version"; |
| 84 | return; |
| 85 | } |
| 86 | |
| 87 | string out; |
| 88 | int exit_code = ptxas.Communicate(/*stdin_input=*/nullptr, &out, |
| 89 | /*stderr_output=*/nullptr); |
| 90 | if (exit_code != 0) { |
| 91 | LOG(WARNING) << "Running " << ptxas_path << " --version returned " |
| 92 | << exit_code; |
| 93 | return; |
| 94 | } |
| 95 | |
| 96 | int64 vmaj, vmin, vdot; |
| 97 | string vmaj_str, vmin_str, vdot_str; |
| 98 | if (!RE2::PartialMatch(out, R"(\bV(\d+)\.(\d+)\.(\d+)\b)", &vmaj_str, |
| 99 | &vmin_str, &vdot_str) || |
| 100 | !absl::SimpleAtoi(vmaj_str, &vmaj) || |
| 101 | !absl::SimpleAtoi(vmin_str, &vmin) || |
| 102 | !absl::SimpleAtoi(vdot_str, &vdot)) { |
| 103 | LOG(WARNING) << "Couldn't parse ptxas version in output of " << ptxas_path |
| 104 | << " --version:\n" |
| 105 | << out; |
| 106 | return; |
| 107 | } |
| 108 | |
| 109 | // We need ptxas >= 9.0 as a hard requirement, because we compile targeting |
| 110 | // PTX 6.0. An older ptxas will just fail to compile any of our code. |
| 111 | // |
| 112 | // ptxas 9.0 before 9.0.276 and ptxas 9.1 before 9.1.121 miscompile some |
| 113 | // address calculations with large offsets (e.g. "load ptr + large_constant"), |
| 114 | // b/70245379. |
| 115 | // |
| 116 | // ptxas 9.1.121 miscompiles some large multioutput fusions, again in a way |
| 117 | // that appears related to address calculations, b/111107644. ptxas 9.2.88 |
| 118 | // appears to work, as far as we can tell. |
| 119 | if (vmaj < 9) { |
| 120 | LOG(ERROR) |
| 121 | << "You are using ptxas 8.x, but TF requires ptxas 9.x (and strongly " |
| 122 | "prefers >= 9.2.88). Compilation of XLA kernels below will likely " |
| 123 | "fail.\n\nYou do not need to update CUDA; cherry-picking the ptxas " |
| 124 | "binary is sufficient."; |
| 125 | } else if (std::make_tuple(vmaj, vmin, vdot) < std::make_tuple(9, 2, 88)) { |
no test coverage detected