HDF5 е библиотека и формат за съхранение и достъп до структурирани и типизирани данни. Тази библиотека намира приложение в софтуерните продукти за анализи на големи масиви данни - от астрономия и метеорология до банково дело и медицина. HDF5 библиотеката, която е включена в пакетната колеция на CentOS 7 и 8, не е изградена с помощта на някои важни оптимизации. Целта на този документ е да предложи рецепта за изграждане на серийна версия на HDF5 библиотеката, която е оптимизирана за скорост на изпълнение, чрез компилаторите от пакета Intel Compilers и/или PGI Compilers.
Ако желаете да научите как да изградите серийна версия на HDF5 библиотеката, прочетете документа "Компилиране, инсталиране и използване на серийна версия на HDF5 под CentOS 7 и 8".
Ако желаете да научите как да изградите серийна версия на HDF5 библиотеката, с поддръжка на SZIP, прочетете документа "Компилиране, инсталиране и използване на серийна версия на HDF5 с поддръжка на SZIP под CentOS 7 и 8".
Ако желаете да научите как да изградите MPI версия на HDF5 библиотеката, с поддръжка на SZIP, прочетете документа "Компилиране, инсталиране и използване на MPI версия на HDF5 с поддръжка на SZIP под CentOS 7 и 8".
ВНИМАНИЕ! MPI версията на HDF5 библиотеката не поддържа Java и C++ интерфейсни библиотеки.
Трябва да имате и достъп до изпълнимите файлове на компилаторите, включени в Intel Compilers и/или PGI Compilers (в зависимост от това кой пакет компилатори ще използвате). В случая на Intel Compilers това са icc
, mpiicc
, icpc
, mpiicpc
, ifort
и mpiifort
, а при използване на PGI Compilers това са pgcc
, mpicc
, pgc++
, mpicxx
, pgfortran
и mpifc
. Нужно е да имате директен достъп до съответния mpiexec
(използва се в тестовете). Също така, в системата следва да са инсталирани пакетите cmake (виж бележката относно версията на cmake по-долу) и zlib-devel:
ВНИМАНИЕ! HDF5 изисква версия на CMake по-висока от 3.15. Следвайте инструкциите в документа "Компилиране и инсталиране на последна актуална версия на CMake под CentOS 7 и 8", ако искате да компилирате последната актуална версия на CMake в случай, че тя не е на разположение!
Изтеглете архива с изходния код на HDF5 библиотеката от страницата на проекта (изберете tar.bz2 или tar.gz формат на архива):
https://www.hdfgroup.org/downloads/hdf5/source-code/
В примерите по-долу се предполага, че е изтеглен файла с архива hdf5-1.10.5.tar.bz2
(по времето, по което вие изпълнявате тези инструкции, е възмжно версията да бъде по-висока от 1.10.5). Създайте директория, в която да извършите компилирането:
$ mkdir ~/build
Разпакетирайте в нея файла с архива:
$ tar xvf hdf5-1.10.5.tar.bz2 -C ~/build
влезте в новосъздадената при разпакетирането директория:
$ cd ~/build/hdf5-1.10.5
там създайте поддиректорията build
и влезте в нея:
$ mkdir build
$ cd build
Там стартирайте конфигурирането на компилационния процес чрез cmake3
по начина показан по-долу (отбележете, че директорията, в която ще бъде инсталиран готовия код е стойността на -DCMAKE_INSTALL_PREFIX
- може да я смените по ваш избор с друга):
-
ако компилирането се извършва с Intel Compilers:
Първо заредете всички променливи на средата, чрез които се задават пътищата до компилаторите и библиотеките:
$ source /usr/unite/intel/compilers_and_libraries/linux/bin/compilervars.sh intel64
и след това стартирайте конфигурирането:
$ PATH=/usr/unite/cmake-3.16.5-gnu/bin:$PATH FC=mpiifort FCFLAGS="-xHost" CC=mpiicc CFLAGS="-xHost" cmake .. -DCMAKE_INSTALL_PREFIX=/usr/unite/hdf5-1.10.5-icc-mpi -DHDF5_ENABLE_THREADSAFE=OFF -DHDF5_BUILD_FORTRAN=ON -DHDF5_BUILD_HL_LIB=ON -DHDF5_ENABLE_Z_LIB_SUPPORT=ON -DZLIB_DIR=/usr -DHDF5_ENABLE_PARALLEL=YES -DHDF5_BUILD_CPP_LIB=OFF
-
ако компилирането се извършва с PGI Compilers:
$ PATH=/usr/unite/cmake-3.16.5-gnu/bin:/usr/unite/pgi/linux86-64/2019/bin:/usr/unite/pgi/linux86-64/2019/mpi/openmpi-3.1.3/bin:$PATH FC=mpiifort FCFLAGS="-fast" CC=mpiicc CFLAGS="-fast" cmake .. -DCMAKE_INSTALL_PREFIX=/usr/unite/hdf5-1.10.5-pgi-mpi -DHDF5_ENABLE_THREADSAFE=OFF -DHDF5_BUILD_FORTRAN=ON -DHDF5_BUILD_HL_LIB=ON -DHDF5_ENABLE_Z_LIB_SUPPORT=ON -DZLIB_DIR=/usr -DHDF5_ENABLE_PARALLEL=YES -DHDF5_BUILD_CPP_LIB=OFF
След като всичко дотук е протекло успешно, може да пристъпите към компилирането на кода:
-
ако компилирането се извършва с Intel Compilers (трябва да сте задали пътищата до Intel компилаторите, както е показано при конфигирурането по-горе):
$ make -j6
-
ако компилирането се извършва с PGI Compilers (не е нужно за задавате предварително пътищата до компилаторите):
$ PATH=/usr/unite/pgi/linux86-64/2019/bin:/usr/unite/pgi/linux86-64/2019/mpi/openmpi-3.1.3/bin:$PATH make -j6
След успешното завършване на компилацията, пристъпете към тестовете на получения продукт (те са начин за проверка дали компилираната HDF5 библиотека е компилирана правилно и функционалността ѝ отговаря на очакванията):
-
ако компилирането се извършва с Intel Compilers (трябва да сте задали пътищата до Intel компилаторите, както е показано при конфигирурането по-горе):
$ make test
-
ако компилирането се извършва с PGI Compilers (не е нужно за задавате предварително пътищата до компилаторите)::
$ PATH=/usr/unite/pgi/linux86-64/2019/bin:/usr/unite/pgi/linux86-64/2019/mpi/openmpi-3.1.3/bin:$PATH make test
В случай на компилиране с PGI Compilers следните два теста могат да бъдат маркирани като провалени:
The following tests FAILED:
66 - H5TEST-swmr (Failed)
122 - H5TEST-shared-swmr (Failed)
За SWMR организацията на достъпа до контейнерите с данни, може да прочетете на страницата на проекта HDF5. На практика обаче, проблем няма (тестовете се провалят поради проблеми с детектирането на някои от използваните флагове за стаертиране на PGI компилаторите - това следва да се вземе предвид при компилиране на код, който е зависим от HDF5, чрез PGI Compilers, където да се направи пак реален предварителен тест - да се използват правилните флагове).
Ако само посочените по-горе тестове са маркирани като провалени, пристъпете към инсталирането:
$ make install
След успешно извършване на инсталацията, може да изведете списък с библиотеките, към които е динамично свързана библиотеката libhdf5.so
. Това става по следния начин:
-
ако компилирането се извършва с Intel Compilers:
$ LD_LIBRARY_PATH=/usr/unite/intel/compilers_and_libraries/linux/lib/intel64:/usr/unite/intel/compilers_and_libraries/linux/mpi/intel64/libfabric/lib:$LD_LIBRARY_PATH ldd /usr/unite/hdf5-1.10.5-icc-mpi/lib/libhdf5.so
Трябва да получите изход, който е подобен на:
linux-vdso.so.1 (0x00007ffe49b05000)
libm.so.6 => /lib64/libm.so.6 (0x00007f1165f75000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007f1165d71000)
libz.so.1 => /lib64/libz.so.1 (0x00007f1165b5a000)
libmpifort.so.12 => /usr/unite/intel/compilers_and_libraries_2019.1.144/linux/mpi/intel64/lib/libmpifort.so.12 (0x00007f11657ad000)
libmpi.so.12 => /usr/unite/intel/compilers_and_libraries_2019.1.144/linux/mpi/intel64/lib/release/libmpi.so.12 (0x00007f1162520000)
librt.so.1 => /lib64/librt.so.1 (0x00007f1162317000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f11620f7000)
libimf.so => /usr/unite/intel/compilers_and_libraries_2019.1.144/linux/compiler/lib/intel64_lin/libimf.so (0x00007f1161b57000)
libsvml.so => /usr/unite/intel/compilers_and_libraries_2019.1.144/linux/compiler/lib/intel64_lin/libsvml.so (0x00007f11601b4000)
libirng.so => /usr/unite/intel/compilers_and_libraries_2019.1.144/linux/compiler/lib/intel64_lin/libirng.so (0x00007f115fe42000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f115fc2a000)
libintlc.so.5 => /usr/unite/intel/compilers_and_libraries_2019.1.144/linux/compiler/lib/intel64_lin/libintlc.so.5 (0x00007f115f9b8000)
libc.so.6 => /lib64/libc.so.6 (0x00007f115f5f4000)
/lib64/ld-linux-x86-64.so.2 (0x00007f116696c000)
libfabric.so.1 => /usr/unite/intel/compilers_and_libraries_2019.1.144/linux/mpi/intel64/libfabric/lib/libfabric.so.1 (0x00007f115f3bb000)
-
ако компилирането се извършва с PGI Compilers:
$ ldd /usr/unite/hdf5-1.10.5-pgi-mpi/lib/libhdf5.so
Трябва да получите изход, който е подобен на:
linux-vdso.so.1 (0x00007fff6d3b8000)
libm.so.6 => /lib64/libm.so.6 (0x00007fd05eaaf000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fd05e8ab000)
libz.so.1 => /lib64/libz.so.1 (0x00007fd05e694000)
libmpi.so.40 => /usr/unite/pgi/linux86-64-llvm/2019/mpi/openmpi-3.1.3/lib/libmpi.so.40 (0x00007fd05ce29000)
libpgatm.so => /usr/unite/pgi/linux86-64-llvm/19.10/lib/libpgatm.so (0x00007fd05cc20000)
libpgkomp.so => /usr/unite/pgi/linux86-64-llvm/19.10/lib/libpgkomp.so (0x00007fd05ca1d000)
libomp.so => /usr/unite/pgi/linux86-64-llvm/19.10/lib/libomp.so (0x00007fd05c74c000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fd05c52c000)
libpgmath.so => /usr/unite/pgi/linux86-64-llvm/19.10/lib/libpgmath.so (0x00007fd05c117000)
libpgc.so => /usr/unite/pgi/linux86-64-llvm/19.10/lib/libpgc.so (0x00007fd05bdbe000)
libc.so.6 => /lib64/libc.so.6 (0x00007fd05b9fa000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fd05b7e2000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd05f4c2000)
libopen-rte.so.40 => /usr/unite/pgi/linux86-64-llvm/2019/mpi/openmpi-3.1.3/lib/../lib/libopen-rte.so.40 (0x00007fd05b0b6000)
libopen-pal.so.40 => /usr/unite/pgi/linux86-64-llvm/2019/mpi/openmpi-3.1.3/lib/../lib/libopen-pal.so.40 (0x00007fd05a6ed000)
librdmacm.so.1 => /lib64/librdmacm.so.1 (0x00007fd05a4d6000)
libibverbs.so.1 => /lib64/libibverbs.so.1 (0x00007fd05a2bc000)
libnuma.so => /usr/unite/pgi/linux86-64-llvm/2019/mpi/openmpi-3.1.3/lib/../lib/libnuma.so (0x00007fd05a0b0000)
librt.so.1 => /lib64/librt.so.1 (0x00007fd059ea7000)
libutil.so.1 => /lib64/libutil.so.1 (0x00007fd059ca3000)
libnl-route-3.so.200 => /lib64/libnl-route-3.so.200 (0x00007fd059a2a000)
libnl-3.so.200 => /lib64/libnl-3.so.200 (0x00007fd059807000)
Най-важното, за което трябва да проверите в този списък с библиотеки, е наличието на свързани библиотеки от колекцията от Intel Compilers и/или PGI Compilers (виж редовете оцветени в светло синьо). Задължително трябва да виждате и съответната MPI библиотека, от използвания пакет с компилатори, оцветена в примерите по-горе в зелено.
ВНИМАНИЕ! Ако в bin/
директорията на инсталацията (ако сте следвали горния пример това ще е директория /usr/unite/hdf5-1.10.5-icc-mpi/bin
или /usr/unite/hdf5-1.10.5-pgi-mpi/bin
) не намирате h5fc
, ще се наложи да го създадете по следния начин:
-
за инсталацията създадена с Intel Compilers:
$ sudo sed 's/icc/ifort/g' /usr/unite/hdf5-1.10.5-icc-mpi/bin/h5cc > /usr/unite/hdf5-1.10.5-icc-mpi/bin/h5fc
$ sudo chmod 755 /usr/unite/hdf5-1.10.5-icc-mpi/bin/h5fc
-
за инсталацията създадена с PGI Compilers:
$ sudo sed 's/pgcc/pgfortran/g' /usr/unite/hdf5-1.10.5-pgi-mpi/bin/h5cc > /usr/unite/hdf5-1.10.5-pgi-mpi/bin/h5fc
$ sudo chmod 755 /usr/unite/hdf5-1.10.5-pgi-mpi/bin/h5fc
За да може даден код да бъде компилиран спрямо динамичната версия на HDF5 библиотеките (компилирани по процедурата показана по-горе), освен описание на използваните от нея функции в кода, в процеса на конфигурацията или компилацията му трябва да бъдат указани HDF5 компилаторите и посочени пътищата до хедър файловете и библиотеките:
-
за инсталацията създадена с Intel Compilers:
$ PATH=/usr/unite/hdf5-1.10.5-icc-mpi/bin:$PATH CC=h5pcc FC=h5pfc F77=h5pfc F90=h5pfc F95=h5pfc ./configure ... CGLAGS="-I/usr/unite/hdf5-1.10.5-icc-mpi/include" LFLAGS="-L/usr/unite/hdf5-1.10.5-icc-mpi/lib -lhdf5"
или
$ PATH=/usr/unite/hdf5-1.10.5-icc-mpi/bin:$PATH LD_LIBRARY_PATH=/usr/unite/hdf5-1.10.5-icc-mpi:$LD_LIBRARY_PATH CC=h5pcc FC=h5pfc F77=h5pfc F90=h5pfc F95=h5pfc make ... CGLAGS="-I/usr/unite/hdf5-1.10.5-icc-mpi/include" LFLAGS="-L/usr/unite/hdf5-1.10.5-icc-mpi/lib -lhdf5"
-
за инсталацията създадена с PGI Compilers:
$ PATH=/usr/unite/hdf5-1.10.5-pgi-mpi/bin:$PATH CC=h5pcc FC=h5pfc F77=h5pfc F90=h5pfc F95=h5pfc ./configure ... CGLAGS="-I/usr/unite/hdf5-1.10.5-pgi-mpi/include" LFLAGS="-L/usr/unite/hdf5-1.10.5-pgi-mpi/lib -lhdf5"
или
$ PATH=/usr/unite/hdf5-1.10.5-pgi-mpi/bin:$PATH LD_LIBRARY_PATH=/usr/unite/hdf5-1.10.5-pgi-mpi:$LD_LIBRARY_PATH CC=h5pcc FC=h5pfc F77=h5pfc F90=h5pfc F95=h5pfc make ... CGLAGS="-I/usr/unite/hdf5-1.10.5-pgi-mpi/include" LFLAGS="-L/usr/unite/hdf5-1.10.5-pgi-mpi/lib -lhdf5"
След успешна компилация спрямо динамичната версия на библиотеката, изпълнимият код трябва да може да зарежда HDF5 библиотеките при стартиране. За целта, в текущата сесия на bash
, в която ще става стартирането, трябва да се зареди пътя до тях (успоредно, трябва да заредите, когато това е нужно, пътищата то MPI библиотеките от пакета на използвания компилатор):
-
за инсталацията създадена с Intel Compilers:
$ export LD_LIBRARY_PATH=/usr/unite/hdf5-1.10.5-icc-mpi/lib:$LD_LIBRARY_PATH
-
за инсталацията създадена с PGI Compilers:
$ export LD_LIBRARY_PATH=/usr/unite/hdf5-1.10.5-pgi-mpi/lib:$LD_LIBRARY_PATH
Това зареждане може да бъде направено инцидентно (примера по-горе) или да стане част от постоянните настройки за bash
сесията (те са обикновено във файла ~/.bashrc
).
ВАЖНО! В състемата, в която ще се изпълнява кода на приложението, към което са динамично свързани HDF5 библиотеките, трябва да са налични и съответните библиотеки от пакета на използвания компилатор (виж примера с извеждането на техния списък по-горе).
Когато се използва статичната версия на HDF5 библиотеките, самия файл с библиотеката се задава в списъка с бинарни обекти, на база на които компилатора създава изпълнимия код. Например:
-
за инсталацията създадена с Intel Compilers:
$ PATH=/usr/unite/hdf5-1.10.5-icc-mpi/bin:$PATH h5pcc -o test test.c file1.o file2.o /usr/unite/hdf5-1.10.5-icc-mpi/lib/libhdf5.a
-
за инсталацията създадена с PGI Compilers:
$ PATH=/usr/unite/hdf5-1.10.5-pgi-mpi/bin:$PATH h5pcc -o test test.c file1.o file2.o /usr/unite/hdf5-1.10.5-pgi-mpi/lib/libhdf5.a