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