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