sglang_v0.5.2/pytorch_2.8.0/third_party/NVTX/tests/PathHelper.h

225 lines
6.2 KiB
C++

/*
* SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Licensed under the Apache License v2.0 with LLVM Exceptions.
* See https://nvidia.github.io/NVTX/LICENSE.txt for license information.
*/
#pragma once
/* Dynamic libraries should be loaded with absolute paths to avoid
* problems not finding things in the search paths. Construct the
* absolute path to a dynamic library in the same directory as the
* process's executable, or some subdirectory of it, using these
* utility functions. C++17's std::filesystem makes this much
* easier, but these utilities should work in C++11.
*/
#if defined(_WIN32)
#include <windows.h>
#else
#if defined(__CYGWIN__)
#if defined(__POSIX_VISIBLE)
#if __POSIX_VISIBLE < 200112L
#error On Cygwin, you must `#define _POSIX_C_SOURCE 200112L` or greater before including any headers so that readlink() is available. You can achieve this by including this header before any others.
#endif
#endif
#if defined(_POSIX_C_SOURCE)
#undef _POSIX_C_SOURCE
#endif
#define _POSIX_C_SOURCE 200809L
#endif
#include <unistd.h>
#endif
#if defined(__APPLE__)
#include <libproc.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
#include "DllHelper.h"
#if defined(_WIN32)
constexpr char pathSep = '\\';
#else
constexpr char pathSep = '/';
#endif
// Adapted from C functions in NVTXW implementation
static std::string GetCurrentProcessPath(void);
static std::string GetCurrentProcessPath(void)
{
char* buf;
#if defined(_WIN32)
{
DWORD size = MAX_PATH;
DWORD newSize;
buf = nullptr;
while (1)
{
buf = static_cast<char*>(realloc(buf, size));
if (!buf)
{
return nullptr;
}
newSize = GetModuleFileNameA(nullptr, buf, size);
if (newSize < size)
{
break;
}
size *= 2;
}
}
#elif defined(__APPLE__)
{
int ret;
pid_t pid = getpid();
buf = static_cast<char*>(malloc(PROC_PIDPATHINFO_MAXSIZE));
if (!buf)
{
return nullptr;
}
ret = proc_pidpath(pid, buf, PROC_PIDPATHINFO_MAXSIZE);
if (ret == 0)
{
free(buf);
return nullptr;
}
}
#elif defined(__QNX__)
{
size_t size = fpathconf(0, _PC_MAX_INPUT);
if (size <= 0)
{
size = 4096;
}
++size;
buf = static_cast<char*>(malloc(size));
if (!buf)
{
return nullptr;
}
_cmdname(buf);
}
#else
{
size_t size = 1024;
ssize_t bytesReadSigned;
size_t bytesRead;
static const char linkName[] = "/proc/self/exe";
buf = nullptr;
while (1)
{
buf = static_cast<char*>(realloc(buf, size));
if (!buf)
{
return nullptr;
}
bytesReadSigned = readlink(linkName, buf, size);
if (bytesReadSigned < 0)
{
free(buf);
return nullptr;
}
bytesRead = static_cast<size_t>(bytesReadSigned);
if (bytesRead < size) break;
size *= 2;
}
buf[bytesRead] = '\0';
}
#endif
std::string result;
if (buf)
{
result = buf;
free(buf);
}
return result;
}
/*
* We know the absolute path must have at least one slash in it,
* right before the exe filename. So we can truncate the string
* to end just after the last slash, and append other file or
* directory names. Examples:
* C:\path\to\foo.exe -> C:\path\to\
* C:\foo.exe -> C:\
* /path/to/foo -> /path/to/
* /foo -> /
*/
static std::string GetCurrentProcessDirWithSep(void);
static std::string GetCurrentProcessDirWithSep(void)
{
std::string exeAbsPath = GetCurrentProcessPath();
exeAbsPath.resize(exeAbsPath.find_last_of(pathSep) + 1);
return exeAbsPath;
}
/*
* Take the absolute path to the current process's executable,
* remove the executable's name, and then append the library
* filename. Applies the standard dynamic library prefix and
* suffix to the library's base name, but the suffix may be
* overridden if it isn't the standard one (e.g. ".so.1.1").
* If subDirs has any entries, they are added between the
* directory and the library name, with path separators added
* between each. Examples:
* (Assuming process is C:\path\to\foo.exe on Windows)
* AbsolutePathToLibraryInCurrentProcessPath("example")
* -> C:\path\to\example.dll
* AbsolutePathToLibraryInCurrentProcessPath("example", {"nested", "deeper"})
* -> C:\path\to\nested\deeper\example.dll
* (Assuming process is /path/to/foo on Linux)
* AbsolutePathToLibraryInCurrentProcessPath("example")
* -> /path/to/libexample.so
* AbsolutePathToLibraryInCurrentProcessPath("example", {"nested", "deeper"}, ".so.1")
* -> /path/to/nested/deeper/libexample.so.1
*/
static std::string AbsolutePathToLibraryInCurrentProcessPath(
std::string libraryBaseName,
std::vector<std::string> subDirs = {},
std::string libSuffix = DLL_SUFFIX);
static std::string AbsolutePathToLibraryInCurrentProcessPath(
std::string libraryBaseName,
std::vector<std::string> subDirs,
std::string libSuffix)
{
std::string result = GetCurrentProcessDirWithSep();
for (auto const& subDir : subDirs)
{
result += subDir;
result += pathSep;
}
result += DLL_PREFIX;
result += libraryBaseName;
result += libSuffix;
return result;
}