I have a question about to use offload pragma.
I wrote a small programm. This program succeeds.
[cpp]int main() {
float *x = (float *) _mm_malloc(100 * sizeof(float),64);
#pragma offload target (mic:0) \
in(x : length(100) ALLOC)
{
}
#pragma offload target(mic:0) \
nocopy(x : length(100) REUSE)
{
x[0] = 0;
}
#pragma offload target (mic:0) \
nocopy(x : length(0) FREE)
{
}
_mm_free(x);
}[/cpp]
But if I move some of code to function.
[cpp] void f1(float *x) {
#pragma offload target(mic:0) \
nocopy(x : length(100) REUSE)
{
x[0] = 0;
}
}
int main( ) {
float *x = (float *) _mm_malloc(100 * sizeof(float),64);
#pragma offload target (mic:0) \
in(x : length(100) ALLOC)
{
}
f1(x);
#pragma offload target (mic:0) \
nocopy(x : length(0) FREE)
{
}
_mm_free(x);
}[/cpp]
The program crashes and generates this error
HOST--ERROR:myoiScifGetRecvId: Call recv() Header Failed ! for source: 1, errno = 104
CARD--ERROR:1 myoiPageFaultHandler: (nil) Out of Range!
CARD--ERROR:1 _myoiPageFaultHandler: (nil) switch to default signal handle
CARD--ERROR:1 Segment Fault!
offload error: process on the device 0 unexpectedly exited with code 1
offload error: process on the device 0 was unexpectedly terminated
I don't understand why first version program successes, but second version program crashes.
Thanks.
链接已复制
In the function f1, use IN with REUSE/RETAIN and length(0) to create an instance of the pointer within that scope and allow the offload RTL to associate it with target pointer/memory allocated in main. Also use RETAIN in main.
[cpp]#define ALLOC alloc_if(1)
#define FREE free_if(1)
#define REUSE alloc_if(0)
#define RETAIN free_if(0)
void f1(float *x) {
//#pragma offload target(mic:0) nocopy(x : length(100) REUSE)
#pragma offload target(mic:0) in(x : length(0) REUSE RETAIN)
{
x[0] = 50.0f;
printf("modify x[0] = %f\n",x[0]);
fflush(0);
}
}
int main( ) {
float *x = (float *) _mm_malloc(100 * sizeof(float),64);
// #pragma offload target (mic:0) in(x : length(100) ALLOC )
#pragma offload target (mic:0) in(x : length(100) ALLOC RETAIN)
{
x[0] = 100.0f;
printf("init x[0] = %f\n",x[0]);
fflush(0);
}
f1(x);
#pragma offload target (mic:0) nocopy(x : length(0) FREE)
{
printf("final x[0] = %f\n",x[0]);
fflush(0);
}
_mm_free(x);
}[/cpp]
[cpp]$ icc -V
Intel(R) C Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 13.1.2.183 Build 20130514
$ icc test.c && ./a.out
init x[0] = 100.000000
modify x[0] = 50.000000
final x[0] = 50.000000[/cpp]
Some good resources to check out:
This Sticky post: FAQs: Compiler
Effective Use of the Intel Compiler's Offload Features
Behind the Scenes: Offload Memory Management on the Intel® Xeon Phi™ coprocessor
