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