如何仅禁用一项功能的Cuda主机设备警告?

时间:2019-04-02 18:17:37

标签: c++ cuda closures c++14 pragma

我的Cuda代码中有一个C ++ 14模板,该模板以lambda闭包为模板,分别为__device__warning: calling a __host__ function("Iter<(bool)1> ::Iter [subobject]") from a __host__ __device__ function("Horizontal::Horizontal") is not allowed ,并得到警告:

__host__

但这是一个错误的肯定,因为调用模板__host__的只是模板的#pragma hd_warning_disable 实例,因此我希望仅针对一个模板定义取消此警告。

我可以在模板之前添加它:

#pragma hd_warning_enable

警告消失了,但是,我担心我只希望针对该一个模板功能而不是对编译单元的其余部分禁止它。我不能轻易地将模板功能移至编译单元的末尾。

我想要某种推送和弹出,但是我在任何地方都找不到。

在定义了模板功能之后,是否有一种方法可以重新启用高清警告?

我尝试过:

test.cu:44:0: warning: ignoring #pragma 
hd_warning_enable  [-Wunknown-pragmas]
 #pragma hd_warning_enable

但这不起作用:

//#pragma hd_warning_disable

template<typename Lambda>
__host__ __device__
int hostDeviceFunction(const Lambda lambda)
{
    return lambda();
}


__device__
int deviceFunction()
{
    auto lambda = []() { return 0.0; };

    return hostDeviceFunction( lambda );
}

__host__
int hostFunction()
{
    auto lambda = []() { return 1.0; };

    return hostDeviceFunction( lambda );
}

以下是一个简单的测试案例来说明问题:

test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
          detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]" 
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
          detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]" 
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
          detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]" 
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
          detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]" 
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
          detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]" 
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
          detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]" 
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
          detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]" 
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
          detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]" 
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
          detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]" 
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
          detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]" 
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed
test.cu(7): warning: calling a __host__ function from a __host__ __device__ function is not allowed
          detected during instantiation of "int hostDeviceFunction(Lambda) [with Lambda=lambda []()->double]" 
(24): here
test.cu(7): warning: calling a __host__ function(" const") from a __host__ __device__ function("hostDeviceFunction< ::> ") is not allowed

其中给出以下警告:

import tkinter as tk
from tkinter import ttk

class App(tk.Frame):

    def __init__(self,):

        super().__init__()

        self.master.title("Hello World")

        self.init_ui()

    def init_ui(self):

        f = tk.Frame()

        tk.Label(f, text = "Buon Appetito").pack()
        cols = (["#0",'','w',False,200,200],
                 ["#1",'','w',True,0,0],)

        self.Pasta = self.get_tree(f, cols, show="tree")
        self.Pasta.show="tree"
        self.Pasta.pack(fill=tk.BOTH, padx=2, pady=2)
        self.Pasta.bind("<<TreeviewSelect>>", self.on_selected)
        self.Pasta.bind("<Double-1>", self.on_double_click)

        w = tk.Frame()

        tk.Button(w, text="Load", command=self.set_values).pack()
        tk.Button(w, text="Close", command=self.on_close).pack()

        w.pack(side=tk.RIGHT, fill=tk.BOTH, expand=0)
        f.pack(side=tk.LEFT, fill=tk.BOTH, expand=0)

    def set_values(self,):

        #.insert(parent, index, iid=None, **kw)
        rs = [(0,'Spaghetti'),(1,'Rigatoni'),(2,'Pennette')]

        for i in rs:
            #print(i)
            pasta = self.Pasta.insert("", i[0], text=i[1], values=(i[0],'pasta'))
            rs_dishes = self.load_dishes(i[0])
            if rs_dishes is not None:
                for dish in rs_dishes:
                    #print(dish)
                    wards = self.Pasta.insert(pasta, dish[0],text=dish[1], values=(dish[0],'dishes'))


    def load_dishes(self, i):

        rs = [(0,'Spaghetti aglio e olio'),
              (1,'Rigatoni alla matriciana'),
              (1,'Rigatoni al pesto'),
              (1,'Rigatoni alla norma'),
              (2,'Pennette al pesto'),
              (2,'Pennette alla wodka'),
              (2,'Pennette al tartufo'),
              (0,'Spaghetti allo scoglio'),
              (0,'Spaghetti al pesto'),
              (0,'Spaghetti alla carbonara'),
              (0,'Spaghetti alla puttanesca')]

        r = [x for x in rs if x[0] == i]

        return r

    def on_selected(self, evt=None):

        selected_item = self.Pasta.focus()

        d = self.Pasta.item(selected_item)

        if d['values']:
            if d['values'][1]=='dishes':

                pk = d['values'][0]

                print("pk: {}".format(pk))


    def on_double_click(self, evt=None):

        if self.Pasta.focus():
            item_iid = self.Pasta.selection()    
            pk = self.Pasta.item(self.Pasta.focus())['text']

            print(item_iid, pk)


    def get_tree(self,container, cols, size=None, show=None):

        headers = []

        for col in cols:
            headers.append(col[1])
        del headers[0]

        if show is not None:
            w = ttk.Treeview(container,show=show)
        else:
            w = ttk.Treeview(container,)

        w['columns']=headers

        for col in cols:
            w.heading(col[0], text=col[1], anchor=col[2],)
            w.column(col[0], anchor=col[2], stretch=col[3],minwidth=col[4], width=col[5])

        sb = ttk.Scrollbar(container)
        sb.configure(command=w.yview)
        w.configure(yscrollcommand=sb.set)

        w.pack(side=tk.LEFT, fill=tk.BOTH, expand =1)
        sb.pack(fill=tk.Y, expand=1)

        return w

    def on_close(self):
        self.master.destroy()

