Ubuntu系统下ITensor的安装与测试

使用make命令编译源码安装❤️LM

Posted by 晨曦on July 4, 2020

目录

1. 安装ITensor步骤

1.1 基本步骤

  1. 下载ITensor源码
    git clone https://github.com/ITensor/ITensor itensor
    注意:可以把此itensor文件夹移动到任何你想安装到的位置。另外,也可以下载release版本的代码压缩包并解压
  2. 进入该目录
    cd itensor
  3. 安装blaslapack包用于ITensor的编译
    sudo apt-get install libblas-dev liblapack-dev
  4. 创建并修改make的配置文件
    cp options.mk.sample options.mk
    gedit options.mk
    然后修改此文件:
    根据文件中的提示,分别更改三个部分
    • 第一步:选择编译器,使用GNU GCC compiler,把其他的注释掉(即保持默认)
       CCCOM=g++ -m64 -std=c++17 -fconcepts -fPIC
      
    • 第二步:选择BLAS/LAPACK相关选项,使用GNU/LINUX systems,注释其他,即
       PLATFORM=lapack
       BLAS_LAPACK_LIBFLAGS=-lpthread -L/usr/lib -lblas -llapack
      
    • 第三步:其余全部保持默认即可
  5. 编译源代码
    make -j$(nproc)
  6. 此时即可正常使用itensor

修改后的options.mk文件关键部分示例:

#########
## [1]
##
## Set which compiler to use by defining CCCOM:
## GNU GCC compiler
CCCOM=g++ -m64 -std=c++17 -fconcepts -fPIC

#########
## [2]
##
## BLAS/LAPACK Related Options
##

##
## Example using a C interface to LAPACK on GNU/LINUX systems
## (Path to lib/ folder may differ on your system)
##
PLATFORM=lapack
BLAS_LAPACK_LIBFLAGS=-lpthread -L/usr/lib -lblas -llapack

1.2 添加HDF5支持

可选功能,在1.1的基础上,执行以下命令安装HDF5

sudo apt-get install libhdf5-dev
# 记录下面命令的输出
# -L/usr/lib/x86_64-linux-gnu/hdf5/serial
# 则HDF5_PREFIX=/usr/lib/x86_64-linux-gnu/hdf5/serial
h5cc -show

然后修改options.mk文件,取消注释HDF5_PREFIX=/usr/local并修改:

#########
## [3]
##
HDF5_PREFIX=/usr/lib/x86_64-linux-gnu/hdf5/serial

然后保存,在当前目录执行make -j$(nproc)

1.3 添加OpenMP支持

可选功能OpenMP。如果使用该功能,在运行编译后的程序时需要设置环境变量OMP_NUM_THREADSOPENBLAS_NUM_THREADSMKL_NUM_THREADS。实现OpenMP有以下3种方法,任选其一即可:

  • 使用OpenMP
  • 使用OpenBLAS
  • 使用Intel MKL

1.3.1 安装OpenMP

在1.1的基础上,安装OpenMP

sudo apt-get install libomp-dev

另外还要启用OMP

#########
## [4]
##
ITENSOR_USE_OMP=1

然后保存,在当前目录执行make -j$(nproc)

1.3.2 安装OpenBLAS

在1.1的基础上,安装OpenBLAS

# 安装OpenBLAS OpenMP
sudo apt-get install liblapacke-dev libopenblas-dev

然后设置BLAS/LAPACK相关选项,取消注释其他平台,只保留openblas平台;另外还要启用OMP

## [2]
##
## BLAS/LAPACK Related Options
##
PLATFORM=openblas
# 根据实际openblas安装位置修改路径
# 也可能是 /usr/local/opt/openblas/lib 和 /usr/local/opt/openblas/include
BLAS_LAPACK_LIBFLAGS=-lpthread -L/usr/lib/x86_64-linux-gnu/openblas-pthread -lopenblas
BLAS_LAPACK_INCLUDEFLAGS=-I/usr/include/x86_64-linux-gnu/openblas-pthread -fpermissive -DHAVE_LAPACK_CONFIG_H -DLAPACK_COMPLEX_STRUCTURE

# ...
#########
## [4]
##
ITENSOR_USE_OMP=1

然后保存,在当前目录执行make -j$(nproc)

1.3.3 安装配置Intel MKL

该步骤较麻烦,在1.1的基础上:
安装Intel-oneAPI-Toolkits并启用intel-mkl
然后设置BLAS/LAPACK相关选项,取消注释其他平台,只保留mkl平台;另外还要启用OMP

## [2]
##
## BLAS/LAPACK Related Options
##
PLATFORM=mkl
BLAS_LAPACK_LIBFLAGS=-L/opt/intel/mkl/lib/intel64 -lmkl_intel_lp64 -lmkl_intel_thread -lmkl_rt -lmkl_core -liomp5 -lpthread
BLAS_LAPACK_INCLUDEFLAGS=-I/opt/intel/mkl/include

# ...
#########
## [4]
##
ITENSOR_USE_OMP=1

然后保存,在当前目录执行make -j$(nproc)

2. 如何创建和编译itensor项目

2.1 官方测试项目

2.1.1 测试sample示例

