CUDA:如果函数在constexpr中,“在非void函数末尾缺少返回语句”

问题描述

当我编译以下测试代码时,会收到此警告:

test.cu(49): warning: missing return statement at end of non-void function "AllocateSize<T,D>(size_t) noexcept [with T=int,D=Device::GPU]"
          detected during instantiation of "Pointer<T,D> AllocateSize<T,D=Device::GPU]" 
(61): here

我应该担心吗,这是预期的吗?我该怎么做才能使其消失?这似乎很奇怪,因为cuda确实支持C ++ 17。预先感谢!

编译为:nvcc -std=c++17 test.cu -o test

测试代码test.cu):

enum class Device { cpu,GPU }; // Device

template <typename T,Device D>
class Pointer {
private:
    T* m_raw = nullptr;
    
public:
    __host__ __device__ inline Pointer(T* const p)              noexcept { this->SetPointer(p); }

    __host__ __device__ inline void SetPointer(const Pointer<T,D>& o) noexcept { this->m_raw = o.m_raw; }

    template <typename U>
    __host__ __device__ inline Pointer<U,D> AsPointerTo() const noexcept {
        return Pointer<U,D>(reinterpret_cast<U*>(this->m_raw));
    }

    __host__ __device__ inline operator T*& () noexcept { return this->m_raw; }
}; // Pointer<T,D>

template <typename T>
using cpu_Ptr = Pointer<T,Device::cpu>;

template <typename T>
using GPU_Ptr = Pointer<T,Device::GPU>;

template <typename T,Device D>
__host__ inline Pointer<T,D> AllocateSize(const size_t size) noexcept {
    if constexpr (D == Device::cpu) {
        return cpu_Ptr<T>(reinterpret_cast<T*>(std::malloc(size)));
    } else {
        T* p;
        cudamalloc(reinterpret_cast<void**>(&p),size);
        return GPU_Ptr<T>(p);
    }
}

template <typename T,Device D>
__host__ inline void Free(const Pointer<T,D>& p) noexcept {
    if constexpr (D == Device::cpu) {
        std::free(p);
    } else {
        cudaFree(p.template AsPointerTo<void>());
    }
}

int main() { Free(AllocateSize<int,Device::GPU>(1024)); }
  • CUDA版本11.1
  • 基于Ubuntu的Linux发行版

解决方法

我们的编译器团队研究了这个问题。该警告是虚假警告。我们希望在将来的CUDA版本中解决该问题。我将无法回答有关何时可能出现的问题。代码已正确生成。

如果您想使警告静音,一种可能的方法是在相关函数的末尾添加一个附加的return语句。在这种情况下,这是无效的,因为它是无法访问的:

template <typename T,Device D>
__host__ inline Pointer<T,D> AllocateSize(const size_t size) noexcept {
    if constexpr (D == Device::CPU) {
        return CPU_Ptr<T>(reinterpret_cast<T*>(std::malloc(size)));
    } else {
        T* p;
        cudaMalloc(reinterpret_cast<void**>(&p),size);
        return GPU_Ptr<T>(p);
    }
    return Pointer<T,D>(NULL);
}
,

如果函数的返回类型为mouseout,则由于[另一个错误的]“冲突类型错误”,在函数末尾添加无用的return语句(@RobertCrovella的答案)不起作用。 / p>

对我有用的是将此选项传递给前端

clearInterval()

http://www.ssl.berkeley.edu/~jimm/grizzly_docs/SSL/opt/intel/cc/9.0/lib/locale/en_US/mcpcom.msg

(花了我一段时间才能找到正确的选择)。


更正,它不能消除警告,似乎与作为模板的功能有关,并且在实例化模板之前应用了杂注。

**更新:更具体的解决方法**

正如@RobertCrovella所评论的那样,全局抑制警告可以使它忽略警告有意义的合法情况。因此,最好使用本地化的替代方法:

mouseout

我在这里找到错误代码:http://www.ece.ualberta.ca/~cmpe490/documents/ghs/405/c_error_ref.pdf。但是遗憾的是,很难找到有关这些NVCC编译器选项的信息。