Building Boost* with Intel® oneAPI

ID 标签 676375
已更新 3/8/2022
版本 Latest
公共

author-image

作者

Introduction

This document explains how to build Boost* using the Intel® oneAPI Toolkits.

What is Boost*? From the Boost* website:

“Boost* provides free peer-reviewed portable C++ source libraries.

We emphasize libraries that work well with the C++ Standard Library. Boost* libraries are intended to be widely useful, and usable across a broad spectrum of applications. The Boost* license encourages both commercial and non-commercial use.”

We aim to establish "existing practice" and provide reference implementations so that Boost* libraries are suitable for eventual standardization. Ten Boost* libraries are included in the C++ Standards Committee's Library Technical Report (TR1) and in the C++11 Standard. C++11 also includes several more Boost* libraries in addition to those from TR1. More Boost* libraries are proposed for standardization in C++17.

Follow the Getting Started Guide which answers some open questions for details on how to download and install Boost*.

Building Boost* with Intel® C++ Compiler

Step 1 - Version information

This section is created to help Boost* users to make use of the Intel® C++ Compiler (icpx) on Windows platforms and Linux* platforms.

The instructions given in this section apply to Intel® C++ Compiler 2022.0. These have been verified with Intel® C++ Compiler 2022.0.0 from Intel® oneAPI Base Toolkit and Boost* 1.75.0, Boost* 1.78.0.

Step 2 - Prerequisites

To build the Boost* library with Intel® C++ Compiler, the Intel® oneAPI Base Toolkit  is required. Begin by downloading the Boost* zip file or Boost* tar file from here.

Step 3 - Configuration

Windows platforms

  • Check your clang-cl version (clang-cl --version), for example, 2022.0.0.20211123.
  •  check your clang-cl path, for example, C:/Program Files (x86)/Intel/oneAPI/compiler/latest/windows/bin-llvm/clang-cl.exe" .
  • Add the following command into project-config.jam which is in folder <boost_root>, which means, you’ll add your clang-cl version, and then your clang-cl path. Please make sure there’s a space between each : and the last ;
using clang-win : 2022.0.0.20211123 : "C:/Program Files (x86)/Intel/oneAPI/compiler/latest/windows/bin-llvm/clang-cl.exe" ;

Linux platforms

  • If you use Boost* 1.75.0, which isn’t supported Intel® C++ Compiler (icpx), you can add the clang++ version and the clang++ path into the project-config.jam in folder <boost_root>, for example,
using clang : 2022.0.0.20211123 : " /opt/intel/oneapi/compiler/2022.0.1/linux/bin-llvm/clang++" ;
  • If you use Boost* 1.78.0, which has supported Intel® C++ Compiler (icpx), but when building Boost* 1.78.0 with Intel® C++ Compiler, the following error will be generated,
clang++: error: no such file or directory: 'bin.v2/libs/math/build/intel-linux-2022.0.0/release/threading-multi/visibility-hidden/pch.pchi'                        
clang++: error: unsupported argument 'h-create' to option '-pc'

It uses option “-pch-create” to generate the precompiled header “pch.pchi”. Option “-pch-create” is supported in Intel® C++ Compiler Classic compiler (icpc) but isn’t supported in Intel® C++ Compiler (icpx). User can use command “icpx -qnextgen-diag” to check. One workaround is, using the option “-emit-pch”, which is supported in clang* compiler. 

So, to fix this error, can modify intel-linux.jam file which is in folder <boost_root>/ tools/build/src/tools, about in line277

Modify the following code

actions compile.c++.pch
{
    rm -f "$(<)" && LD_LIBRARY_PATH="$(RUN_PATH)" "$(CONFIG_COMMAND)" -x c++-header $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -pch-create "$(<)" "$(>)"
}

to 

actions compile.c++.pch
{
rm -f "$(<)" && LD_LIBRARY_PATH="$(RUN_PATH)" "$(CONFIG_COMMAND)" -x c++-header $(OPTIONS) $(USER_OPTIONS) -D$(DEFINES) -I"$(INCLUDES)" -c -Xclang -emit-pch -o "$(<)" "$(>)"
}

 

