<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.2">Jekyll</generator><link href="https://rapsealk.github.io/feed.xml" rel="self" type="application/atom+xml" /><link href="https://rapsealk.github.io/" rel="alternate" type="text/html" /><updated>2022-08-12T00:57:23+09:00</updated><id>https://rapsealk.github.io/feed.xml</id><title type="html">꼭대기에 대한 상상</title><subtitle>rapsealk's GitHub Blog
</subtitle><author><name>rapsealk</name><email>piono623@naver.com</email></author><entry><title type="html">Go언어와 CUDA Runtime API(cudart)</title><link href="https://rapsealk.github.io/2022/04/24/go-cuda.html" rel="alternate" type="text/html" title="Go언어와 CUDA Runtime API(cudart)" /><published>2022-04-24T00:00:00+09:00</published><updated>2022-04-24T00:00:00+09:00</updated><id>https://rapsealk.github.io/2022/04/24/go-cuda</id><content type="html" xml:base="https://rapsealk.github.io/2022/04/24/go-cuda.html">&lt;p&gt;기존에 Python으로 작성했던 프로젝트를 Go로 다시 작성하는 과정에서 CUDA와 관련하여 문제가 발생했다. Python의 경우 &lt;a href=&quot;https://developer.nvidia.com/cuda-python&quot;&gt;cuda-python&lt;/a&gt;이라는 &lt;a href=&quot;https://pypi.org/project/cuda-python/&quot;&gt;패키지&lt;/a&gt;가 공식적으로 지원되는 데 반해, 아직 Go에는 그런 것이 존재하지 않았다. Go에서 CUDA의 기능을 이용하기 위한 방법들을 찾아보다가, &lt;a href=&quot;https://go.dev/blog/cgo&quot;&gt;&lt;strong&gt;cgo&lt;/strong&gt;&lt;/a&gt;라는 것을 이용하여 C 코드를 실행할 수 있다는 것을 알 수 있었다. &lt;a href=&quot;https://go.dev/blog/cgo&quot;&gt;cgo&lt;/a&gt;에 대한 자세한 내용은 아래의 글을 참고하시기 바란다.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://go.dev/blog/cgo&quot;&gt;C? Go? Cgo! - The Go Programming Language&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;cgo를 사용하기 위해서는 import “C” 구문 바로 이전에 주석의 형태로 C 코드를 작성하면 되는데, 이것을 preamble이라고 부른다. 이렇게 작성된 코드는 Go 런타임에서 C 패키지를 통해 접근이 가능해진다. 또한 #cgo 지시자를 통해 컴파일러에 옵션을 전달할 수 있다. 이 글에서는 gcc를 사용하였으며, CUDA Runtime API를 사용하기 위하여 아래와 같은 형태로 작성하였다.&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;// #cgo CFLAGS: -I/usr/local/cuda/include&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// #cgo LDFLAGS: -L/usr/local/cuda/lib64 -lcudart&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;// #include &amp;lt;cuda_runtime_api.h&amp;gt;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;C&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이제 Go에서 CUDA Runtime API를 사용할 수 있게 되었다. 코드를 작성하기에 앞서, 아래의 문서를 통해 CUDA Runtime API의 명세를 확인할 수 있다.(본 글에서는 cudaGetDeviceCount, cudaGetDeviceProperties 등 Device Management 관련 API만을 사용한다.)&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://docs.nvidia.com/cuda/cuda-runtime-api/group__CUDART__DEVICE.html&quot;&gt;CUDA Runtime API :: CUDA Toolkit Documentation (nvidia.com)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;이제 본격적으로 Go 코드를 작성해 보도록 하겠다.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;cudaGetDeviceCount
cudaGetDeviceCount는 사용 가능한 CUDA Device의 갯수를 읽어오는 함수로, 그 명세는 아래와 같다.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;__host____device__cudaError_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cudaGetDeviceCount&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;count&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;함수에 전달한 int형 주소값인 count를 역참조하여 CUDA Device의 갯수 정보를 입력하고, 함수의 반환값으로는 에러의 유무를 전달하여 정상적으로 처리되었는지를 알 수 있게 한다. 이 API를 Go로 사용하기 위하여 아래와 같이 작성할 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;errors&quot;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ErrCUDAInvalidValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;New&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;This indicates that one or more..&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetDeviceCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;deviceCount&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cudaGetDeviceCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deviceCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ErrCUDAInvalidValue&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;deviceCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이때 C 함수에는 *C.int 자료형을 전달하고, Go 함수에서 반환할 때는 int32 자료형으로 변환했음에 유의하자.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;cudaGetDeviceProperties
cudaGetDeviceProperties는 n번째 CUDA Device의 정보를 읽어오는 함수로, 그 명세는 아래와 같다.&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;__host__cudaError_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cudaGetDeviceProperties&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cudaDeviceProp&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;device&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;마찬가지로 함수에 전달한 cudaDeviceProp형 주소값인 prop을 역참조하여 device 번째에 해당하는 CUDA Device의 정보를 입력하고, 함수의 반환값으로는 에러의 유무를 전달한다. 이 API를 Go로 사용하기 위하여 아래와 같이 작성할 수 있다.&lt;/p&gt;

