| 158 | } |
| 159 | |
| 160 | LinkedLibraryHolder::LinkedLibraryHolder() : availablePlatforms{"default"} { |
| 161 | ScopedTraceWithContext("LinkedLibraryHolder::constructor"); |
| 162 | CUDAQ_INFO("Init infrastructure for pythonic builder."); |
| 163 | |
| 164 | if (!cudaq::detail::canModifyTarget()) |
| 165 | return; |
| 166 | |
| 167 | cudaq::detail::CUDAQLibraryData data; |
| 168 | #if defined(__APPLE__) && defined(__MACH__) |
| 169 | libSuffix = "dylib"; |
| 170 | cudaq::detail::getCUDAQLibraryPath(&data); |
| 171 | #else |
| 172 | libSuffix = "so"; |
| 173 | dl_iterate_phdr(cudaq::detail::getCUDAQLibraryPath, &data); |
| 174 | #endif |
| 175 | |
| 176 | std::filesystem::path nvqirLibPath{data.path}; |
| 177 | cudaqLibPath = nvqirLibPath.parent_path(); |
| 178 | if (cudaqLibPath.filename().string() == "common") { |
| 179 | // this is a build path |
| 180 | cudaqLibPath = cudaqLibPath.parent_path().parent_path() / "lib"; |
| 181 | } |
| 182 | |
| 183 | // Populate the map of available targets. |
| 184 | { |
| 185 | ScopedTraceWithContext("findAvailableTargets"); |
| 186 | auto targetPath = cudaqLibPath.parent_path() / "targets"; |
| 187 | findAvailableTargets(targetPath, targets, simulationTargets); |
| 188 | } |
| 189 | |
| 190 | CUDAQ_INFO("Init: Library Path is {}.", cudaqLibPath.string()); |
| 191 | |
| 192 | // Load nvqir, cudaq, and the default execution manager. The em cannot |
| 193 | // be a needed dep of libcudaq.so (circular dependency), but downstream |
| 194 | // libraries like cuda-qx reference its symbols at dlopen time. |
| 195 | std::vector<std::filesystem::path> libPaths{ |
| 196 | cudaqLibPath / fmt::format("libnvqir.{}", libSuffix), |
| 197 | cudaqLibPath / fmt::format("libcudaq.{}", libSuffix), |
| 198 | cudaqLibPath / fmt::format("libcudaq-em-default.{}", libSuffix)}; |
| 199 | |
| 200 | const char *dynlibs_var = std::getenv("CUDAQ_DYNLIBS"); |
| 201 | if (dynlibs_var != nullptr) { |
| 202 | std::string dynlib; |
| 203 | std::stringstream ss((std::string(dynlibs_var))); |
| 204 | while (std::getline(ss, dynlib, ':')) { |
| 205 | CUDAQ_INFO("Init: add dynamic library path {}.", dynlib); |
| 206 | libPaths.push_back(dynlib); |
| 207 | } |
| 208 | } |
| 209 | |
| 210 | // Load all the defaults |
| 211 | { |
| 212 | ScopedTraceWithContext("dlopen_core_and_dynlibs"); |
| 213 | for (auto &p : libPaths) { |
| 214 | void *libHandle = dlopen(p.string().c_str(), RTLD_GLOBAL | RTLD_NOW); |
| 215 | if (libHandle) { |
| 216 | libHandles.emplace(p.string(), libHandle); |
| 217 | } else { |
nothing calls this directly
no test coverage detected