如何针对自定义 CUDA 安装使用 OpenCL 构建 GDAL?

How do I build GDAL with OpenCL against a custom CUDA installation?

我正在尝试针对 OpenCL 构建 GDAL 以获得 GPU 加速光栅操作,具体取决于 Cuda。我设法让 ./configure 完成并开始使用 make 进行编译。但是在编译的时候gdalinfo,编译失败,因为找不到OpenCL符号。

我很确定这是因为某处缺少 -lOpenCL 标志,但是 (1) 我不知道在哪里; (2) 我不知道要改变什么。所以我的问题是如何正确配置构建命令以使用 OpenCL?

构建失败错误:

echo '#!/bin/sh' > gdal-config
echo 'CONFIG_LIBS="libgdal.la"' >> gdal-config
echo 'CONFIG_DEP_LIBS=" -lcrypto -lpoppler -ljson-c -lfreexl -lqhull -lqhull -L/usr/lib/x86_64-linux-gnu -lgeos_c -lwebp -lodbc -lodbcinst -lkmlbase -lkmldom -lkmlengine -lkmlxsd -lkmlregionator -lexpat -lxerces-c -lpthread -lopenjp2 -ljasper -L/usr/lib -L/usr/lib/x86_64-linux-gnu/hdf5/serial -lnetcdf -lhdf5_hl -lhdf5 -lpthread -lsz -lz -ldl -lm -lcurl -L/usr/lib/x86_64-linux-gnu/hdf5/serial -lhdf5 -lmfhdfalt -ldfalt -logdi -lgif -ljpeg -lgeotiff -ltiff -lpng -L/usr/lib/x86_64-linux-gnu -lpq -lzstd -llzma -lz -lpthread -lm -lrt -ldl  -lspatialite -lsqlite3 -lpcre   -L/usr/lib/x86_64-linux-gnu -lcurl        cuda    -lxml2     "' >> gdal-config
echo 'CONFIG_PREFIX="gdal-2.4.2"' >> gdal-config
echo 'CONFIG_CFLAGS="-Iport -Igcore -Ialg -Iogr -Iogr/ogrsf_frmts -Ifrmts/vrt -Iapps"' >> gdal-config
echo 'CONFIG_DATA="data"' >> gdal-config
echo 'CONFIG_VERSION="'`cat ../VERSION`'"' >> gdal-config
echo 'CONFIG_OGR_ENABLED=yes' >> gdal-config  # Deprecated.  Always true.
echo 'CONFIG_GNM_ENABLED=yes' >> gdal-config
echo 'CONFIG_FORMATS=" gxf gtiff hfa aigrid aaigrid ceos ceos2 iso8211 xpm sdts raw dted mem jdem envisat elas fit vrt usgsdem l1b nitf bmp airsar rs2 ilwis rmf leveller sgi srtmhgt idrisi gsg ingr ers jaxapalsar dimap gff cosar pds adrg coasp tsx terragen blx msgn til r northwood saga xyz hf2 kmlsuperoverlay ctg e00grid zmap ngsgeoid iris map cals safe sentinel2 derived prf sigdem ignfheightasciigrid mrf webp wcs wms plmosaic wmts rda eeda grib bsb openjpeg jpeg2000 netcdf hdf5 hdf4 gif jpeg png pcraster  pcidsk rik ozi pdf rasterlite mbtiles postgisraster arg"' >> gdal-config
cat gdal-config.in >> gdal-config
chmod a+x gdal-config
/bin/bash libtool --mode=compile --silent --tag=CXX g++ -std=c++11 -Iport -Igcore -Ialg -Iogr -Iogr/ogrsf_frmts -Ignm -Iapps -DHAVE_AVX_AT_COMPILE_TIME -DHAVE_SSSE3_AT_COMPILE_TIME -DHAVE_SSE_AT_COMPILE_TIME -g -O2  -Wall -Wextra -Winit-self -Wunused-parameter -Wformat -Werror=format-security -Wno-format-nonliteral -Wlogical-op -Wshadow -Werror=vla -Wdate-time -Wfloat-conversion -Wmissing-declarations -Wnon-virtual-dtor -Woverloaded-virtual -fno-operator-names -Wzero-as-null-pointer-constant -Wsuggest-override  -Ifrmts/vrt -DGNM_ENABLED -Iport -I/usr/include/openjpeg-2.1 -I/usr/include  -DGDAL_COMPILATION -DHAVE_XERCES -I/usr/include -I/usr/include/xercesc -Iport -I/usr/include/openjpeg-2.1 -I/usr/include  -DGDAL_COMPILATION -I/usr/include/json-c -Iogr/ogrsf_frmts/geojson -Iogr/ogrsf_frmts/generic -Ignm -DHAVE_GEOS=1 -I/usr/include -c -o gdalinfo_bin.lo gdalinfo_bin.cpp
/bin/bash libtool --mode=link --silent g++ -std=c++11  gdalinfo_bin.lo  libgdal.la  -o gdalinfo
.libs/libgdal.so: undefined reference to `clCreateProgramWithSource'
.libs/libgdal.so: undefined reference to `clReleaseKernel'
.libs/libgdal.so: undefined reference to `clGetSupportedImageFormats'
.libs/libgdal.so: undefined reference to `clGetKernelWorkGroupInfo'
.libs/libgdal.so: undefined reference to `clCreateImage2D'
.libs/libgdal.so: undefined reference to `clEnqueueMapBuffer'
.libs/libgdal.so: undefined reference to `clEnqueueNDRangeKernel'
.libs/libgdal.so: undefined reference to `clGetPlatformIDs'
.libs/libgdal.so: undefined reference to `clGetDeviceInfo'
.libs/libgdal.so: undefined reference to `clCreateBuffer'
.libs/libgdal.so: undefined reference to `clReleaseCommandQueue'
.libs/libgdal.so: undefined reference to `clReleaseContext'
.libs/libgdal.so: undefined reference to `clReleaseEvent'
.libs/libgdal.so: undefined reference to `clGetDeviceIDs'
.libs/libgdal.so: undefined reference to `clReleaseMemObject'
.libs/libgdal.so: undefined reference to `clCreateCommandQueue'
.libs/libgdal.so: undefined reference to `clBuildProgram'
.libs/libgdal.so: undefined reference to `clFinish'
.libs/libgdal.so: undefined reference to `clGetProgramBuildInfo'
.libs/libgdal.so: undefined reference to `clEnqueueReadBuffer'
.libs/libgdal.so: undefined reference to `clReleaseProgram'
.libs/libgdal.so: undefined reference to `clCreateContext'
.libs/libgdal.so: undefined reference to `clSetKernelArg'
.libs/libgdal.so: undefined reference to `clCreateKernel'
collect2: error: ld returned 1 exit status
GNUmakefile:82: recipe for target 'gdalinfo' failed
make[1]: *** [gdalinfo] Error 1
make[1]: Leaving directory 'apps'
GNUmakefile:112: recipe for target 'apps-target' failed
make: *** [apps-target] Error 2

