1 /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 #include "tensorflow/stream_executor/platform/default/dso_loader.h"
16
17 #include <stdlib.h>
18
19 #include "absl/strings/str_cat.h"
20 #include "absl/strings/string_view.h"
21 #include "third_party/gpus/cuda/cuda_config.h"
22 #include "tensorflow/stream_executor/lib/env.h"
23 #include "tensorflow/stream_executor/lib/error.h"
24 #include "tensorflow/stream_executor/lib/path.h"
25 #include "tensorflow/stream_executor/platform/logging.h"
26 #include "tensorflow/stream_executor/platform/port.h"
27 #include "third_party/tensorrt/tensorrt_config.h"
28
29 #if TENSORFLOW_USE_ROCM
30 #include "rocm/rocm_config.h"
31 #endif
32
33 namespace stream_executor {
34 namespace internal {
35
36 namespace {
GetCudaVersion()37 string GetCudaVersion() { return TF_CUDA_VERSION; }
GetCudaRtVersion()38 string GetCudaRtVersion() { return TF_CUDART_VERSION; }
GetCudnnVersion()39 string GetCudnnVersion() { return TF_CUDNN_VERSION; }
GetCublasVersion()40 string GetCublasVersion() { return TF_CUBLAS_VERSION; }
GetCusolverVersion()41 string GetCusolverVersion() { return TF_CUSOLVER_VERSION; }
GetCurandVersion()42 string GetCurandVersion() { return TF_CURAND_VERSION; }
GetCufftVersion()43 string GetCufftVersion() { return TF_CUFFT_VERSION; }
GetCusparseVersion()44 string GetCusparseVersion() { return TF_CUSPARSE_VERSION; }
GetTensorRTVersion()45 string GetTensorRTVersion() { return TF_TENSORRT_VERSION; }
46
GetDsoHandle(const string & name,const string & version)47 port::StatusOr<void*> GetDsoHandle(const string& name, const string& version) {
48 auto filename = port::Env::Default()->FormatLibraryFileName(name, version);
49 void* dso_handle;
50 port::Status status =
51 port::Env::Default()->LoadDynamicLibrary(filename.c_str(), &dso_handle);
52 if (status.ok()) {
53 VLOG(1) << "Successfully opened dynamic library " << filename;
54 return dso_handle;
55 }
56
57 auto message = absl::StrCat("Could not load dynamic library '", filename,
58 "'; dlerror: ", status.error_message());
59 #if !defined(PLATFORM_WINDOWS)
60 if (const char* ld_library_path = getenv("LD_LIBRARY_PATH")) {
61 message += absl::StrCat("; LD_LIBRARY_PATH: ", ld_library_path);
62 }
63 #endif
64 LOG(WARNING) << message;
65 return port::Status(port::error::FAILED_PRECONDITION, message);
66 }
67 } // namespace
68
69 namespace DsoLoader {
GetCudaDriverDsoHandle()70 port::StatusOr<void*> GetCudaDriverDsoHandle() {
71 #if defined(PLATFORM_WINDOWS)
72 return GetDsoHandle("nvcuda", "");
73 #elif defined(__APPLE__)
74 // On Mac OS X, CUDA sometimes installs libcuda.dylib instead of
75 // libcuda.1.dylib.
76 auto handle_or = GetDsoHandle("cuda", "");
77 if (handle_or.ok()) {
78 return handle_or;
79 }
80 #endif
81 return GetDsoHandle("cuda", "1");
82 }
83
GetCudaRuntimeDsoHandle()84 port::StatusOr<void*> GetCudaRuntimeDsoHandle() {
85 return GetDsoHandle("cudart", GetCudaRtVersion());
86 }
87
GetCublasDsoHandle()88 port::StatusOr<void*> GetCublasDsoHandle() {
89 return GetDsoHandle("cublas", GetCublasVersion());
90 }
91
GetCublasLtDsoHandle()92 port::StatusOr<void*> GetCublasLtDsoHandle() {
93 return GetDsoHandle("cublasLt", GetCublasVersion());
94 }
95
GetCufftDsoHandle()96 port::StatusOr<void*> GetCufftDsoHandle() {
97 return GetDsoHandle("cufft", GetCufftVersion());
98 }
99
GetCusolverDsoHandle()100 port::StatusOr<void*> GetCusolverDsoHandle() {
101 return GetDsoHandle("cusolver", GetCusolverVersion());
102 }
103
GetCusparseDsoHandle()104 port::StatusOr<void*> GetCusparseDsoHandle() {
105 return GetDsoHandle("cusparse", GetCusparseVersion());
106 }
107
GetCurandDsoHandle()108 port::StatusOr<void*> GetCurandDsoHandle() {
109 return GetDsoHandle("curand", GetCurandVersion());
110 }
111
GetCuptiDsoHandle()112 port::StatusOr<void*> GetCuptiDsoHandle() {
113 // Load specific version of CUPTI this is built.
114 auto status_or_handle = GetDsoHandle("cupti", GetCudaVersion());
115 if (status_or_handle.ok()) return status_or_handle;
116 // Load whatever libcupti.so user specified.
117 return GetDsoHandle("cupti", "");
118 }
119
GetCudnnDsoHandle()120 port::StatusOr<void*> GetCudnnDsoHandle() {
121 return GetDsoHandle("cudnn", GetCudnnVersion());
122 }
123
GetNvInferDsoHandle()124 port::StatusOr<void*> GetNvInferDsoHandle() {
125 return GetDsoHandle("nvinfer", GetTensorRTVersion());
126 }
127
GetNvInferPluginDsoHandle()128 port::StatusOr<void*> GetNvInferPluginDsoHandle() {
129 return GetDsoHandle("nvinfer_plugin", GetTensorRTVersion());
130 }
131
GetRocblasDsoHandle()132 port::StatusOr<void*> GetRocblasDsoHandle() {
133 return GetDsoHandle("rocblas", "");
134 }
135
GetMiopenDsoHandle()136 port::StatusOr<void*> GetMiopenDsoHandle() {
137 return GetDsoHandle("MIOpen", "");
138 }
139
GetHipfftDsoHandle()140 port::StatusOr<void*> GetHipfftDsoHandle() {
141 #if TF_ROCM_VERSION < 40100
142 return GetDsoHandle("rocfft", "");
143 #else
144 return GetDsoHandle("hipfft", "");
145 #endif
146 }
147
GetRocrandDsoHandle()148 port::StatusOr<void*> GetRocrandDsoHandle() {
149 return GetDsoHandle("rocrand", "");
150 }
151
GetRocsolverDsoHandle()152 port::StatusOr<void*> GetRocsolverDsoHandle() {
153 return GetDsoHandle("rocsolver", "");
154 }
155
GetRoctracerDsoHandle()156 port::StatusOr<void*> GetRoctracerDsoHandle() {
157 return GetDsoHandle("roctracer64", "");
158 }
159
GetHipsparseDsoHandle()160 port::StatusOr<void*> GetHipsparseDsoHandle() {
161 return GetDsoHandle("hipsparse", "");
162 }
163
GetHipDsoHandle()164 port::StatusOr<void*> GetHipDsoHandle() { return GetDsoHandle("amdhip64", ""); }
165
166 } // namespace DsoLoader
167
168 namespace CachedDsoLoader {
GetCudaDriverDsoHandle()169 port::StatusOr<void*> GetCudaDriverDsoHandle() {
170 static auto result = new auto(DsoLoader::GetCudaDriverDsoHandle());
171 return *result;
172 }
173
GetCudaRuntimeDsoHandle()174 port::StatusOr<void*> GetCudaRuntimeDsoHandle() {
175 static auto result = new auto(DsoLoader::GetCudaRuntimeDsoHandle());
176 return *result;
177 }
178
GetCublasDsoHandle()179 port::StatusOr<void*> GetCublasDsoHandle() {
180 static auto result = new auto(DsoLoader::GetCublasDsoHandle());
181 return *result;
182 }
183
GetCublasLtDsoHandle()184 port::StatusOr<void*> GetCublasLtDsoHandle() {
185 static auto result = new auto(DsoLoader::GetCublasLtDsoHandle());
186 return *result;
187 }
188
GetCurandDsoHandle()189 port::StatusOr<void*> GetCurandDsoHandle() {
190 static auto result = new auto(DsoLoader::GetCurandDsoHandle());
191 return *result;
192 }
193
GetCufftDsoHandle()194 port::StatusOr<void*> GetCufftDsoHandle() {
195 static auto result = new auto(DsoLoader::GetCufftDsoHandle());
196 return *result;
197 }
198
GetCusolverDsoHandle()199 port::StatusOr<void*> GetCusolverDsoHandle() {
200 static auto result = new auto(DsoLoader::GetCusolverDsoHandle());
201 return *result;
202 }
203
GetCusparseDsoHandle()204 port::StatusOr<void*> GetCusparseDsoHandle() {
205 static auto result = new auto(DsoLoader::GetCusparseDsoHandle());
206 return *result;
207 }
208
GetCuptiDsoHandle()209 port::StatusOr<void*> GetCuptiDsoHandle() {
210 static auto result = new auto(DsoLoader::GetCuptiDsoHandle());
211 return *result;
212 }
213
GetCudnnDsoHandle()214 port::StatusOr<void*> GetCudnnDsoHandle() {
215 static auto result = new auto(DsoLoader::GetCudnnDsoHandle());
216 return *result;
217 }
218
GetRocblasDsoHandle()219 port::StatusOr<void*> GetRocblasDsoHandle() {
220 static auto result = new auto(DsoLoader::GetRocblasDsoHandle());
221 return *result;
222 }
223
GetMiopenDsoHandle()224 port::StatusOr<void*> GetMiopenDsoHandle() {
225 static auto result = new auto(DsoLoader::GetMiopenDsoHandle());
226 return *result;
227 }
228
GetHipfftDsoHandle()229 port::StatusOr<void*> GetHipfftDsoHandle() {
230 static auto result = new auto(DsoLoader::GetHipfftDsoHandle());
231 return *result;
232 }
233
GetRocrandDsoHandle()234 port::StatusOr<void*> GetRocrandDsoHandle() {
235 static auto result = new auto(DsoLoader::GetRocrandDsoHandle());
236 return *result;
237 }
238
GetRoctracerDsoHandle()239 port::StatusOr<void*> GetRoctracerDsoHandle() {
240 static auto result = new auto(DsoLoader::GetRoctracerDsoHandle());
241 return *result;
242 }
243
GetRocsolverDsoHandle()244 port::StatusOr<void*> GetRocsolverDsoHandle() {
245 static auto result = new auto(DsoLoader::GetRocsolverDsoHandle());
246 return *result;
247 }
248
GetHipsparseDsoHandle()249 port::StatusOr<void*> GetHipsparseDsoHandle() {
250 static auto result = new auto(DsoLoader::GetHipsparseDsoHandle());
251 return *result;
252 }
253
GetHipDsoHandle()254 port::StatusOr<void*> GetHipDsoHandle() {
255 static auto result = new auto(DsoLoader::GetHipDsoHandle());
256 return *result;
257 }
258
259 } // namespace CachedDsoLoader
260 } // namespace internal
261 } // namespace stream_executor
262