如何正确包含来自 NVIDIA C++ 标准库的文件?

Posted

技术标签:

【中文标题】如何正确包含来自 NVIDIA C++ 标准库的文件?【英文标题】:How do I properly include files from the NVIDIA C++ standard library? 【发布时间】:2021-09-05 13:30:52 【问题描述】:

我试图通过使用 NVIDIA 的 C++ 标准库的 version 在 CUDA 中使用共享指针。所以试图包括<cuda/std/detail/libcxx/include/memory>。我有一些错误。其中之一包括cannot open source file<__config><__functional_base>。这些文件显然在目录中。就像视觉工作室的行为就像那些文件不存在一样,即使它们存在。我得到的另一个错误是linkage specification is incompatible with previous ""<cmath>

我很少挖掘。我发现cannot open source filecuda/std/detail/libcxx/include/ 中以_ 开头的每个非头文件都很明显。就像 Visual Studio 以某种方式表现得好像那些文件不存在,尽管它们清楚地位于附加的包含目录中。此外,当我键入cuda/std/detail/libcxx/include/ 时,IntelliSense 将找不到这些文件。如果我能让 Visual Studio 识别这些文件,我就可以在 NVIDIA 版本的标准库中正确包含任何文件。

【问题讨论】:

Cuda 有自己的标准库版本。它被称为 libcu++。我什至指向了标准库中这些文件的目录,cuda/std/detail/libcxx/include/ 【参考方案1】:

首先要了解的是 CUDA 没有 C++ 标准库。您指的是 libcu++,它是对 C++ 标准库中定义的一小部分内容的非常 裸骨异构重新实现。您可以使用 libcu++ 中定义的任何内容(这并不多,这是一个非常不完整的实现),如下所示:

    将本地路径 cuda/std/ 添加到您使用的任何标准库头文件中,以便将本地主机 C++ 标准库的导入替换为 libcu++ 将命名空间从std 更改为cuda::std 使用nvcc编译

作为一个简单的example:

$ cat atomics.cpp

#include <iostream>         // std::cout
#include <cuda/std/atomic>  // cuda::std::atomic, cuda::std::atomic_flag, ATOMIC_FLAG_INIT
#include <thread>           // std::thread, std::this_thread::yield
#include <vector>           // std::vector

cuda::std::atomic<bool> ready (false);
cuda::std::atomic_flag winner = ATOMIC_FLAG_INIT;

void count1m (int id) 
  while (!ready)  std::this_thread::yield();       // wait for the ready signal
  for (volatile int i=0; i<1000000; ++i)           // go!, count to 1 million
  if (!winner.test_and_set())  std::cout << "thread #" << id << " won!\n"; 
;

int main ()

  std::vector<std::thread> threads;
  std::cout << "spawning 10 threads that count to 1 million...\n";
  for (int i=1; i<=10; ++i) threads.push_back(std::thread(count1m,i));
  ready = true;
  for (auto& th : threads) th.join();

  return 0;


$ nvcc -std=c++11 -o atomics atomics.cpp -lpthread
$ ./atomics
spawning 10 threads that count to 1 million...
thread #6 won!

请注意,根据documentation,目前(CUDA 11.2)只有以下实现:

&lt;atomic&gt; &lt;latch&gt; &lt;barrier&gt; &lt;semaphore&gt; &lt;chrono&gt; &lt;cfloat&gt; &lt;ratio&gt; &lt;climits&gt; &lt;cstdint&gt; &lt;type_traits&gt; &lt;tuple&gt; &lt;functional&gt; &lt;utility&gt; &lt;version&gt; &lt;cassert&gt; &lt;cstddef&gt;

从外观上看,下一个 CUDA 版本将提供复杂的支持。

您提到了共享指针。目前还没有&lt;memory&gt; 实现,所以不能让它工作。

【讨论】:

所以cuda/std/detail/libcxx/include目录中的文件不算作实现。 &lt;memory&gt; 在那个目录中。 您不能(或不应该)在 any libC++ 实现中直接导入 std/detail 中的任何内容。仅仅因为那里有文件,并不意味着它们可以直接使用或包含任何有意义的东西。它们是内部实现细节,故意隐藏在视图之外。***标头始终是 API 的入口点。 推力指针在形式和功能上与 C++ 标准库中&lt;memory&gt; 中声明的智能指针不同。没有引用计数/垃圾收集等。它们实际上只是在库本身内使基于标签的算法选择成为可能的一种设备

以上是关于如何正确包含来自 NVIDIA C++ 标准库的文件?的主要内容,如果未能解决你的问题,请参考以下文章

如何获得涉及 C++ 标准库的帧指针性能调用堆栈/火焰图?

标准 C++ 库的跨平台程度如何?

C++标准库和标准模板库

如何以clang格式创建外部标题的类别?

C++ STL应用与实现72: 标准库里的堆--如何使用标准库的heap算法

Windows 和 Linux 上动态库的 C++ 标准 [关闭]