Современная наука невозможна без компьютерных вычислений — от обработки результатов измерений до моделирования процессов. Одним из наиболее широко используемых инструментов для вычислений в ядерной физике и физике высоких энергий является фреймворк ROOT, разрабатываемый в CERN.
Собственная архитектура e2k с очень длинной машинной командой VLIW не позволяет отечественным процессорам Эльбрус без портирования нативно запускать программное обеспечение, в том числе и ROOT.
В статье рассмотрим "айсберг" проблем, с которыми пришлось столкнуться в ходе портирования ROOT, а также сферу и примеры его применения.
Для чего и где используют ROOT?
Цель разработки ROOT заключается в создании удобной среды для обработки, хранения, визуализации и анализа научных данных в рамках единого программного пакета. ROOT написан для физиков, что делает его довольно доступным для тех, кто не готов глубоко погружаться в программирование.
Одной из отличительных особенностей является интерпретатор С++ Cling, позволяющий в интерактивном режиме работать с данными. Это удобно для быстрого просмотра и исправлений "на лету". А ещё есть возможность работы с графическим интерфейсом в TBrowser для чтения .root файлов.
Файлы .root - удобный способ сохранения данных или любого объекта C++ в сжатом бинарном виде. Хранение данных в виде "деревьев" отличное решение для быстрого доступа к огромным объемам данных, которые повсеместны в физике высоких энергий. Возможно объединение деревьев из разных файлов в единую цепочку для обработки. В каждом файле может содержаться несколько деревьев, состоящих из отдельных "ветвей". Конечной точкой веток являются переменные "листья". Пример одного из файлов .root, хранящий экспериментальные данные, полученные в эксперименте BM@N на NICA, показан на рисунке ниже в списке слева. В данном случае bmndata
это дерево, NdetEvent
- ветка, а fCells.fTimeStamp
и др - листья, используя которые можно заполнить гистограмму. Справа отрисована гистограмма заполненная fSignal
, соответсвующая сигналу с ячеек детектора.