&lt;div class=&quot;language-go highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;encoding/hex&quot;&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;fmt&quot;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;func&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;GetDeviceProperties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;device&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;struct_cudaDeviceProp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prop&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;struct_cudaDeviceProp&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cudaGetDeviceProperties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;device&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ErrCUDAInvalidValue&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;c_uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GoString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bytes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;uuid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;make&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([]&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;EncodedLen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;len&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c_uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;hex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;c_uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Name:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;C&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;GoString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;UUID:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;uuid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;fmt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Println&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Total Global Memory:&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;totalGlobalMem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;이때 C에서 정의된 struct cudaDeviceProp {…}과 같은 구조체는 C.struct_cudaDeviceProp과 같은 형태로 접근할 수 있다. 또한 C.GoString은 *_Ctype_char을 인자로 받기 때문에, []_Ctype_char 자료형인 prop.name을 &amp;amp;prop.name[0]의 형태로 참조하였다.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;language-txt&quot;&gt;Hello, MLRD!
GPU Device count: 1
Name: NVIDIA GeForce GTX 1660 Ti
UUID: cfd68e3d1d6d95b3e8240890188f0536
Total Global Memory: 6441992192
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;하루종일 삽질한 결과 방법을 찾아낼 수 있었다.&lt;/p&gt;

&lt;p&gt;참고: &lt;a href=&quot;https://github.com/rapsealk/go-cuda&quot;&gt;https://github.com/rapsealk/go-cuda&lt;/a&gt;&lt;/p&gt;</content><author><name>rapsealk</name><email>piono623@naver.com</email></author><category term="go,cuda" /><summary type="html">기존에 Python으로 작성했던 프로젝트를 Go로 다시 작성하는 과정에서 CUDA와 관련하여 문제가 발생했다. Python의 경우 cuda-python이라는 패키지가 공식적으로 지원되는 데 반해, 아직 Go에는 그런 것이 존재하지 않았다. Go에서 CUDA의 기능을 이용하기 위한 방법들을 찾아보다가, cgo라는 것을 이용하여 C 코드를 실행할 수 있다는 것을 알 수 있었다. cgo에 대한 자세한 내용은 아래의 글을 참고하시기 바란다. C? Go? Cgo! - The Go Programming Language cgo를 사용하기 위해서는 import “C” 구문 바로 이전에 주석의 형태로 C 코드를 작성하면 되는데, 이것을 preamble이라고 부른다. 이렇게 작성된 코드는 Go 런타임에서 C 패키지를 통해 접근이 가능해진다. 또한 #cgo 지시자를 통해 컴파일러에 옵션을 전달할 수 있다. 이 글에서는 gcc를 사용하였으며, CUDA Runtime API를 사용하기 위하여 아래와 같은 형태로 작성하였다. // #cgo CFLAGS: -I/usr/local/cuda/include // #cgo LDFLAGS: -L/usr/local/cuda/lib64 -lcudart // #include &amp;lt;cuda_runtime_api.h&amp;gt; import &quot;C&quot; 이제 Go에서 CUDA Runtime API를 사용할 수 있게 되었다. 코드를 작성하기에 앞서, 아래의 문서를 통해 CUDA Runtime API의 명세를 확인할 수 있다.(본 글에서는 cudaGetDeviceCount, cudaGetDeviceProperties 등 Device Management 관련 API만을 사용한다.) CUDA Runtime API :: CUDA Toolkit Documentation (nvidia.com) 이제 본격적으로 Go 코드를 작성해 보도록 하겠다. cudaGetDeviceCount cudaGetDeviceCount는 사용 가능한 CUDA Device의 갯수를 읽어오는 함수로, 그 명세는 아래와 같다. __host____device__cudaError_t cudaGetDeviceCount ( int* count ) 함수에 전달한 int형 주소값인 count를 역참조하여 CUDA Device의 갯수 정보를 입력하고, 함수의 반환값으로는 에러의 유무를 전달하여 정상적으로 처리되었는지를 알 수 있게 한다. 이 API를 Go로 사용하기 위하여 아래와 같이 작성할 수 있다. import &quot;errors&quot; var ErrCUDAInvalidValue = errors.New(&quot;This indicates that one or more..&quot;) func GetDeviceCount() (int32, error) { var deviceCount C.int if C.cudaGetDeviceCount(&amp;amp;deviceCount) != 0 { return 0, ErrCUDAInvalidValue } return int32(deviceCount), nil } 이때 C 함수에는 *C.int 자료형을 전달하고, Go 함수에서 반환할 때는 int32 자료형으로 변환했음에 유의하자. cudaGetDeviceProperties cudaGetDeviceProperties는 n번째 CUDA Device의 정보를 읽어오는 함수로, 그 명세는 아래와 같다. __host__cudaError_t cudaGetDeviceProperties ( cudaDeviceProp* prop, int device ) 마찬가지로 함수에 전달한 cudaDeviceProp형 주소값인 prop을 역참조하여 device 번째에 해당하는 CUDA Device의 정보를 입력하고, 함수의 반환값으로는 에러의 유무를 전달한다. 이 API를 Go로 사용하기 위하여 아래와 같이 작성할 수 있다. import ( &quot;encoding/hex&quot; &quot;fmt&quot; ) func GetDeviceProperties(device int32) (C.struct_cudaDeviceProp, error) { var prop C.struct_cudaDeviceProp if C.cudaGetDeviceProperties(&amp;amp;prop, C.int(device)) != 0 { return prop, ErrCUDAInvalidValue } c_uuid := []byte(C.GoString(&amp;amp;prop.uuid.bytes[0])) uuid := make([]byte, hex.EncodedLen(len(c_uuid))) hex.Encode(uuid, c_uuid) fmt.Println(&quot;Name:&quot;, C.GoString(&amp;amp;prop.name[0])) fmt.Println(&quot;UUID:&quot;, string(uuid)) fmt.Println(&quot;Total Global Memory:&quot;, prop.totalGlobalMem) return prop, nil } 이때 C에서 정의된 struct cudaDeviceProp {…}과 같은 구조체는 C.struct_cudaDeviceProp과 같은 형태로 접근할 수 있다. 또한 C.GoString은 *_Ctype_char을 인자로 받기 때문에, []_Ctype_char 자료형인 prop.name을 &amp;amp;prop.name[0]의 형태로 참조하였다. Hello, MLRD! GPU Device count: 1 Name: NVIDIA GeForce GTX 1660 Ti UUID: cfd68e3d1d6d95b3e8240890188f0536 Total Global Memory: 6441992192 하루종일 삽질한 결과 방법을 찾아낼 수 있었다. 참고: https://github.com/rapsealk/go-cuda</summary></entry><entry><title type="html">Welcome</title><link href="https://rapsealk.github.io/2018/07/01/welcome.html" rel="alternate" type="text/html" title="Welcome" /><published>2018-07-01T00:00:00+09:00</published><updated>2018-07-01T00:00:00+09:00</updated><id>https://rapsealk.github.io/2018/07/01/welcome</id><content type="html" xml:base="https://rapsealk.github.io/2018/07/01/welcome.html">&lt;p&gt;If you see this page, that means you have setup your site. enjoy! :ghost: :ghost: :ghost:&lt;/p&gt;

&lt;p&gt;You may want to &lt;a href=&quot;https://tianqi.name/jekyll-TeXt-theme/docs/en/configuration&quot;&gt;config the site&lt;/a&gt; or &lt;a href=&quot;https://tianqi.name/jekyll-TeXt-theme/docs/en/writing-posts&quot;&gt;writing a post&lt;/a&gt; next. Please feel free to &lt;a href=&quot;https://github.com/kitian616/jekyll-TeXt-theme/issues&quot;&gt;create an issue&lt;/a&gt; or &lt;a href=&quot;mailto:kitian616@outlook.com&quot;&gt;send me email&lt;/a&gt; if you have any questions.&lt;/p&gt;

&lt;!--more--&gt;

&lt;hr /&gt;

&lt;p&gt;If you like TeXt, don’t forget to give me a star. :star2:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/kitian616/jekyll-TeXt-theme/&quot;&gt;&lt;img src=&quot;https://img.shields.io/github/stars/kitian616/jekyll-TeXt-theme.svg?label=Stars&amp;amp;style=social&quot; alt=&quot;Star This Project&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content><author><name>rapsealk</name><email>piono623@naver.com</email></author><category term="TeXt" /><summary type="html">If you see this page, that means you have setup your site. enjoy! :ghost: :ghost: :ghost: You may want to config the site or writing a post next. Please feel free to create an issue or send me email if you have any questions.</summary></entry><entry><title type="html">Post with Header Image</title><link href="https://rapsealk.github.io/2018/06/01/header-image.html" rel="alternate" type="text/html" title="Post with Header Image" /><published>2018-06-01T00:00:00+09:00</published><updated>2018-06-01T00:00:00+09:00</updated><id>https://rapsealk.github.io/2018/06/01/header-image</id><content type="html" xml:base="https://rapsealk.github.io/2018/06/01/header-image.html">&lt;p&gt;A Post with Header Image, See &lt;a href=&quot;https://tianqi.name/jekyll-TeXt-theme/samples.html#page-layout&quot;&gt;Page layout&lt;/a&gt; for more examples.&lt;/p&gt;

&lt;!--more--&gt;</content><author><name>rapsealk</name><email>piono623@naver.com</email></author><category term="TeXt" /><summary type="html">A Post with Header Image, See Page layout for more examples.</summary></entry></feed>