Home > Back-end >  How to build SYCL programs using DPC & CMake?
How to build SYCL programs using DPC & CMake?

Time:10-03

Background

I'm trying to learn SYCL using CUDA backend (I compiled dpc compiler using these instructions and vector addition worked). However, the next day I couldn't get the first example from the book to work by using CMake, however using command line and invoking compiler directly solved the problem.

#include <CL/sycl.hpp>
#include <iostream>
#include <string>

using namespace sycl;

const std::string secret =
    "Ifmmp-!xpsme\"\012J(n!tpssz-!Ebwf/!"
"J(n!bgsbje!J!dbo(u!ep!uibu/!.!IBM\01";

const auto sz = secret.size();

int main() {
    queue Q;

    char* result = malloc_shared<char>(sz, Q);
    std::memcpy(result, secret.data(), sz);

    Q.parallel_for(sz, [=](auto& i) {
        result[i] -= 1;
    }).wait();

    std::cout << result << '\n';
}

I use this script to setup environment variables:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/shino/software/sources/llvm/build/lib/
export DPCPP_HOME=/home/shino/software/sources
export CUDA_LIB_PATH=/usr/local/cuda/lib64/stubs/
export CXX=/home/shino/software/sources/llvm/build/bin/clang  
export CC=/home/shino/software/sources/llvm/build/bin/clang
export CUDA_PATH=/usr/local/cuda

And here is my CMakeLists.txt:

cmake_minimum_required(VERSION 3.20)
project(sycl-convolution)

add_executable(convolution main.cpp)
target_include_directories(convolution PRIVATE /home/shino/software/sources/llvm/sycl/include)
target_compile_features(convolution PRIVATE cxx_std_17)
target_compile_options(convolution PRIVATE -fsycl -fsycl-targets=nvptx64-nvidia-cuda --cuda-path=$ENV{CUDA_PATH})
target_link_directories(convolution PRIVATE /home/shino/software/sources/llvm/build/lib/)

Here are the first few lines of linker errors:

/usr/bin/ld: CMakeFiles/convolution.dir/main.cpp.o: in function `main':
main-4cf7ed.cpp:(.text 0x122): undefined reference to `cl::sycl::event::wait()'
/usr/bin/ld: CMakeFiles/convolution.dir/main.cpp.o: in function `main::{lambda(auto:1&)#1} cl::sycl::queue::submit<cl::sycl::queue::parallel_for_impl<cl::sycl::detail::auto_name, main::{lambda(auto:1&)#1}, 1>(cl::sycl::range<1>, main::{lambda(auto:1&)#1}, cl::sycl::detail::code_location const&)::{lambda(cl::sycl::handler&)#1}>(cl::sycl::queue::parallel_for_impl<cl::sycl::detail::auto_name, main::{lambda(auto:1&)#1}, 1>(cl::sycl::range<1>, main::{lambda(auto:1&)#1}, cl::sycl::detail::code_location const&)::{lambda(cl::sycl::handler&)#1}, cl::sycl::detail::code_location const)':
main-4cf7ed.cpp:(.text 0x3c0): undefined reference to `cl::sycl::event::event()'
/usr/bin/ld: main-4cf7ed.cpp:(.text 0x3cc): undefined reference to `cl::sycl::queue::is_host() const'
/usr/bin/ld: main-4cf7ed.cpp:(.text 0x47b): undefined reference to `cl::sycl::queue::submit_impl_and_postprocess(std::function<void (cl::sycl::handler&)>, cl::sycl::detail::code_location const&, std::function<void (bool, bool, cl::sycl::event&)> const&)'
/usr/bin/ld: main-4cf7ed.cpp:(.text 0x543): undefined reference to `cl::sycl::queue::submit_impl(std::function<void (cl::sycl::handler&)>, cl::sycl::detail::code_location const&)'
/usr/bin/ld: CMakeFiles/convolution.dir/main.cpp.o: in function `void cl::sycl::handler::parallel_for_lambda_impl<cl::sycl::detail::auto_name, main::{lambda(auto:1&)#1}, 1>(cl::sycl::range<1>, main::{lambda(auto:1&)#1})':
main-4cf7ed.cpp:(.text 0xa23): undefined reference to `cl::sycl::handler::GetRangeRoundingSettings(unsigned long&, unsigned long&, unsigned long&)'

How do I fix this? My gut feeling tells me that compiler invokes linker differently when invoked directly and I'm not specifying some very important part of linkage process.

Invoking the compiler with verbose mode gave the following link command:

 "/usr/bin/ld" -z relro --hash-style=gnu --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o a.out /lib/x86_64-linux-gnu/crt1.o /lib/x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/9/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/9 -L/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib64 -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib64 -L/home/shino/software/sources/llvm/build/bin/../lib -L/lib -L/usr/lib /tmp/main-7d74d3.o /tmp/a-cacdd3.o -lstdc   -lm -lgcc_s -lgcc -lsycl -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/9/crtend.o /lib/x86_64-linux-gnu/crtn.o

Other than linker errors, there were a lot more warnings, which suggests than the compiler is not in the correct "mode". I do not know where to start digging next.

CodePudding user response:

You're missing the actual libraries to link with, specify them with target_link_libraries directive. Find more information inside CMake's documentation.

Note that target_link_directories is not enough - it only specifies the paths of the libraries the linker should search for.

More specifically, from reading the link command you've posted, you should add:

target_link_libraries(convolution PRIVATE sycl)

Addition by the OP: Adding SYSTEM to the target_include_directories directive will silence the warnings:

target_include_directories(convolution SYSTEM PRIVATE /home/shino/software/sources/llvm/sycl/include) 
  • Related