Также в .root сохраняются гистограммы и "канвасы" для их быстрого построения и изменения без необходимости повторной обработки. В общем, ROOT - мощный инструмент в работе со статистикой и ее визуализации (особенно в виде гистограмм). Гистограммы могут быть представлены в 1D, 2D и 3D виде, их можно накладывать друг на друга для сравнения, совершать операции над ними, а также фитировать их с помощью мощного встроенного интерфейса.
ROOT продолжает развиваться, в нем есть встроенные средства для работы с машинным обучением и многое другое. Отдельно можно отметить интеграцию с языками Python и R, а также поддержку работы с MySQL, PostgreSQL и SQLite.
В основном ROOT используется в крупных международных коллаборациях, занимающимися исследованиями в физике высоких энергий, ядерной физике и физике элементарных частиц, где требуется работа с большой статистикой для изучения редких процессов. Коллаборации, как правило, используют свою надстройку над ROOT, включающую в себя все необходимое для работы над конкретным экспериментом (например, классы и параметры детекторов). Среди наиболее известных коллабораций, использующих ROOT - ATLAS, CMS, LHCb, ALICE в CERN, HADES и CBM в GSI, T2K, а также BM@N и MPD на NICA в ОИЯИ.
Портирование ROOT
Портирование фреймворка ROOT осуществлялось в рамках операционной системы Collaboration OS (CollabOS). Ключевой особенностью CollabOS является поддержка пакетной базы на основе CentOS 9 и Epel, что обеспечивает легкий переход на процессоры Эльбрус с других дистрибутивов Linux, основанных на RedHat: CentOS, Fedora и Scientific Linux. Поддержка языков C, C++, Fortran, Python 3.9, Perl, Java 8 и 11, PHP, Lua, Ruby, R, Rust позволяет осуществлять привычную работу с кодом. На данный момент операционная система поддерживает процессоры 5 и 6 поколений Эльбрус 8СВ, 2С3, 16С.
Уровень 0: Сборка зависимостей
Поскольку цель стояла в сборке ROOT в конфигурации максимально приближенной к epel 9, то необходимо было собрать ряд зависимостей. Так, были портированы: R - язык для анализа и визуализации данных, xrootd - расширенный файловый сервер ROOT, pythia8 - генератор взаимодействий в физике высоких энергий, библиотеки для работы с математикой openblas, flexiblas, atlas, libarrow, lhapdf, cfitsio и другие пакеты.
Гораздо большую сложность составил выбор компилятора. Оптимизирующий компилятор lcc оказался не способен скомпилировать исходный код ROOT, в частности модифицированных llvm и clang, без существенных изменений в нем. Особенно сложно было бы внести такие изменения в актуальные версии ROOT (v6.34 - v6.37), так как они основаны на библиотеках llvm-18. Поэтому изначально было решено откатиться к root-6.30.06, где основой является llvm-13.
Позднее нами были собраны llvm-13 и llvm-17 из исходников проекта по портированию llvm на e2k архитектуру - llvm-project-e-2-k, благодаря предоставленными МЦСТ более свежими версиями компонент lccrt и liblccopt, необходимым для его работы. Это позволило собирать актуальные версии ROOT - v6.34.06 в рамках дистрибутива CollabOS и последнюю на данный момент v6.37.01 из исходников. В ходе сборки llvm-17 с использованием clang-13 была выявлена проблема при сборке с флажками оптимизации -O3
, -O2
, -O1
, -O0
- clang-17 не мог скомпилировать даже простейший "Hello, World!", поэтому и для сборки ROOT они не использовались.
Уровень 1: Добавление поддержки e2k в ROOT
Первым и наиболее простым шагом было добавление поддержки e2k в cmake/modules/SetUpLinux.cmake
, config/root-config.in
, etc/Makefile.arch
, root/core/foundation/inc/ROOT/RConfig.hxx
и interpreter/CMakeLists.txt
по аналогии с другими архитектурами. При наличии всех зависимостей это помогает пройти конфигурацию самого ROOT.
Но этого недостаточно, так как интерпретатор Cling основан на модифицированном llvm, и, соответственно, в него также необходимо добавлять поддержку архитектуры e2k.
Уровень 2: добавление поддержки e2k в форк llvm с патчами для ROOT
Эта задача оказалась на порядки сложнее, так как нужно было скрестить два форка llvm - с изменениями разработчиков из МЦСТ и изменениями разработчиков ROOT. Но и тут не все так просто, так как хотелось бы, так как в МЦСТ работы по портированию ведутся в ветках llvmorg-13.0.1-e2k, llvmorg-17.0.1-e2k и llvmorg-19-e2k, а ROOT собирается с llvm-18. Есть, конечно, ещё порт llvm-18 с нативной кодогенерацией без lcc от Унипро, но его исходники закрыты, что не дает возможности модифицировать его для работы с ROOT.
Поэтому для слияния был выбран следущий подход: изменения, необходимые для работы на Эльбрусах, из ветки llvmorg-19-e2k переносились в llvm-18 от команды ROOT, а встречающиеся конфликты и падения во время сборок решались подглядыванием в llvmorg-17.0.1-e2k. После большого числа исправлений на выходе получили патч, который можно применить при сборке rpm-пакета в rpmbuild без подмены исходников.
При этом нужно не забыть указать следующие флаги cmake при сборке:
-DLLVM_TARGET_ARCH=e2k
-DLLVM_DEFAULT_TARGET_TRIPLE=e2k64-unknown-linux-gnu
-DLLVM_WITH_LCCRT=/usr/lib64/lccrt
-DLLVM_LCCRT_RELEASE=True
А также убедиться, что установлены lccrt и liblccopt версии не ниже 146390. Мы собираем проект используя clang-13 для более быстрой сборки, но можно собирать и используя clang-17 (которые мы собирали из исходников в рамках дистрибутива CollabOS), а также clang-18 от Унипро.
Уровень 3: исправление ошибок при сборке
1. Ошибки вида:
Error in <AnnotatedRecordDecl::BuildDemangledTypeInfo>: Demangled typeinfo name 'Typeinfo for TStreamerElement' does not start with 'typeinfo for'
Решается изменением в core/clingutils/src/TClingUtils.cxx
в случае e2k c:
static const char typeinfoNameFor[] = "typeinfo for ";
на:
static const char typeinfoNameFor[] = "Typeinfo for ";
2. При сборке из ветки master все собирается, но при попытке использования cling падает. Как оказалось, причиной было добавление строки с set(LLVM_UNREACHABLE_OPTIMIZE FALSE)
в interpreter/CMakeLists.txt
в одном из коммитов. Аналогичная проблема была и при сборке clang-17 с флажками -O3
, -O2
, -O1
, как отмечалось выше. Поэтому на данный момент вынуждены не задавать LLVM_UNREACHABLE_OPTIMIZE
для e2k. Возможно, что это уже исправили, но для пересборки с новыми коммитами требуются более свежие версии lccrt и liblccopt.
Также при сборке ROOT v6.30 и ниже с использованием lcc могут возникать и другие ошибки (undefined reference
, не находятся заголовочные файлы и др.). Однако освещать их не будем, так как в конечном варианте для сборки актуальных версий ROOT используется clang, с которым этих проблем нет.
Уровень 4: что не удалось исправить
Несмотря на наши усилия по сборке ROOT в полной конфигурации, приближенной к epel 9, некоторые опции сборки нам пришлось отключить из-за ошибок при линковке libCling.so следущего вида:
../../clingutils/CMakeFiles/ClingUtils.dir/src/TClingUtils.cxx.o: in function `ROOT::TMetaUtils::GetRealPath(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
-:(.text+0x14374): relocation truncated to fit: R_E2K_DISP against symbol `llvm::sys::fs::real_path(llvm::Twine const&, llvm::SmallVectorImpl<char>&, bool)' defined in .text._ZN4llvm3sys2fs9real_pathERKNS_5TwineERNS_15SmallVectorImplIcEEb section in ../../../interpreter/llvm-project/llvm/lib/libLLVMSupport.a(Path.cpp.o)
Ранее сталкивались с такой ошибкой при сборке clang-17 с библиотеками от clang-13, чтобы при апгрейде с clang-13 не возникало конфликтов, так как некоторые пакеты зависели от clang-13. Эту ошибку тогда удалось обойти использованием флагов:
-DLLVM_BUILD_LLVM_DYLIB=ON \
-DLLVM_LINK_LLVM_DYLIB:BOOL=ON \
-DCLANG_LINK_CLANG_DYLIB=ON \
Предположительно, она возникала из-за слишком большого размера файлов при линковке.
Однако при сборке ROOT они не помогали, поэтому мы постарались максимально уменьшить размер библиотек следущим образом:
Использовали -g0 для отключения отладочной информации.
Изменили тип сборки с
RelWithDebInfo
наMinSizeRel
.Использовали опции
-DLLVM_ENABLE_UNWIND_TABLES=OFF и -DBUILD_SHARED_LIBS=ON
.Отключили сборку библиотеки автоматического дифференцирования Clad. В такой конфигурации сборка проходит успешно.
Помимо этого также отключили сборку и прогон тестов, оставив задачу полноценного тестирования на будущее, так как она требует больших усилий. Также отмечу, что ROOT TBrowser в браузере Firefox-91 в нашей ОС не запускается, что вероятно связано со старой версией браузера, а исходники свежей версии портированного на e2k Firefox не открыты.
Это все ограничения, на которые пришлось пойти. К сожалению, добавить наши изменения в основной репозиторий ROOT не удастся (как это сделали для risc-v и loongarch64), так как необходимо, чтобы основной репозиторий llvm поддерживал архитектуру e2k. Надеемся, что рано или поздно это сделают, и можно будет официально добавить поддержку e2k в ROOT. А пока репозиторий ROOT с поддержкой e2k архитектуры доступен по ссылке: https://github.com/e2k-community/root-e2k в ветках master и latest-stable.
Проверка работы ROOT на Эльбрусе
Теперь перейдем к тестированию собранного ROOT на Эльбрус-8СВ. Для начала прогоним встроенный бенчмарк tutorials/legacy/benchmarks.C
. Он прогоняет несколько тестов по заполнению, фитированию и построению гистограмм и графиков. Пример некоторых из них показан ниже:



