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 namespace stream_executor {
30 namespace internal {
31
32 namespace {
GetCudaVersion()33 string GetCudaVersion() { return TF_CUDA_VERSION; }
GetCudaRtVersion()34 string GetCudaRtVersion() { return TF_CUDART_VERSION; }
GetCudnnVersion()35 string GetCudnnVersion() { return TF_CUDNN_VERSION; }
GetCublasVersion()36 string GetCublasVersion() { return TF_CUBLAS_VERSION; }
GetCusolverVersion()37 string GetCusolverVersion() { return TF_CUSOLVER_VERSION; }
GetCurandVersion()38 string GetCurandVersion() { return TF_CURAND_VERSION; }
GetCufftVersion()39 string GetCufftVersion() { return TF_CUFFT_VERSION; }
GetCusparseVersion()40 string GetCusparseVersion() { return TF_CUSPARSE_VERSION; }
GetTensorRTVersion()41 string GetTensorRTVersion() { return TF_TENSORRT_VERSION; }
42
GetDsoHandle(const string & name,const string & version)43 port::StatusOr<void*> GetDsoHandle(const string& name, const string& version) {
44 auto filename = port::Env::Default()->FormatLibraryFileName(name, version);
45 void* dso_handle;
46 port::Status status =
47 port::Env::Default()->LoadDynamicLibrary(filename.c_str(), &dso_handle);
48 if (status.ok()) {
49 LOG(INFO) << "Successfully opened dynamic library " << filename;
50 return dso_handle;
51 }
52
53 auto message = absl::StrCat("Could not load dynamic library '", filename,
54 "'; dlerror: ", status.error_message());
55 #if !defined(PLATFORM_WINDOWS)
56 if (const char* ld_library_path = getenv("LD_LIBRARY_PATH")) {
57 message += absl::StrCat("; LD_LIBRARY_PATH: ", ld_library_path);
58 }
59 #endif
60 LOG(WARNING) << message;
61 return port::Status(port::error::FAILED_PRECONDITION, message);
62 }
63 } // namespace
64
65 namespace DsoLoader {
GetCudaDriverDsoHandle()66 port::StatusOr<void*> GetCudaDriverDsoHandle() {
67 #if defined(PLATFORM_WINDOWS)
68 return GetDsoHandle("nvcuda", "");
69 #elif defined(__APPLE__)
70 // On Mac OS X, CUDA sometimes installs libcuda.dylib instead of
71 // libcuda.1.dylib.
72 auto handle_or = GetDsoHandle("cuda", "");
73 if (handle_or.ok()) {
74 return handle_or;
75 }
76 #endif
77 return GetDsoHandle("cuda", "1");
78 }
79
GetCudaRuntimeDsoHandle()80 port::StatusOr<void*> GetCudaRuntimeDsoHandle() {
81 return GetDsoHandle("cudart", GetCudaRtVersion());
82 }
83
GetCublasDsoHandle()84 port::StatusOr<void*> GetCublasDsoHandle() {
85 return GetDsoHandle("cublas", GetCublasVersion());
86 }
87
GetCublasLtDsoHandle()88 port::StatusOr<void*> GetCublasLtDsoHandle() {
89 return GetDsoHandle("cublasLt", GetCublasVersion());
90 }
91
GetCufftDsoHandle()92 port::StatusOr<void*> GetCufftDsoHandle() {
93 return GetDsoHandle("cufft", GetCufftVersion());
94 }
95
GetCusolverDsoHandle()96 port::StatusOr<void*> GetCusolverDsoHandle() {
97 return GetDsoHandle("cusolver", GetCusolverVersion());
98 }
99
GetCusparseDsoHandle()100 port::StatusOr<void*> GetCusparseDsoHandle() {
101 return GetDsoHandle("cusparse", GetCusparseVersion());
102 }
103
GetCurandDsoHandle()104 port::StatusOr<void*> GetCurandDsoHandle() {
105 return GetDsoHandle("curand", GetCurandVersion());
106 }
107
GetCuptiDsoHandle()108 port::StatusOr<void*> GetCuptiDsoHandle() {
109 // Load specific version of CUPTI this is built.
110 auto status_or_handle = GetDsoHandle("cupti", GetCudaVersion());
111 if (status_or_handle.ok()) return status_or_handle;
112 // Load whatever libcupti.so user specified.
113 return GetDsoHandle("cupti", "");
114 }
115
GetCudnnDsoHandle()116 port::StatusOr<void*> GetCudnnDsoHandle() {
117 return GetDsoHandle("cudnn", GetCudnnVersion());
118 }
119
GetNvInferDsoHandle()120 port::StatusOr<void*> GetNvInferDsoHandle() {
121 return GetDsoHandle("nvinfer", GetTensorRTVersion());
122 }
123
GetNvInferPluginDsoHandle()124 port::StatusOr<void*> GetNvInferPluginDsoHandle() {
125 return GetDsoHandle("nvinfer_plugin", GetTensorRTVersion());
126 }
127
GetRocblasDsoHandle()128 port::StatusOr<void*> GetRocblasDsoHandle() {
129 return GetDsoHandle("rocblas", "");
130 }
131
GetMiopenDsoHandle()132 port::StatusOr<void*> GetMiopenDsoHandle() {
133 return GetDsoHandle("MIOpen", "");
134 }
135
GetRocfftDsoHandle()136 port::StatusOr<void*> GetRocfftDsoHandle() {
137 return GetDsoHandle("rocfft", "");
138 }
139
GetRocrandDsoHandle()140 port::StatusOr<void*> GetRocrandDsoHandle() {
141 return GetDsoHandle("rocrand", "");
142 }
143
GetHipsparseDsoHandle()144 port::StatusOr<void*> GetHipsparseDsoHandle() {
145 return GetDsoHandle("hipsparse", "");
146 }
147
GetHipDsoHandle()148 port::StatusOr<void*> GetHipDsoHandle() { return GetDsoHandle("amdhip64", ""); }
149
150 } // namespace DsoLoader
151
152 namespace CachedDsoLoader {
GetCudaDriverDsoHandle()153 port::StatusOr<void*> GetCudaDriverDsoHandle() {
154 static auto result = new auto(DsoLoader::GetCudaDriverDsoHandle());
155 return *result;
156 }
157
GetCudaRuntimeDsoHandle()158 port::StatusOr<void*> GetCudaRuntimeDsoHandle() {
159 static auto result = new auto(DsoLoader::GetCudaRuntimeDsoHandle());
160 return *result;
161 }
162
GetCublasDsoHandle()163 port::StatusOr<void*> GetCublasDsoHandle() {
164 static auto result = new auto(DsoLoader::GetCublasDsoHandle());
165 return *result;
166 }
167
GetCublasLtDsoHandle()168 port::StatusOr<void*> GetCublasLtDsoHandle() {
169 static auto result = new auto(DsoLoader::GetCublasLtDsoHandle());
170 return *result;
171 }
172
GetCurandDsoHandle()173 port::StatusOr<void*> GetCurandDsoHandle() {
174 static auto result = new auto(DsoLoader::GetCurandDsoHandle());
175 return *result;
176 }
177
GetCufftDsoHandle()178 port::StatusOr<void*> GetCufftDsoHandle() {
179 static auto result = new auto(DsoLoader::GetCufftDsoHandle());
180 return *result;
181 }
182
GetCusolverDsoHandle()183 port::StatusOr<void*> GetCusolverDsoHandle() {
184 static auto result = new auto(DsoLoader::GetCusolverDsoHandle());
185 return *result;
186 }
187
GetCusparseDsoHandle()188 port::StatusOr<void*> GetCusparseDsoHandle() {
189 static auto result = new auto(DsoLoader::GetCusparseDsoHandle());
190 return *result;
191 }
192
GetCuptiDsoHandle()193 port::StatusOr<void*> GetCuptiDsoHandle() {
194 static auto result = new auto(DsoLoader::GetCuptiDsoHandle());
195 return *result;
196 }
197
GetCudnnDsoHandle()198 port::StatusOr<void*> GetCudnnDsoHandle() {
199 static auto result = new auto(DsoLoader::GetCudnnDsoHandle());
200 return *result;
201 }
202
GetRocblasDsoHandle()203 port::StatusOr<void*> GetRocblasDsoHandle() {
204 static auto result = new auto(DsoLoader::GetRocblasDsoHandle());
205 return *result;
206 }
207
GetMiopenDsoHandle()208 port::StatusOr<void*> GetMiopenDsoHandle() {
209 static auto result = new auto(DsoLoader::GetMiopenDsoHandle());
210 return *result;
211 }
212
GetRocfftDsoHandle()213 port::StatusOr<void*> GetRocfftDsoHandle() {
214 static auto result = new auto(DsoLoader::GetRocfftDsoHandle());
215 return *result;
216 }
217
GetRocrandDsoHandle()218 port::StatusOr<void*> GetRocrandDsoHandle() {
219 static auto result = new auto(DsoLoader::GetRocrandDsoHandle());
220 return *result;
221 }
222
GetHipsparseDsoHandle()223 port::StatusOr<void*> GetHipsparseDsoHandle() {
224 static auto result = new auto(DsoLoader::GetHipsparseDsoHandle());
225 return *result;
226 }
227
GetHipDsoHandle()228 port::StatusOr<void*> GetHipDsoHandle() {
229 static auto result = new auto(DsoLoader::GetHipDsoHandle());
230 return *result;
231 }
232
233 } // namespace CachedDsoLoader
234 } // namespace internal
235 } // namespace stream_executor
236