2014-09-23 71 views
1

在此代碼:外部函數使用的設備內存變量如何?

#include <iostream> 

void intfun(int * variable, int value){ 
    #pragma acc parallel present(variable[:1]) num_gangs(1) num_workers(1) 
    { 
     *variable = value; 
    } 
} 

int main(){ 
    int var, value = 29; 

    #pragma acc enter data create(var) copyin(value) 
     intfun(&var,value); 
    #pragma acc exit data copyout(var) delete(value) 

    std::cout << var << std::endl; 
} 

如何int value認爲是在設備內存在intfun?如果我在intfun編譯取代present(variable[:1])通過present(variable[:1],value),我得到以下運行時錯誤:

FATAL ERROR: data in PRESENT clause was not found on device 1: name=_43144_33_value 
file:/opt/pgi/linux86-64/14.9/include/CC/iostream intfun__FPii line:5 
Present table dump for device[1]: NVIDIA Tesla GPU 1, compute capability 3.5 
host:0x7fffc11faa28 device:0x2303f20200 size:4 presentcount:1 line:14 name:_43152_14_value 
host:0x7fffc11faa34 device:0x2303f20000 size:4 presentcount:2 line:14 name:_43152_9_var 

我不明白爲什麼指定valuepresent導致上述故障。我使用NVVP進行了檢查,value僅在enter data指令中被複制一次,即它不會在intfunparallel指令中再次被複制。 OpenACC如何發揮其魔力?

回答

4

你已經被自己的語法和已經指出的內容再次弄糊塗了。

intfunvalue是不一樣的value您在maincopyin(value)。該函數調用通過值value,意味着它使副本它。因此將其添加到present()子句是沒有意義的,因爲它在設備上的不存在。編譯器必須將其複製。(並且,如果根本沒有提及它,編譯器會自動識別它是否需要並將其複製到您的目錄中。)

存在的項目在設備上是main -scope變量value,這是未使用intfun。給所有的變量同名可能無助於你理解這一點。

爲了證明這一點,讓我們通過value通過引用代替由值

$ cat main8.cpp 
#include <iostream> 

void intfun(int * variable, int &value){ 
    #pragma acc parallel present(variable[:1],value) num_gangs(1) num_workers(1) 
    { 
     *variable = value; 
    } 
} 

int main(){ 
    int var, value = 29; 

    #pragma acc enter data create(var) copyin(value) 
     intfun(&var,value); 
    #pragma acc exit data copyout(var) delete(value) 

    std::cout << var << std::endl; 
} 
[[email protected] misc]$ pgcpp -acc -Minfo main8.cpp 
intfun(int *, int &): 
     5, Generating present(variable[:1]) 
     Generating present(value[:]) 
     Accelerator kernel generated 
     Generating Tesla code 
main: 
    14, Generating enter data copyin(value) 
     Generating enter data create(var) 
    17, Generating exit data delete(value) 
     Generating exit data copyout(var) 
$ ./a.out 
29 
$ 

現在主要範圍的可變value是在設備上,編譯器知道它,它會被用於通過intfun直接,並將其添加到present子句是合法和功能。

+0

然後我不明白爲什麼在我的起源例子中,如果我省略'main'中編譯指令中的'copyin(value)'和'delete(value)','value'不會複製到設備上, 。設備從哪裏檢索29的值?這存儲在主機內存中,因此必須在某個點上將其複製到設備內存中? – lodhb 2014-09-24 19:07:36

+1

我已經在我的回答中說過,如果你省略了任何提及'value'的東西,編譯器會自動識別內核需要'value',它會自動爲它生成所需的副本。只有當你指定'present'時纔會覆蓋這個行爲,那麼事情就會破裂。如果您有一個新問題,即您不明白的其他問題,它基於與問題中顯示的代碼不同的代碼,那麼您可能會提出一個新問題。 'main'中的'copyin(value)'與你的原始代碼無關,你的原始代碼在沒有它的情況下工作得很好。 – 2014-09-24 19:20:59

+0

我已經用NVVP驗證過,在'main'中省略''copyin''的值'導致沒有主機到設備的數據傳輸。因此,我對設備從哪裏獲得「價值」的價值感到困惑。 – lodhb 2014-09-24 19:26:44

相關問題