Результат прогона бенчмарка на Эльбрус-8св:
---------------ROOT 6.37.01 benchmarks summary--------------------
hsimple : Real Time = 1.82 seconds Cpu Time = 1.54 seconds
tornado : Real Time = 0.00 seconds Cpu Time = 0.00 seconds
na49 : Real Time = 0.10 seconds Cpu Time = 0.06 seconds
geometry : Real Time = 0.10 seconds Cpu Time = 0.14 seconds
na49view : Real Time = 0.10 seconds Cpu Time = 0.03 seconds
ntuple1 : Real Time = 1.01 seconds Cpu Time = 0.78 seconds
TOTAL : Real Time = 3.13 seconds Cpu Time = 2.55 seconds
---------------ROOT 6.37.01 benchmarks summary (in ROOTMARKS)-----
For comparison, a Pentium IV 2.4Ghz is benchmarked at 600 ROOTMARKS
hsimple = 95.71 RealMARKS, = 109.09 CpuMARKS
tornado = 9679163.00 RealMARKS, = inf CpuMARKS
na49 = 8258.16 RealMARKS, = 13900.00 CpuMARKS
geometry = 1128.74 RealMARKS, = 771.43 CpuMARKS
na49view = 178.32 RealMARKS, = 600.00 CpuMARKS
ntuple1 = 172.29 RealMARKS, = 207.69 CpuMARKS
****************************************************
* Your machine is estimated at 706.57 ROOTMARKS *
****************************************************
Несмотря на не очень высокий результат, ROOT на e2k спокойно можно использовать для повседневной работы, как на любом персональном компьютере. Для тяжелых вычислений Эльбрусы не подойдут. Возможно, если исходники порта llvm-18 от Унипро появятся в открытом доступе, то ROOT станет работать быстрее.
А теперь протестируем в реальных задачах. Вот гистограммы, которые строились для пока ещё не вышедшей, но уже принятой в печать статьи (Nuclear Science and Techniques, Q1, IF 3.6). Их получили как из экспериментальных данных, так и из моделирования в Geant4 (который прекрасно работает на e2k и доступен в CollabOS).