Step 4 – Building and Installing Boost*


Windows platforms


The method works for both Boost* 1.75.0 and Boost* 1.78.0.
Go to Start -> Intel® oneAPI 2022 -> Intel® oneAPI command prompt
•    cd <boost_root>
•    bootstrap.bat
•    build the library you need, for example,
b2 install –prefix=<install_dir> --without-python --without-graph_parallel --without-mpi toolset=clang-win link=shared address-model=64 architecture=x86 runtime-link=shared


Linux platforms

If you use Boost* 1.75.0, 
•    Run “ source /opt/intel/oneapi/setvars.sh” 
•    cd <boost_root>
•    ./bootstrap.sh
•    build the library you need, for example,
./b2 install –prefix=<install_dir> --without-python --without-graph_parallel --without-mpi cxxstd=17  toolset=clang  link=shared address-model=64 architecture=x86 runtime-link=shared

If you use  Boost* 1.78.0.
•    Run “source /opt/intel/oneapi/setvars.sh” 
•    cd <boost_root>
•    ./bootstrap.sh
•    build the library you need, for example,
    ./b2 install –prefix=<install_dir> --without-python --without-graph_parallel --without-mpi cxxstd=17  toolset=intel-linux  link=shared address-model=64 architecture=x86 runtime-link=shared
 

Building Boost* with Intel® Classic Compiler

Step 1 - Version information

This section is created to help Boost* users to make use of the Intel® C++ Compiler Classic on Windows platforms and Linux* platforms.

The instructions given in this article apply to Intel® Classic Compiler 2021.1. These have been verified with Intel® C++ Compiler Classic 2021.1 from Intel® oneAPI Toolkits and Boost* 1.75.0.

Step 2 - Prerequisites

To build the Boost* library with Intel® oneAPI Toolkits, the Intel® oneAPI Base Toolkit and Intel® oneAPI HPC Toolkit are required. Begin by downloading the Boost* zip file or Boost* tar file from here.

Step 3 - Configuration

When using Intel® C++ Compiler to build Boost* library, by default B2 (B2 is a utility that makes it easy to build C++ projects ) will search in directory paths included in the environment variable PATH for an executable ‘icl.exe’ on Windows or ‘icpc’ on Linux*. Then using the path of ‘icl.exe’, B2 searches for the ‘iclvars.bat’ file for configuring the compiler environment (paths to header files and compiler libraries). However, the bat file in Intel® oneAPI Toolkits is in a different directory compared with that in Intel® Parallel Studio XE (IPSXE) product. Therefore, it is necessary to change the path where B2 searches for the bat file.

Windows Platforms

  • Modify the intel-win.jam in the folder <boost_root>\tools\build\src\tools.

According to analysis intel.jam and intel-win.jam, when using icl compiler in Intel® oneAPI ToolKits to build the Boost* library, B2 will look for the iclvars.bat in folder C:/Program Files (x86)/Intel/oneAPI/compiler/latest/windows/bin/. However, in Intel® oneAPI toolkits, the bat file is located in folder C:/Program Files (x86)/Intel/oneAPI/compiler/latest/env, and the bat file is named vars.bat, not iclvars.bat. So, we need to change the path where B2 searches for the compiler bat file, and change “iclvars.bat” to “vars.bat” in line179-line188. as below shows,