cd ~
# 创建临时目录
mkdir tmp && cd tmp
cp -r ~/itensor/sample/* ./
# 修改Makefile文件
vim Makefile

然后替换Makefile前两行的

include ../this_dir.mk
include ../options.mk

# 上一步ITensor的安装路径
LIBRARY_DIR=/home/zfb/itensor
include $(LIBRARY_DIR)/this_dir.mk
include $(LIBRARY_DIR)/options.mk

最后执行make -j$(nproc)

2.1.2 测试tutorial的project_template示例

cd ~
# 创建临时目录
mkdir temp && cd temp
cp -r ~/itensor/tutorial/project_template/* ./
# 检查Makefile文件的LIBRARY_DIR是否为本机路径
# 若不是,则修改
# 编译
make -j$(nproc)
# 运行
./myappname

2.2 第一种方法(推荐)

整个项目可以在仓库itensor-install/first-method下载

  1. 编写代码文件myappname.cpp和头文件myclass.h以及头文件myappname.h
  2. 创建文件命名为Makefile,内容在下面
  3. 编译项目 make -j$(nproc)
  4. 此时项目文件夹下会生成myappname文件,运行代码 ./myappname

Makefile文件的所有内容

# 你的itensor在安装时的路径
LIBRARY_DIR=/home/zfb/itensor

# 如果你的main()函数在myappname.cpp文件中,那么就把此处设置为myappname
APP=myappname

# 如果你调用了myclass.h的自定义头文件,那么把它写在这里
HEADERS=myclass.h

#--------- 以下内容无需修改 -----------

CCFILES=$(APP).cpp


include $(LIBRARY_DIR)/this_dir.mk
include $(LIBRARY_DIR)/options.mk

TENSOR_HEADERS=$(LIBRARY_DIR)/itensor/core.h

#Mappings --------------
OBJECTS=$(patsubst %.cpp,%.o, $(CCFILES))
GOBJECTS=$(patsubst %,.debug_objs/%, $(OBJECTS))

#Rules ------------------

%.o: %.cpp $(HEADERS) $(TENSOR_HEADERS)
	$(CCCOM) -c $(CCFLAGS) -o $@ $<

.debug_objs/%.o: %.cpp $(HEADERS) $(TENSOR_HEADERS)
	$(CCCOM) -c $(CCGFLAGS) -o $@ $<

#Targets -----------------

build: $(APP)
debug: $(APP)-g

$(APP): $(OBJECTS) $(ITENSOR_LIBS)
	$(CCCOM) $(CCFLAGS) $(OBJECTS) -o $(APP) $(LIBFLAGS)

$(APP)-g: mkdebugdir $(GOBJECTS) $(ITENSOR_GLIBS)
	$(CCCOM) $(CCGFLAGS) $(GOBJECTS) -o $(APP)-g $(LIBGFLAGS)

clean:
	rm -fr .debug_objs *.o $(APP) $(APP)-g

mkdebugdir:
	mkdir -p .debug_objs

注意:这里换行之后必须用TAB键缩进,不能用空格

2.3 第二种方法

整个项目可以在仓库itensor-install/second-method下载

  1. 编写代码文件test.cpp和头文件myclass.h
  2. 编译项目
    g++ -m64 -std=c++17 -fPIC -c -I. -I/home/zfb/itensor -o test.o test.cpp
    g++ -m64 -std=c++17 -fPIC -I. -I/home/zfb/itensor test.o -o test -L/home/zfb/itensor/lib -litensor -lpthread -L/usr/lib -lblas -llapack
    
  3. 此时项目文件夹下会生成test文件,运行代码 ./test

3. 常见问题

截止ITensor v3.1.11,该库不支持搭配使用lapack >= 3.9.1(即Ubuntu 22.04),报错类似:

tensor/lapack_wrap.cc: In function ‘void itensor::dsyev_wrapper(char, char, itensor::LAPACK_INT, itensor::LAPACK_REAL*, itensor::LAPACK_REAL*, itensor::LAPACK_INT&)’:
tensor/lapack_wrap.cc:342:19: error: too few arguments to function ‘void dsyev_(const char*, const char*, const int*, double*, const int*, double*, double*, const int*, int*, size_t, size_t)’
  342 |     F77NAME(dsyev)(&jobz,&uplo,&n,A,&lda,eigs,&wkopt,&lwork,&info);
      |                   ^
In file included from /usr/include/lapack.h:11,
                 from /usr/include/lapacke.h:36,
                 from /home/zfb/itensor/itensor/tensor/lapack_wrap.h:50,
                 from tensor/lapack_wrap.cc:16:
/usr/include/lapack.h:17008:6: note: declared here
17008 | void LAPACK_dsyev_base(
      |      ^~~~~~~~~~~~~~~~~
tensor/lapack_wrap.cc:345:19: error: too few arguments to function ‘void dsyev_(const char*, const char*, const int*, double*, const int*, double*, double*, const int*, int*, size_t, size_t)’
  345 |     F77NAME(dsyev)(&jobz,&uplo,&n,A,&lda,eigs,work.data(),&lwork,&info);
      |                   ^
In file included from /usr/include/lapack.h:11,
                 from /usr/include/lapacke.h:36,
                 from /home/zfb/itensor/itensor/tensor/lapack_wrap.h:50,
                 from tensor/lapack_wrap.cc:16:
/usr/include/lapack.h:17008:6: note: declared here
17008 | void LAPACK_dsyev_base(
      |      ^~~~~~~~~~~~~~~~~

原因是lapack 3.9.1修改了部分函数的定义,解决办法
修改文件itensor/tensor/lapack_wrap.h
原始内容

#ifdef FORTRAN_NO_TRAILING_UNDERSCORE
#define F77NAME(x) x
#else
#define F77NAME(x) x##_
#endif

修改后内容

#ifdef FORTRAN_NO_TRAILING_UNDERSCORE
#define F77NAME(x) x
#else
#if defined(LAPACK_GLOBAL) || defined(LAPACK_NAME)
#define F77NAME(x) LAPACK_##x
#else
#define F77NAME(x) x##_
#endif
#endif

目前已经提交PR且合并进入主仓库,预计下个版本将会修复

晨曦 / -  views
Published under (CC) BY-NC-SA 4.0