Ниже также пример работы TBrowser на e2k, позволяющего просматривать "деревья", строить, изменять и фитировать гистограммы в интерактивном режиме (что особенно удобно для первичного анализа, уточнения пределов построения гистограммы, пределов фитирования, выбора ширины бинов и много другого).

Что в итоге
ROOT - мощный инструмент "все в одном" для анализа данных - теперь можно использовать и на Эльбрусах. К сожалению, в официальный репозиторий пока поддержку e2k добавить не удастся, как и гарантировать, что он будет работать для еще невышедших версий. Нам пришлось пойти на некоторые ограничения при сборке, что надеемся в будущем исправить.
Не так давно наш коллега проводил тестирование производительности процессоров Эльбрус в различных языках программирования, где среди них был и интерпретатор Cling, показавший лучший результат среди интерпретаторов на e2k (что неудивительно).
Также хочу поблагодарить:
Михаила Лукашова за неоценимую помощь в сборке llvm и портировании ROOT
Павла Степанова за помощь в сборке llvm-17
Евгения Плисковского за консультацию при портировании root-6.30 (именно ему удалось первым собрать root-6.28 на e2k).
x2v0
Меня зовут Валерий Онучин.
Я стоял у истоков ROOTa, когда ещё официальный ЦЕРН его отрицал.
Поэтому искренне благодарен за проделанную интересную работу..
К тому же, я сам сейчас занимаюсь Эльбрусом.
Постараюсь связаться со своими друзьями из ROOT-team и донести им эту новость.