if $(command) || $(root)
{
local bin = [ common.get-absolute-tool-path $(command[-1]) ] ;
if $(major) >= 2021
{
bin = [ path.make $(bin) ] ;
bin = [ path.parent $(bin) ] ;
bin = [ path.parent $(bin) ] ;
bin = [ path.parent $(bin) ] ;
root ?= $(bin) ;
root = $(root)/env ;
}
else if $(major) >= 12 && $(major) < 2021
{
bin = [ path.make $(bin) ] ;
bin = [ path.parent $(bin) ] ;
root ?= $(bin) ;
root = $(root)/ ;
}
else
{
root ?= $(bin) ;
root = $(root)/ ;
}
}
local setup ;
if $(major) >= 2021
{
setup = [ path.glob $(root) : vars_*.bat ] ;
if ! $(setup)
{
setup = [ path.glob $(root) : "vars.bat" ] ;
setup = [ path.native $(setup) ] ;
}
}
else
{
setup = [ path.glob $(root) : iclvars_*.bat ] ;
if ! $(setup)
{
setup = [ path.join $(root) "iclvars.bat" ] ;
setup = [ path.native $(setup) ] ;
}
}
local target_types ;
local iclvars_vs_arg ;
if $(major) >= 12
{
# if we have a known intel toolset check for visual studio compatibility
# if not trust parameters
if ! [ is-msvc-supported $(version) : $(msvc-version) ]
{
errors.error "msvc $(msvc-version) not supported for intel toolset version $(version)" ;
}
if $(.iclvars-version-alias-$(compatibility))
{
iclvars_vs_arg = $(.iclvars-version-alias-$(compatibility)) ;
}
else
{
errors.error "Don't know what parameter to pass for vc version ( $(compatibility) )" ;
}
# There are two possible paths for the 64-bit intel compiler,
# one for the IA32-Intel64 cross compiler, and one for the native
# 64 bit compiler. We prefer the latter one if it's installed,
# and don't rely on whether the OS reports whether we're 64 or 32 bit
# as that really only tells us which subsystem bjam is running in:
#
if $(major) >= 2021
{
local intel64_path = [ path.parent $(root) ] ;
intel64_path = [ path.join $(intel64_path) windows/bin/intel64 ] ;
if [ path.glob $(intel64_path) : icl.exe ]
{
target_types = ia32 intel64 ;
}
else
{
target_types = ia32 ia32_intel64 ;
}
}
else
{
local intel64_path = [ path.join $(root) intel64 ] ;
if [ path.glob $(intel64_path) : icl.exe ]
{
target_types = ia32 intel64 ;
}
else
{
target_types = ia32 ia32_intel64 ;
}
}
}

At the same time, need to add the version of icl in Intel® oneAPI Toolkits and the version of msvc that supported in the end.

.iclvars-2021.1-supported-vcs = "14.2 14.1" ;
  • If you build the context library or other libraries that are depend on context library in Boost*,
    you need to add options “/c “ and “/Fo” into the assembler flags in line1888 in msvc.jam.
//msvc.jam
toolset.flags msvc.compile.asm ASMFLAGS <architecture>x86/<warnings>on : /W3 /c /Fo ;

Without adding these two options, there is a link error, as follows,

LINK : fatal error LNK1181: cannot open input file
'bin.v2\libs\context\build\intel-vc14.1-win-2021.1\debug\address-model-64\architecture-x86\link-static\runtime-link-static\threading-multi\asm\make_x86_64_ms_pe_masm.obj'
Assembling: libs\context\src\asm\make_x86_64_ms_pe_masm.asm

call "bin.v2\standalone\msvc\intel\address-model-64\architecture-x86\msvc-setup.bat" ia32_intel64 vs2017 >nul
ml64 -nologo -DBOOST_ALL_NO_LIB=1 -DBOOST_CONTEXT_EXPORT= -DBOOST_CONTEXT_SOURCE -D_WIN32_WINNT=0x0601 /Zi /Zd /W3 "bin.v2\libs\context\build\intel-vc14.1-win-2021.1\debug\address-model-64\architecture-x86\link-static\runtime-link-static\threading-multi\asm\make_x86_64_ms_pe_masm.obj" "libs\context\src\asm\make_x86_64_ms_pe_masm.asm"

Analyzing the command it calls, the compiler ml64 is supposed to compile the assembly file "libs\context\src\asm\make_x86_64_ms_pe_masm.asm" to get the object file ‘make_x86_64_ms_pe_masm.obj’ and put the object file into the folder “bin.v2\libs\context\build\intel-vc14.1-win-2021.1\debug\address-model-64\architecture-x86\link-static\runtime-link-static\threading-multi\asm”. However, due to the lack of option ‘/c’ and option ‘/Fo’, there is a link error.

  • If you build Python* library in Boost* with icl compiler, you may get the below errors,
