Intel® oneAPI Base Toolkit
Support for the core tools and libraries within the base toolkit that are used to build and deploy high-performance data-centric applications.

## Use mathimf.h with dpcpp

Beginner
1,628 Views

Hi,
I followed this example:
https://software.intel.com/content/www/us/en/develop/documentation/oneapi-dpcpp-cpp-compiler-dev-guide-and-reference/top/optimization-and-programming-guide/intel-math-library/using-the-intel-math-library.html#using-the-intel-math-library

But I encountered an issue at compile time:

u48526@login-2:~/test_mathimf\$ cat test_mathimf.cpp
// real_math.c
#include <stdio.h>
#include <mathimf.h>

int main()
{
float fp32bits;
double fp64bits;
long double fp80bits;
long double pi_by_four = 3.141592653589793238/4.0;

// pi/4 radians is about 45 degrees
fp32bits = (float) pi_by_four; // float approximation to pi/4
fp64bits = (double) pi_by_four; // double approximation to pi/4
fp80bits = pi_by_four; // long double (extended) approximation to pi/4

// The sin(pi/4) is known to be 1/sqrt(2) or approximately .7071067
printf("When x = %8.8f, sinf(x) = %8.8f \n", fp32bits, sinf(fp32bits));
printf("When x = %16.16f, sin(x) = %16.16f \n", fp64bits, sin(fp64bits));
printf("When x = %20.20Lf, sinl(x) = %20.20Lf \n", fp80bits, sinl(fp80bits));

return 0;
}
u48526@login-2:~/test_mathimf\$ icpc test_mathimf.cpp
u48526@login-2:~/test_mathimf\$ dpcpp test_mathimf.cpp
test_mathimf.cpp:3:10: fatal error: 'mathimf.h' file not found
#include <mathimf.h>
^~~~~~~~~~~
1 error generated.

The fact is that I need to use sqrt and log functions in a oneAPI kernel so I cannot compile that part of code with icpc.

I also tried to use math.h but this issue occures at runtime:

terminate called after throwing an instance of 'cl::sycl::compile_program_error'
what(): The program was built for 1 devices
Build program log for 'Intel(R) Xeon(R) Gold 6128 CPU @ 3.40GHz':
Linking started
Linking done
Device build started
Options used by backend compiler:
Failed to build device program
Error: unimplemented function(s) used:
__svml_log16_mask is undefined
__svml_sqrt16_mask is undefined
CompilerException Failed to parse IR
-17 (CL_LINK_PROGRAM_FAILURE)

Is there a way to have sqrt and log functions for oneAPI kernels?

1 Solution
Moderator
1,609 Views

Hi,

Thanks for reaching out to us.

If you want to use sqrt, log, or any other math functions, then no need to compile the code with icpc. You can directly write the kernel, add function to it and compile with dpcpp.

For more details, you can refer to the below code. In this, I tried to used sqrt and log inside kernel with CPU selector. You can directly compile it with dpcpp.

``````#include <CL/sycl.hpp>
#include <iostream>
using namespace cl::sycl;

#define SIZE 20

int main(){

queue q;

double* A;
double* d_A;

q = queue(cpu_selector{});

A = (double* )malloc(sizeof(double)*SIZE);
for(int i=0; i<SIZE; ++i)
A[i] = i+1;

d_A = (double *)malloc_device(sizeof(double)*SIZE, q.get_device(), q.get_context());

std::cout << "Before" << "\n";
for(int i=0; i<SIZE; ++i)
std::cout << A[i] << " ";
std::cout << "\n";

q.memcpy(d_A, A, sizeof(double)*SIZE).wait();
q.parallel_for(range<1>{SIZE}, [=](id<1> i){
if(i<10)
d_A[i] = sycl::sqrt((double)i+1);
else
d_A[i] = sycl::log((double)i+1);
});
q.wait();
q.memcpy(A, d_A, sizeof(double)*SIZE).wait();

std::cout << "After" << "\n";
for(int i=0; i<SIZE; ++i)
std::cout << A[i] << " ";
std::cout << "\n";

std::free(A);
sycl::free(d_A, q.get_context());

return 0;
}
``````

Hope this will help you to solve your issue.

Warm Regards,

Abhishek

3 Replies
Moderator
1,610 Views

Hi,

Thanks for reaching out to us.

If you want to use sqrt, log, or any other math functions, then no need to compile the code with icpc. You can directly write the kernel, add function to it and compile with dpcpp.

For more details, you can refer to the below code. In this, I tried to used sqrt and log inside kernel with CPU selector. You can directly compile it with dpcpp.

``````#include <CL/sycl.hpp>
#include <iostream>
using namespace cl::sycl;

#define SIZE 20

int main(){

queue q;

double* A;
double* d_A;

q = queue(cpu_selector{});

A = (double* )malloc(sizeof(double)*SIZE);
for(int i=0; i<SIZE; ++i)
A[i] = i+1;

d_A = (double *)malloc_device(sizeof(double)*SIZE, q.get_device(), q.get_context());

std::cout << "Before" << "\n";
for(int i=0; i<SIZE; ++i)
std::cout << A[i] << " ";
std::cout << "\n";

q.memcpy(d_A, A, sizeof(double)*SIZE).wait();
q.parallel_for(range<1>{SIZE}, [=](id<1> i){
if(i<10)
d_A[i] = sycl::sqrt((double)i+1);
else
d_A[i] = sycl::log((double)i+1);
});
q.wait();
q.memcpy(A, d_A, sizeof(double)*SIZE).wait();

std::cout << "After" << "\n";
for(int i=0; i<SIZE; ++i)
std::cout << A[i] << " ";
std::cout << "\n";

std::free(A);
sycl::free(d_A, q.get_context());

return 0;
}
``````

Hope this will help you to solve your issue.

Warm Regards,

Abhishek

Beginner
1,601 Views

Hi,

I understood my error with your example: I tried to use math or mathimf sqrt and log functions, which are not recognized at accelerator side. With sycl::sqrt and sycl::log, it is recognized.

Regards

Florent

Moderator
1,591 Views

Hi Florent,

Thanks for the confirmation, we will no longer monitor this thread as your issue is resolved.

Please post a new thread if you have any other issues.

Warm Regards,

Abhishek