Я использую двоичный файл (R), который динамически связывается с общей версией BLAS,
например (и во многих случаях) это openBLAS.
Теперь внутри R я динамически загружаю другую общую библиотеку (libtorch.so), по существу используя dlopen(). Оказывается, libtorch статически ссылается на MKL BLAS.
Насколько я понимаю статическое и динамическое связывание, это не должно быть проблемой. Т.е. поскольку libtorch статически связан с MKL. При вызове кода libtorch он всегда будет отдавать предпочтение своим собственным символам, а не другим символам с похожими именами, которые могут быть загружены динамически.
Действительно, это обычное поведение. Например, если я уберу BLAS и LibTorch из игры, я смогу скомпилировать исполняемый файл, который ссылается на общую библиотеку libA, реализуя, например, print() и на другую общую библиотеку libB, которая статически связана с libA. При вызове кода из libB он будет корректно вызывать определения из собственной версии libA.
Но этого не происходит с libtorch/MKL и openBLAS. Если я скомпилирую исполняемый файл, который динамически связывается как с libTorch, так и с openBlas, тогда libtorch начнет использовать процедуры openBLAS вместо статически связанных процедур MKL.
Например:
#0 0x00007ffff5537da0 in sgemm_ () from /lib/x86_64-linux-gnu/libopenblas.so.0
#1 0x00007fffde5385d6 in at::native::cpublas::gemm(at::native::TransposeType, at::native::TransposeType, long, long, long, float, float const*, long, float const*, long, float, float*, long) () from /home/rstudio/data/torch/build-lantern/libtorch/lib/libtorch_cpu.so
#2 0x00007fffde67c139 in at::native::addmm_impl_cpu_(at::Tensor&, at::Tensor const&, at::Tensor, at::Tensor, c10::Scalar const&, c10::Scalar const&) () from /home/rstudio/data/torch/build-lantern/libtorch/lib/libtorch_cpu.so
#3 0x00007fffde67d475 in at::native::structured_mm_out_cpu::impl(at::Tensor const&, at::Tensor const&, at::Tensor const&) ()
from /home/rstudio/data/torch/build-lantern/libtorch/lib/libtorch_cpu.so
#4 0x00007fffdf42309b in at::(anonymous namespace)::wrapper_CPU_mm(at::Tensor const&, at::Tensor const&) ()
from /home/rstudio/data/torch/build-lantern/libtorch/lib/libtorch_cpu.so
#5 0x00007fffdf423123 in c10::impl::wrap_kernel_functor_unboxed_::call(c10::OperatorKernel*, c10::DispatchKeySet, at::Tensor const&, at::Tensor const&) () from /home/rstudio/data/torch/build-lantern/libtorch/lib/libtorch_cpu.so
#6 0x00007fffdf1eaa70 in at::_ops::mm::redispatch(c10::DispatchKeySet, at::Tensor const&, at::Tensor const&) ()
from /home/rstudio/data/torch/build-lantern/libtorch/lib/libtorch_cpu.so
Это происходит, даже если libtorch_cpu.so включает собственную версию sgemm_, например:
nm libtorch/lib/libtorch_cpu.so | grep "T sgemm_"
0000000006c531b0 T sgemm_
0000000006c53870 T sgemm_64
0000000006c53870 T sgemm_64_
Мой вопрос: при каких обстоятельствах символы из динамически загружаемой библиотеки могут оказаться перед статически загружаемой библиотекой? Я наверняка упускаю здесь что-то важное, и любой совет будет чрезвычайно полезен.
Воспроизводимый пример:
#include
#include
#include
extern "C" void execute () {
for (auto i = 1; i < 10; i++) {
torch::Tensor tensor = torch::randn({2000, 2000});
auto k = tensor.mm(tensor);
}
}
int main() {
execute();
int m = 3; // rows of A
int n = 3; // cols of A
// Matrix A (m x n) in row-major order
double A[] = {1.0, 2.0, 3.0,
4.0, 5.0, 6.0,
7.0, 8.0, 9.0};
// Vector x (size n)
double x[] = {1.0, 1.0, 1.0};
// Result vector y (size m), initially zero
double y[] = {0.0, 0.0, 0.0};
// Scalar multipliers
double alpha = 1.0, beta = 0.0;
// Perform y = alpha * A * x + beta * y
cblas_dgemv(CblasRowMajor, CblasNoTrans, m, n, alpha, A, n, x, 1, beta, y, 1);
return 0;
}
С помощью CMakeLists.txt
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(example)
find_package(Torch REQUIRED)
find_package(BLAS)
add_executable(example example.cpp)
target_link_libraries(example "${TORCH_LIBRARIES}" "${BLAS_LIBRARIES}")
set_property(TARGET example PROPERTY CXX_STANDARD 17)
LibTorch можно получить на веб-сайте pytorch по прямой ссылке для скачивания.
Для запуска
mkdir build && cd build
cmake .. -DCMAKE_PREFIX_PATH=
cmake --build .
Подробнее здесь: https://stackoverflow.com/questions/791 ... ut-linking
Взаимодействие MKL и openBLAS – вопрос о связывании ⇐ C++
Программы на C++. Форум разработчиков
-
Anonymous
1731375863
Anonymous
Я использую двоичный файл (R), который динамически связывается с общей версией BLAS,
например (и во многих случаях) это openBLAS.
Теперь внутри R я динамически загружаю другую общую библиотеку (libtorch.so), по существу используя dlopen(). Оказывается, libtorch статически ссылается на MKL BLAS.
Насколько я понимаю статическое и динамическое связывание, это не должно быть проблемой. Т.е. поскольку libtorch статически связан с MKL. При вызове кода libtorch он всегда будет отдавать предпочтение своим собственным символам, а не другим символам с похожими именами, которые могут быть загружены динамически.
Действительно, это обычное поведение. Например, если я уберу BLAS и LibTorch из игры, я смогу скомпилировать исполняемый файл, который ссылается на общую библиотеку libA, реализуя, например, print() и на другую общую библиотеку libB, которая статически связана с libA. При вызове кода из libB он будет корректно вызывать определения из собственной версии libA.
Но этого не происходит с libtorch/MKL и openBLAS. Если я скомпилирую исполняемый файл, который динамически связывается как с libTorch, так и с openBlas, тогда libtorch начнет использовать процедуры openBLAS вместо статически связанных процедур MKL.
Например:
#0 0x00007ffff5537da0 in sgemm_ () from /lib/x86_64-linux-gnu/libopenblas.so.0
#1 0x00007fffde5385d6 in at::native::cpublas::gemm(at::native::TransposeType, at::native::TransposeType, long, long, long, float, float const*, long, float const*, long, float, float*, long) () from /home/rstudio/data/torch/build-lantern/libtorch/lib/libtorch_cpu.so
#2 0x00007fffde67c139 in at::native::addmm_impl_cpu_(at::Tensor&, at::Tensor const&, at::Tensor, at::Tensor, c10::Scalar const&, c10::Scalar const&) () from /home/rstudio/data/torch/build-lantern/libtorch/lib/libtorch_cpu.so
#3 0x00007fffde67d475 in at::native::structured_mm_out_cpu::impl(at::Tensor const&, at::Tensor const&, at::Tensor const&) ()
from /home/rstudio/data/torch/build-lantern/libtorch/lib/libtorch_cpu.so
#4 0x00007fffdf42309b in at::(anonymous namespace)::wrapper_CPU_mm(at::Tensor const&, at::Tensor const&) ()
from /home/rstudio/data/torch/build-lantern/libtorch/lib/libtorch_cpu.so
#5 0x00007fffdf423123 in c10::impl::wrap_kernel_functor_unboxed_::call(c10::OperatorKernel*, c10::DispatchKeySet, at::Tensor const&, at::Tensor const&) () from /home/rstudio/data/torch/build-lantern/libtorch/lib/libtorch_cpu.so
#6 0x00007fffdf1eaa70 in at::_ops::mm::redispatch(c10::DispatchKeySet, at::Tensor const&, at::Tensor const&) ()
from /home/rstudio/data/torch/build-lantern/libtorch/lib/libtorch_cpu.so
Это происходит, даже если libtorch_cpu.so включает собственную версию sgemm_, например:
nm libtorch/lib/libtorch_cpu.so | grep "T sgemm_"
0000000006c531b0 T sgemm_
0000000006c53870 T sgemm_64
0000000006c53870 T sgemm_64_
Мой вопрос: при каких обстоятельствах символы из динамически загружаемой библиотеки могут оказаться перед статически загружаемой библиотекой? Я наверняка упускаю здесь что-то важное, и любой совет будет чрезвычайно полезен.
Воспроизводимый пример:
#include
#include
#include
extern "C" void execute () {
for (auto i = 1; i < 10; i++) {
torch::Tensor tensor = torch::randn({2000, 2000});
auto k = tensor.mm(tensor);
}
}
int main() {
execute();
int m = 3; // rows of A
int n = 3; // cols of A
// Matrix A (m x n) in row-major order
double A[] = {1.0, 2.0, 3.0,
4.0, 5.0, 6.0,
7.0, 8.0, 9.0};
// Vector x (size n)
double x[] = {1.0, 1.0, 1.0};
// Result vector y (size m), initially zero
double y[] = {0.0, 0.0, 0.0};
// Scalar multipliers
double alpha = 1.0, beta = 0.0;
// Perform y = alpha * A * x + beta * y
cblas_dgemv(CblasRowMajor, CblasNoTrans, m, n, alpha, A, n, x, 1, beta, y, 1);
return 0;
}
С помощью CMakeLists.txt
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(example)
find_package(Torch REQUIRED)
find_package(BLAS)
add_executable(example example.cpp)
target_link_libraries(example "${TORCH_LIBRARIES}" "${BLAS_LIBRARIES}")
set_property(TARGET example PROPERTY CXX_STANDARD 17)
LibTorch можно получить на веб-сайте pytorch по прямой ссылке для скачивания.
Для запуска
mkdir build && cd build
cmake .. -DCMAKE_PREFIX_PATH=
cmake --build .
Подробнее здесь: [url]https://stackoverflow.com/questions/79171784/mkl-and-openblas-interactions-a-question-about-linking[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия