Software Archive
Read-only legacy content
17061 Discussions

MIC offload using C++

Salvadore__Francesco
1,246 Views

Hello,

I am trying to port a C++ code using the offload mic directives. I have developed a toy code,

but I cannot manage offload computations using member classes. The code I am working on is provided below.

main.cpp:

[cpp]#include "foo.h"

int main()
{
        foo fo(2,2,2);
        fo.transfer_on_mic();
        fo.compute();
}[/cpp]

foo.cpp:

[cpp]

#include "foo.h"
#include "work.h"
foo::foo(int size1_,int size2_,int size3_):size1(size1_),size2(size2_),size3(size3_)
{
        p_simple=new float[size1*size2*size3];

        for(int i=0;i<size1;i++)
                for(int j=0;j<size2;j++)
                        for(int k=0;k<size3;k++)
                                p_simple[i*size3*size2+j*size3+k] = 23.F;
}

void foo::transfer_on_mic()
{
#pragma offload_transfer target(mic:1) in(p_simple:length(size1*size2*size3) alloc_if(1) free_if(0))
}

void foo::compute()
{
#pragma offload target(mic:1) in(p_simple:length(0) alloc_if(0) free_if(0))
        {
                work_simple(p_simple,size1,size2,size3);
        }

}

[/cpp]

work.cpp

[cpp]

#include <stdio.h>
#include "work.h"

__declspec(target(mic)) void work_simple(float *field,int maxi,int maxj ,int maxk)
{
        for(int i=0;i<maxi;i++)
                for(int j=0;j<maxj;j++)
                        for(int k=0;k<maxk;k++)
                                printf("%f \n", field[i*maxk*maxj+j*maxk+k]);

}

[/cpp]

[cpp]

#ifndef FOO_H
#define FOO_H
#pragma offload_attribute (push,target(mic))
struct foo{
        foo(int ,int ,int);

        void transfer_on_mic();
        void compute();

        float *p_simple;

        int size1,size2,size3;
};
#pragma offload_attribute (pop)
#endif

[/cpp]

[cpp]

#ifndef WORK_H
#define WORK_H
__declspec(target(mic)) void work_simple(float *field,int,int,int);
#endif

[/cpp]

The offload_trasfer seems to work, while the offloaded computation results in a sigsegv error.

Thanks,

Francesco

0 Kudos
6 Replies
Kevin_D_Intel
Employee
1,246 Views

foo.cpp fails to compile. I believe the code I have is what was provided but I'll check again.

$ icpc -c foo.cpp
foo.cpp(16): error: invalid entity for this variable list in
  #pragma offload_transfer target(mic:1) in(p_simple : lengt
 alloc_if(1) free_if(0))
                                            ^

foo.cpp(21): error: invalid entity for this variable list in
  #pragma offload target(mic:1) in(p_simple : length(0) allo
                                   ^

compilation aborted for foo.cpp (code 2)

0 Kudos
Kevin_D_Intel
Employee
1,246 Views

Development’s guidance is that p_simple is a data member of the class, we don't support its usage in offload clauses, and we started diagnosing this in 14.0, which is why I suffered the compilation error. I confirmed this code compiled successfully with 13.1 but suffers the seg-fault you noted.

We have an open feature request for this support in a future release (internal tracking id below) and I will keep this thread updated on the availability of that support in a future release as I learn it.

There is a work around available of using a temporary pointer. This is accomplished with the following changes:

In foo.h, after line 16, add the following declaration:

       static float *p_tmp;

In foo.cpp, make the following changes:

1. After line 22 (before the offload_transfer), add this assignment:

        p_tmp = p_simple;

2. On lines 23, 30, and 34, change the reference for p_simple to p_tmp.

These changes are using with both 13.1 and 14.0 compilers.

(Internal tracking id: DPD200356158)
(Resolution Update on 09/16/2014): This defect is fixed in the Intel® Parallel Studio XE 2015 Initial Release (2015.0.090 - Linux)

0 Kudos
Christof_Soeger
Beginner
1,246 Views

What exactly is the requirement for p_simple? Just not a class member?

In my case a global variable would be not so nice. So I tried it with a method local variable. In this example I just put

float *p_tmp = p_simple;

in front of the offloads in transfer_on_mic and compute, and removed the

static float *p_tmp;

from the header. And it does work. Is this supposed to work, or do I have to be careful here?

I want to use it for a slightly more complicated problem, but I probably start a new thread for that.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,246 Views

In your original code, on the host, what you see in the source code is p_simple, what you are actually using is this->p_simple. On the offload side, the code is only seeing p_simple without a corresponding this object. By making it a local variable (float *p_tmp = p_simple;) you've removed the hidden "this->".

Jim Dempsey

0 Kudos
Kevin_D_Intel
Employee
1,246 Views

Feature support for using a data member of the class within the offload clause is now available in the latest Intel® Parallel Studio XE 2015 initial release for both Linux and Windows.

The test case in the original post successfully compiles and produces expected results using the Intel® Parallel Studio XE 2015 Initial Release (2015.0.090 - Linux).

0 Kudos
KIMATHI__ONESMUS
Beginner
1,246 Views

Woow!

0 Kudos
Reply