if __name__ == '__main__':
    app = App()
    app.mainloop()

2 个答案:

答案 0 :(得分:3)

不需要使用#pragma hd_warning_enable之类的东西,因为#pragma hd_warning_enable仅会影响放置在其前面的功能。 看来这在任何文档中都找不到,但是下面的示例表明了这种行为。

旁注: 也有#pragma nv_exec_check_disable,流行的库已迁移到该实用程序。 参见例如this conversation

#include <iostream>
#include <cassert>

#pragma hd_warning_disable
//#pragma nv_exec_check_disable
template<typename Lambda>
__host__ __device__
int hostDeviceFunction1(const Lambda lambda)
{
    return lambda()*1.0;
}

__host__            
int hostFunction1()
{
    auto lambda = []() { return 1.0; };  
    return hostDeviceFunction1( lambda );
}

template<typename Lambda>
__host__ __device__
int hostDeviceFunction2(const Lambda lambda)
{                                       
    return lambda()*2.0;
}

__host__
int hostFunction2()
{
    auto lambda = []() { return 2.0; };  
    return hostDeviceFunction2( lambda );
}

int main()           
{ 
  std::cout << "hostFunction1: " << hostFunction1() << std::endl;
  assert(hostFunction1() == 1.0);

  std::cout << "hostFunction2: " << hostFunction2() << std::endl;
  assert(hostFunction2() == 4.0);

  return 0;
}
$ nvcc pragma_test.cu 
pragma_test.cu(24): warning: calling a __host__ function from a __host__ __device__ function is not allowed
          detected during instantiation of "int hostDeviceFunction2(Lambda) [with Lambda=lambda []()->double]" 
(31): here

答案 1 :(得分:1)

在某些情况下,避免警告的另一种方法是制作较低级的函数sum((n-2*a) for a in 1...n/2) = n²/4 - n/2 = Ω(n²).并使用constexpr标志。

例如:

--expt-relaxed-constexpr

与未记录的实用程序相比,这具有template<typename Lambda> constexpr int constexprFunction(Lambda&& lambda) { return lambda(); } __host__ int hostFunction() { auto lambda = []() { return 1.0; }; return constexprFunction( lambda ); } __host__ __device__ int hostDeviceFunction() { auto lambda = []() { return 0.0; }; return constexprFunction( lambda ); } 的效果已被准确记录的优点,尽管constexpr的确切行为仍未被记录,并且其与标准的一致性不是100%。例如,以上示例在C ++ 14模式下使用nvcc 10.1.243,但在C ++ 11下不起作用。并且,如果将函数的签名更改为nvcc,警告仍然会出现,因此constexpr int constexprFunction(const Lambda lambda)似乎并没有在所有情况下都起作用。而且,如果您添加了--expt-relaxed-constexpr函数,则会以下列两种方式导致错误:

__device__