我知道这些符号已正确安装,因为如果我这样做,它们会被列出,例如:

$ export LD_LIBRARY_PATH=/usr/local/cuda/lib64   # Inform GDAL of Cuda
$ export PATH=/usr/local/cuda/bin:$PATH          # Inform GDAL of Cuda
$ cat /usr/local/cuda/include/CL/*  | grep -i clCreateProgramWithSource
clCreateProgramWithSource(cl_context        /* context */,
    ... )

我还认为 GDAL 已正确配置以了解这些,因为 ./configure --with-opencl --with-opencl-include=/usr/local/cuda/include/ --with-opencl-lib=cuda 可以找到 OpenCL。

因此,我认为它失败了,因为以下命令没有添加 -lOpenCL,而显然 gdalinfo 确实需要它。

/bin/bash libtool --mode=link --silent g++ -std=c++11  gdalinfo_bin.lo  libgdal.la  -o gdalinfo

所以我的最后一个问题是:如何修改构建配置以在更多地方包含 -lOpenCL?

您无需修改​​任何 GDAL makefile 即可使用 OpenCL - GDAL 构建脚本可以很好地找到您需要的一切。您需要的 configure 脚本的唯一选项是 --with-opencl=yes - 这个 yes 是必不可少的。选项 --with-opencl-include=ARG--with-opencl-lib=ARG 仅在您的 OpenCL 安装不是标准时才有用 - 我根本没有使用它们并正确链接了所有内容。

CUDA 有自己版本的 OpenCL 头文件和加载程序库,因此即使没有标准的 OpenCL(由 Linux 软件更新程序提供,例如 - apt) 在你的盒子上。如果 CUDA 安装在某个 non-standard 位置(例如 - 在您的主目录中),您必须告诉 GDAL configure 脚本:

./configure \
  --with-opencl=yes \
  --with-opencl-include=${HOME}/apps/cuda/targets/x86_64-linux/include \
  --with-opencl-lib="-L${HOME}/apps/cuda/targets/x86_64-linux/lib -lOpenCL" \
  <other options if needed>

此外,您无需向 configure 脚本告知有关您的 CUDA 的任何信息 - OpenCL 加载器库应使用其内部机制在 运行 时找到所有必需的 CUDA 库。