C:\Users \AppData\Roaming\Python\Python37\site-packages\numpy\core\include\numpy/ndarraytypes.h(84): error: expected a "}"
NPY_CHAR NPY_ATTR_DEPRECATE("Use NPY_STRING"),
^
C:\Users\AppData\Roaming\Python\Python37\site-packages\numpy\core\include\numpy/ndarraytypes.h(89): warning #12: parsing restarts here after previous syntax error
};
^
C:\Users\AppData\Roaming\Python\Python37\site-packages\numpy\core\include\numpy/ndarraytypes.h(455): error: identifier "NPY_NTYPES_ABI_COMPATIBLE" is undefined
PyArray_VectorUnaryFunc *cast[NPY_NTYPES_ABI_COMPATIBLE];
^

Analyzing the below codes in ndarraytypes.h file in folder <python_root>\ Lib\site-packages\numpy\core\include\numpy, when using icl compiler, ‘NPY_ATTR_DEPRECATE(text)’ will be defined to ‘__attribute__ ((deprecated (text)))’, but ‘__attribute__’ isn’t supported by icl compiler, so there is a compilation error.

#if !defined(_NPY_NO_DEPRECATIONS) && \
((defined(__GNUC__)&& __GNUC__ >= 6) || \
__has_extension(attribute_deprecated_with_message))
#define NPY_ATTR_DEPRECATE(text) __attribute__ ((deprecated (text)))
#else
#define NPY_ATTR_DEPRECATE(text)
#endif ⋮
enum NPY_TYPES { ⋮
NPY_CHAR NPY_ATTR_DEPRECATE("Use NPY_STRING"), ⋮
};

A workaround is, in file <boost_root> \boost\python\numpy\ internal.hpp, before including < numpy/arrayobject.h >, defining a macro ‘_NPY_NO_DEPRECATIONS ‘, then undefining it. As shown below,

#define _NPY_NO_DEPRECATIONS
#include <numpy/arrayobject.h>
#undef _NPY_NO_DEPRECATIONS

 

Linux* platforms

Modify the file intel-linux.jam in folder <boost_root>/ tools/build/src/tools in line67, add the path of icpc compiler in Intel® oneAPI Toolkits

if [ MATCH "(2021[.]1)" : $(version) ]
{ default_path = /opt/intel/oneapi/compiler/latest/linux/bin/intel64 ; }
else if [ MATCH "(12[.]0|12)" : $(version) ]
{ default_path = /opt/intel/bin ; }

Step 4 – Building and Installing Boost*

Windows Platforms

Go to Start -> Intel® oneAPI 2021 -> Intel® oneAPI command prompt

  • cd <boost_root>
  • bootstrap.bat
  • build the library you need, for example,
    • b2 install –prefix=<Boost.Build install dir> --without-python --without-graph_parallel --without-mpi toolset=intel-2021.1-vc14.1 link=shared address-model=64 architecture=x86 runtime-link=shared

Linux platforms

  • Run “ source /opt/intel/oneapi/compiler/2021.1.1/env/vars.sh”
  • cd <boost_root>
  • ./bootstrap.sh
  • build the library you need, for example,
    • ./b2 install –prefix=<Boost.Build install dir> --without-python --without-graph_parallel --without-mpi toolset=intel-2021.1-vc14.1 link=shared address-model=64 architecture=x86 runtime-link=shared

Note: If you build Python* library or mpi or graph_parallel library in Boost* on Windows or on Linux* , please config the user-config.jam, which is in the folder <boost_root>/tools/build/example, for example, on Linux* 

using mpi : : <find-shared-library>impi ;
using python : 3.7 : /opt/intel/oneapi/intelpython/python3.7 : /opt/intel/oneapi/intelpython/python3.7/include/python3.7m : /opt/intel/oneapi/intelpython/python3.7/lib ;

And specify its location using ‘--user-config’ option while calling b2, like,

 ./b2 --user-config=<boost_root>/tools/build/example/user-config.jam ...