Стоит у меня старенькая HD4850. Скорее из спортивного интереса нежели из необходимости, хочу завести субж. Хотя, надо добавить к этому «дано» ещё одно условие: gentoo без всяких оверлеев (не люблю я их, проблем они создают, как правило, больше чем решают). Сразу отмечу, что на данном этапе я констатирую фейл. Отчасти поэтому и пишу, может кто подскажет чего?
Теперь немного о деталях. Естественно, на все пакеты которые так или иначе могут влиять (mesa, llvm, clang) я повесил keywords ~amd64, дабы собирались последние. К mesa добавил USE=opencl. VIDEO_CARDS=«radeon r600» в make.conf прописано, так что llvm собирается с таргетом r600. Долго мне не удавалось запустить hello_world из opencl-example: он писал что-то про то, что ни одного GPU не было найдено. Так происходило ровно до тех пор, пока я не напоролся на упоминание /etc/opencl/vendors, заглянул туда, почитал, что интернет об этом пишет, добавил туда файлик mesa.icd, с содержимым /usr/lib64/OpenCL/vendors/mesa/libOpenCL.so, и вуаля: hello_world упал с SIGSEGV! Превосходно, казалось бы, дело сдвинулось с мёртвой точки. Но вот теперь я окончательно в ступоре:
gdb ./hello_world GNU gdb (Gentoo 7.6.2 p1) 7.6.2 Copyright © 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-pc-linux-gnu". For bug reporting instructions, please see: <http://bugs.gentoo.org/>... Reading symbols from /home/rgo/src/opencl-example/hello_world...done. (gdb) run Starting program: /home/rgo/src/opencl-example/./hello_world warning: Could not load shared library symbols for linux-vdso.so.1. Do you need "set solib-search-path" or "set sysroot"? Warning: couldn't activate thread debugging using libthread_db: Cannot find new threads: generic error Warning: couldn't activate thread debugging using libthread_db: Cannot find new threads: generic error warning: Unable to find libthread_db matching inferior's thread library, thread debugging will not be available.
Program received signal SIGSEGV, Segmentation fault. 0x00007ffff718d737 in std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&) () from /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/libstdc++.so.6 (gdb) bt #0 0x00007ffff718d737 in std::_Rb_tree_insert_and_rebalance(bool, std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::_Rb_tree_node_base&) () from /usr/lib/gcc/x86_64-pc-linux-gnu/4.7.3/libstdc++.so.6 #1 0x00007ffff203584e in std::_Rb_tree<void const*, std::pair<void const* const, llvm::PassInfo const*>, std::_Select1st<std::pair<void const* const, llvm::PassInfo const*> >, std::less<void const*>, std::allocator<std::pair<void const* const, llvm::PassInfo const*> > >::_M_insert_(std::_Rb_tree_node_base const*, std::_Rb_tree_node_base const*, std::pair<void const* const, llvm::PassInfo const*> const&) () from /usr/lib64/OpenCL/vendors/intel/libclang_compiler.so #2 0x00007ffff2034f37 in llvm::PassRegistry::registerPass(llvm::PassInfo const&) () from /usr/lib64/OpenCL/vendors/intel/libclang_compiler.so #3 0x00007ffff26cfea7 in global constructors keyed to ScalarEvolution.cpp () from /usr/lib64/OpenCL/vendors/intel/libclang_compiler.so #4 0x00007ffff2704346 in __do_global_ctors_aux () from /usr/lib64/OpenCL/vendors/intel/libclang_compiler.so #5 0x00007ffff19b82d3 in _init () from /usr/lib64/OpenCL/vendors/intel/libclang_compiler.so #6 0x0000000000000000 in ?? () (gdb)
Там поначалу какие-то странные варнинги gdb — я ещё не разбирался с чего это он. Но не думаю что они как-то существенно корёжат картину. Видно, что шланговская шаред-библиотека, отрабатывая свой _init при загрузке, пытается что-то добавить в какое-то rbtree (какой-то реестр), и вылетает, вероятно обратившись к нулевому адресу.
По-хорошему, надо лезть и дебажить, но (факамаза) трындец как лень. К стыду своему я даже вынужден признать, что не знаю как повесть бряк на _init ещё не подгруженной библиотеки, к ещё большему стыду, признаю и то, что мне это абсолютно неинтересно и, поэтому, лень читать из-за этого документацию. Поэтому весьма надеюсь решить проблему методом тыка, но при этом, я в прострации.
Меня зело смущает фраза: «LLVM builds all supported targets by default, so adding --enable-targets=x86 will speed up the build time. NOTE: Mesa requires the X86 target to be built» здесь. А если у меня x86_64, мне тоже нужен x86 в качестве таргета? Есть ещё подозрение, что быть может как-то так вышло, что шланговый abi в чём-то несовместим с g++’овым? Ведь mesa-то у меня собрана при помощи gcc, да и шланг с llvm тоже, скорее всего. То есть, даже если так, вряд ли оно могло повлиять в данной ситуации, но хз.
Может у кого ещё какие идеи есть?
Последние комментарии
- OlegL, 17 декабря 2023 года в 15:00 → Перекличка 21
- REDkiy, 8 июня 2023 года в 9:09 → Как «замокать» файл для юниттеста в Python? 2
- fhunter, 29 ноября 2022 года в 2:09 → Проблема с NO_PUBKEY: как получить GPG-ключ и добавить его в базу apt? 6
- Иванн, 9 апреля 2022 года в 8:31 → Ассоциация РАСПО провела первое учредительное собрание 1
- Kiri11.ADV1, 7 марта 2021 года в 12:01 → Логи catalina.out в TomCat 9 в формате JSON 1
На правах блога.
Чтобы отлаживать _init в подгружаемом so, надо сделать: set stop-on-solib-event 1, затем кидать команды continue, до тех пор, пока gdb не тормознёт на нужной библиотеке, после чего сказать: breakpoint _init. Элементарно.
Поковырялся, выяснил что у меня зачем-то установлен был intel’овский opencl, и происходила путаница в библиотеках.Подгружался именно интеловский libOpenCL.so. Удалил /etc/OpenCL/vendors/intelocl64.icd, SIGSEGV стал вылетать из недр libc’ового printf’а, при ближайшем рассмотрении выяснилось, что clGetPlatformIDs возвращает ошибку -1001, а clUtilErrorString в ответ на -1001 возвращает мусорный указатель (бага-бага!). Собственно, присмотревшись повнимательнее, я понял, что несмотря на чистку /etc/OpenCL/vendors, всё равно подгружается не тот libOpenCL, разбираться дальше я не стал. Снёс к чертям intel’овский sdk, всё равно не нужен. Потом пришлось вписать /usr/lib64/OpenCL/vendors/mesa в /etc/ld.conf. Теперь подгружается нужный libOpenCL.so, SIGSEGV прекратились, но я получаю «clGetDeviceIDs() failed: CL_DEVICE_NOT_FOUND».
По мотивам сего патча, прошёлся отладчиком (патч было влом накладывать). Выяснил, что всё, вроде работает, и /usr/lib64/gallium-pipe/pipe_r600.so подгружается успешно… Это печально, поскольку означает, что придётся лезть в сорцы и выяснять там в каком-таком месте происходит затык.
Собственно вот. После всех этих разборок с подгрузкой библиотек, всё видимо заработало как надо. И CL_DEVICE_NOT_FOUND — это уже вердикт: mesa не умеет OpenCL на HD4850. Облом-с. Собственно если глянуть на табличку тут, то HD4850 попадает в столбец r700, где сплошные красные TODO. Странно, о чём я раньше думал… Табличку эту разглядывал, и не понял, что мою видяшку завести не удастся. Причём, вероятно, никогда не удастся: HD6xxx уже переползают на вторичный рынок и продолжают потихоньку падать в цене. Так что для OpenCL проще купить HD69xx, и взвести её под именем Northern Islands, чем возиться с поддержкой совсем уж старья.