Visible to Intel only — GUID: GUID-4B8C0B97-374C-4801-8FEB-26C06588738B
Example Compilation
oneAPI applications can be directly programmed, API-based, which makes use of available oneAPI libraries, or a combination of directly programmed and API-based. API-based programming takes advantage of device offload using library functionality, which can save developers time when writing an application. In general it is easiest to start with API-based programming and use SYCL* or OpenMP* offload features where API-based programming is insufficient for your needs.
The following sections give examples of API-based code and direct programming using SYCL.
API-based Code
The following code shows usage of an API call (a * x + y) employing the Intel oneAPI Math Kernel Library function oneapi::mkl::blas::axpy to multiply a times x and add y across vectors of floating point numbers. It takes advantage of the oneAPI programming model to perform the addition on an accelerator.
#include <vector> // std::vector()
#include <cstdlib> // std::rand()
#include <CL/sycl.hpp>
#include "oneapi/mkl/blas.hpp"
int main(int argc, char* argv[]) {
double alpha = 2.0;
int n_elements = 1024;
int incx = 1;
std::vector<double> x;
x.resize(incx * n_elements);
for (int i=0; i<n_elements; i++)
x[i*incx] = 4.0 * double(std::rand()) / RAND_MAX - 2.0;
// rand value between -2.0 and 2.0
int incy = 3;
std::vector<double> y;
y.resize(incy * n_elements);
for (int i=0; i<n_elements; i++)
y[i*incy] = 4.0 * double(std::rand()) / RAND_MAX - 2.0;
// rand value between -2.0 and 2.0
cl::sycl::device my_dev;
try {
my_dev = cl::sycl::device(cl::sycl::gpu_selector());
} catch (...) {
std::cout << "Warning, failed at selecting gpu device. Continuing on default(host) device.\n";
}
// Catch asynchronous exceptions
auto exception_handler = [] (cl::sycl::exception_list
exceptions) {
for (std::exception_ptr const& e : exceptions) {
try {
std::rethrow_exception(e);
} catch(cl::sycl::exception const& e) {
std::cout << "Caught asynchronous SYCL exception:\n";
std::cout << e.what() << std::endl;
}
}
};
cl::sycl::queue my_queue(my_dev, exception_handler);
cl::sycl::buffer<double, 1> x_buffer(x.data(), x.size());
cl::sycl::buffer<double, 1> y_buffer(y.data(), y.size());
// perform y = alpha*x + y
try {
oneapi::mkl::blas::axpy(my_queue, n_elements, alpha, x_buffer,
incx, y_buffer, incy);
}
catch(cl::sycl::exception const& e) {
std::cout << "\t\tCaught synchronous SYCL exception:\n"
<< e.what() << std::endl;
}
std::cout << "The axpy (y = alpha * x + y) computation is complete!" << std::endl;
// print y_buffer
auto y_accessor = y_buffer.template
get_access<cl::sycl::access::mode::read>();
std::cout << std::endl;
std::cout << "y" << " = [ " << y_accessor[0] << " ]\n";
std::cout << " [ " << y_accessor[1*incy] << " ]\n";
std::cout << " [ " << "... ]\n";
std::cout << std::endl;
return 0;
}
To compile and build the application (saved as axpy.cpp):
Ensure that the MKLROOT environment variable is set appropriately (echo ${MKLROOT}). If it is not set appropriately, source the setvars.sh | oneapi-vars.sh script or run the setvars.bat | oneapi-vars.bat script or set the variable to the folder that contains the lib and include folders.
For more information about the setvars and oneapi-vars scripts, see oneAPI Development Environment Setup.
Build the application using the following command:
On Linux:
icpx -fsycl -I${MKLROOT}/include -c axpy.cpp -o axpy.o
On Windows:
icpx -fsycl -I${MKLROOT}/include /EHsc -c axpy.cpp /Foaxpy.obj
Link the application using the following command:
On Linux:
icpx -fsycl axpy.o -fsycl-device-code-split=per_kernel \ "${MKLROOT}/lib/intel64"/libmkl_sycl.a -Wl,-export-dynamic -Wl,--start-group \ "${MKLROOT}/lib/intel64"/libmkl_intel_ilp64.a \ "${MKLROOT}/lib/intel64"/libmkl_sequential.a \ "${MKLROOT}/lib/intel64"/libmkl_core.a -Wl,--end-group -lsycl -lOpenCL \ -lpthread -lm -ldl -o axpy.out
On Windows:
icpx -fsycl axpy.obj -fsycl-device-code-split=per_kernel ^ "${MKLROOT}\lib\intel64"\mkl_sycl.lib ^ "${MKLROOT}\lib\intel64"\mkl_intel_ilp64.lib ^ "${MKLROOT}\lib\intel64"\mkl_sequential.lib ^ "${MKLROOT}\lib\intel64"\mkl_core.lib ^ sycl.lib OpenCL.lib -o axpy.exe
Run the application using the following command:
On Linux:
./axpy.out
On Windows:
axpy.exe
Direct Programming
The vector addition sample code is employed in this example. It takes advantage of the oneAPI programming model to perform the addition on an accelerator.
The following command compiles and links the executable.
icpx -fsycl vector_add.cpp
The components and function of the command and options are similar to those discussed in the API-Based Code section above.
Execution of this command results in the creation of an executable file, which performs the vector addition when run.