title: How to change the CMAKE of cuda static library from debug to release?
body: <p>I'm a new to use CMAKE. I want to use the kernels in cuda as a static library and use &quot; <code>extern &quot;C&quot; void function();</code>&quot; to call it. Finally I will use cmake to compile the whole project. But its running speed in GPU didn't satisfied me. So I used Nsight eclispe to run it severally in debug and release. After analyzing them in NVVP.I found the default mode of cmake in static library is debug mode.</p>
  <p>So how can I change the debug mode to release in static library?</p>
  <h3>Firstly, I create a project in Nsight eclipse.</h3>
  <p>Below is the example of the file structure that I have.</p>
  <pre><code>Test_in_stack  
  -release
  -debug
  -src  
  --GPU.cu
  --simpleCUFFT.cu
  -lib
  --GPU.cuh
  --Kernels.h
  </code></pre>
  <p>The content of src/simpleCUFFT.cu is:</p>
  <pre><code>// includes, system
  #include &lt;stdlib.h&gt;
  #include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;math.h&gt;
  
  // includes, project
  // #include &lt;Kernels.h&gt;
  #include &lt;GPU.cuh&gt;
  #include &lt;cuda_runtime.h&gt;
  #include &lt;cufft.h&gt;
  #include &lt;cufftXt.h&gt;
  #include &lt;helper_functions.h&gt;
  #include &lt;helper_cuda.h&gt;
  #include &lt;device_functions.h&gt;
  #include &lt;thrust/device_vector.h&gt;
  #include &lt;thrust/host_vector.h&gt;
  #include &lt;thrust/sort.h&gt;
  #include &lt;thrust/generate.h&gt;
  #include &lt;thrust/sequence.h&gt;
  #include &lt;thrust/device_ptr.h&gt;
  #include &lt;thrust/extrema.h&gt;
  #include &lt;thrust/execution_policy.h&gt;
  #include &lt;thrust/equal.h&gt;
  #include &lt;thrust/for_each.h&gt;
  
  
  // Complex data type
  typedef float2 Complex;
  
  #define FFT_NUM 1024
  #define RANGE_NUM 1024
  #define SIGNAL_SIZE RANGE_NUM*FFT_NUM
  
  extern &quot;C&quot; void GPU_Pro(Complex *h_signal,int *h_count);
  ////////////////////////////////////////////////////////////////////////////////
  // Program main
  ////////////////////////////////////////////////////////////////////////////////
  int main()
  {
      Complex *h_signal = (Complex *)malloc(sizeof(Complex) * SIGNAL_SIZE);
      int *h_count = (int *)malloc(sizeof(int) * SIGNAL_SIZE);
      // Initialize the memory for the signal
      for (unsigned int i = 0; i &lt; SIGNAL_SIZE; ++i)
      {
          h_signal[i].x = rand() / (float)RAND_MAX;
          h_signal[i].y = rand() / (float)RAND_MAX;
          h_count[i]=i/FFT_NUM;
      }
      GPU_Pro(h_signal,h_count);
  
      cudaDeviceReset();
  }
  </code></pre>
  <p>The content of src/GPU.cu is:</p>
  <pre><code>#include &lt;Kernels.h&gt;
  #include &lt;GPU.cuh&gt;
  #include &lt;cuda_runtime.h&gt;
  #include &lt;cufft.h&gt;
  #include &lt;cufftXt.h&gt;
  #include &lt;helper_functions.h&gt;
  #include &lt;helper_cuda.h&gt;
  #include &lt;device_functions.h&gt;
  #include &lt;thrust/device_vector.h&gt;
  #include &lt;thrust/host_vector.h&gt;
  #include &lt;thrust/sort.h&gt;
  #include &lt;thrust/generate.h&gt;
  #include &lt;thrust/sequence.h&gt;
  #include &lt;thrust/device_ptr.h&gt;
  #include &lt;thrust/extrema.h&gt;
  #include &lt;thrust/execution_policy.h&gt;
  #include &lt;thrust/equal.h&gt;
  #include &lt;thrust/for_each.h&gt;
  
  typedef float2 Complex;
  #define FFT_NUM 1024
  #define RANGE_NUM 1024
  #define SIGNAL_SIZE RANGE_NUM*FFT_NUM
  
  void GPU_Pro(Complex *h_signal,int *h_count)
  {
      Complex *d_signal;
      float *d_signal_float;
      int *d_count;
      cudaMalloc((void **)&amp;d_signal, SIGNAL_SIZE*sizeof(Complex));
      cudaMalloc((void **)&amp;d_count, SIGNAL_SIZE*sizeof(int));
      cudaMalloc((void **)&amp;d_signal_float, SIGNAL_SIZE*sizeof(float));
      cufftHandle plan;
      checkCudaErrors(cufftPlan1d(&amp;plan, FFT_NUM, CUFFT_C2C, 1));
      dim3 dimblock(32, 32);
      dim3 dimgrid(FFT_NUM / 32, RANGE_NUM / 32);
  
      // Copy host memory to device
      checkCudaErrors(cudaMemcpy(d_signal, h_signal, SIGNAL_SIZE*sizeof(Complex),
                                     cudaMemcpyHostToDevice));
      checkCudaErrors(cudaMemcpy(d_count, h_count, SIGNAL_SIZE*sizeof(int),
                                         cudaMemcpyHostToDevice));
      for(int i=0;i&lt;RANGE_NUM;i++)
      {
          checkCudaErrors(cufftExecC2C(plan, d_signal+i*RANGE_NUM, d_signal+i*RANGE_NUM, CUFFT_FORWARD));
      }
      MatAbsNaive_float&lt;&lt;&lt;dimgrid,dimblock&gt;&gt;&gt;(d_signal,d_signal_float,FFT_NUM,RANGE_NUM);
      thrust::stable_sort_by_key(thrust::device_pointer_cast(d_signal_float),thrust::device_pointer_cast(d_signal_float)+SIGNAL_SIZE,thrust::device_pointer_cast(d_count));
      thrust::stable_sort_by_key(thrust::device_pointer_cast(d_count),thrust::device_pointer_cast(d_count)+SIGNAL_SIZE,thrust::device_pointer_cast(d_signal_float));
  
      cudaDeviceReset();
  }
  </code></pre>
  <p>The content of lib/Kernels.h is:</p>
  <pre><code>/*
   * Kernels.h
   *
   *  Created on: Jan 10, 2019
   *      Author: root
   */
  #include &quot;iostream&quot;
  #include &quot;cuda_runtime.h&quot;
  #include &quot;device_launch_parameters.h&quot;
  #include &quot;stdio.h&quot;
  #include &lt;stdlib.h&gt;
  #include &lt;string.h&gt;
  #include &quot;math.h&quot;
  #include &lt;mat.h&gt;
  #include &quot;cuComplex.h&quot;
  #include &quot;cublas.h&quot;
  #include &lt;cufft.h&gt;
  #include &lt;cufftXt.h&gt;
  #include &lt;time.h&gt;
  #include &lt;cublas_v2.h&gt;
  
  
  __global__ void MatAbsNaive_float(cuComplex *idata, float *odata, int M, int N)
  {
      int x = blockIdx.x * blockDim.x + threadIdx.x;
      int y = blockIdx.y * blockDim.y + threadIdx.y;
      if ((x &lt; M) &amp;&amp; (y &lt; N))
      {
          odata[x + M*y] = sqrt(idata[x + M*y].x * idata[x + M*y].x + idata[x + M*y].y * idata[x + M*y].y);
      }
  }
  </code></pre>
  <p>The content of lib/GPU.cuh is:</p>
  <pre><code>#ifndef GPU_CUH
  #define GPU_CUH
  
  #include &lt;stdio.h&gt;
  #include &quot;cuComplex.h&quot;
  typedef float2 Complex;
  extern &quot;C&quot;
  void GPU_Pro(Complex *h_signal,int *h_count);
  #endif   
  </code></pre>
  <p>The result of NVVP in debug and release are as follows:<br />
  <a href="https://i.stack.imgur.com/gNxpJ.png" rel="nofollow noreferrer">debug</a>
  <a href="https://i.stack.imgur.com/5Jkmg.png" rel="nofollow noreferrer">release</a></p>
  <h3>Then I put the same files in cmake.</h3>
  <p>Below is the example of the file structure that I have.</p>
  <pre><code>Test_in_stack
  -CMakeLists(1).txt
  -build
  -src  
  --CMakeLists(2).txt
  --simpleCUFFT.cpp
  -lib
  --CMakeLists(3).txt
  --GPU.cu
  --GPU.cuh
  --Kernels.h
  </code></pre>
  <p>The (1)、(2)、(3) are labels, the real file names are both CMakeLists.txt. And the content of simpleCUFFT.cu and simpleCUFFT.cpp are the same.<br />
  The content of CMakeLists(1).txt is:</p>
  <pre><code>cmake_minimum_required (VERSION 2.6)
  
  PROJECT(GPU_MODE C CXX)
  #PROJECT(GPU_MODE)
  ADD_SUBDIRECTORY(src bin)
  ADD_SUBDIRECTORY(lib)
  </code></pre>
  <p>The content of CMakeLists(2).txt is:</p>
  <pre><code>INCLUDE_DIRECTORIES(
  ${eclipse_home}VSPS/include 
  /usr/include 
  ${eclipse_home}PetDCPS/include 
  /user/include/c++ 
  /usr/local/cuda-8.0/include 
                     )
  
  INCLUDE_DIRECTORIES(/root/Chenjie/cuda-workspace/Test_in_stack/lib 
  /usr/local/cuda-8.0/samples/common/inc  
  /usr/local/cuda-8.0/include)
  LINK_DIRECTORIES(/usr/local/cuda-8.0/lib64/)
  
  SET(CPU_LIST simpleCUFFT.cpp)
  FIND_PACKAGE(CUDA REQUIRED)
  SET(EXTRA_LIBS ${EXTRA_LIBS} gpu ${CUDA_LIBRARIES})
  ADD_EXECUTABLE(CPUProcessTest ${CPU_LIST})
  SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/src)
  TARGET_LINK_LIBRARIES(CPUProcessTest optimized ${EXTRA_LIBS} vsip_c)
  </code></pre>
  <p>The content of CMakeLists(3).txt is:</p>
  <pre><code>#for cuda
  
  PROJECT(gpu)
  CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
  INCLUDE_DIRECTORIES(/root/Chenjie/cuda-workspace/Test_in_stack/lib 
  /usr/local/cuda-8.0/samples/common/inc  
  /usr/local/cuda-8.0/include)
  FIND_PACKAGE(CUDA QUIET REQUIRED)
  #SET(CUDA_NVCC_FLAGS -03;-G;-g)
  SET(CUDA_NVCC_FLAGS -gencode arch=compute_52,code=sm_52;-G;-g;-lcufft;-lcudart;-lcublas)
  SET(CMAKE_CUDA_FLAGS ${CUDA_NVCC_FLAGS_RELEASE})
  FILE(GLOB_RECURSE CURRENT_HEADERS *.h *.hpp *.cuh)
  FILE(GLOB CURRENT_SOURCES *.cpp *.cu)
  
  SOURCE_GROUP(&quot;Include&quot; FILES ${CURRENT_HEADERS})
  SOURCE_GROUP(&quot;Source&quot; FILES ${CURRENT_SOURCES})
  
  INCLUDE_DIRECTORIES(/usr/local/cuda-8.0/include)
  LINK_DIRECTORIES(/usr/local/cuda-8.0/lib64/)
  LINK_LIBRARIES(cufft cublas)
  
  #TARGET_LINK_LIBRARIES(gpu ${CUDA_LIBRARIES})
  #CUDA_ADD_LIBRARY(gpu SHARED ${CURRENT_HEADERS} ${CURRENT_SOURCES})
  CUDA_ADD_LIBRARY(gpu STATIC ${CURRENT_HEADERS} ${CURRENT_SOURCES} ${CUDA_LIBRARIES} ${CUDA_CUFFT_LIBRARIES})
  </code></pre>
  <p>I used the command line in /built as follows:</p>
  <pre><code>cmake -DCMAKE_BUILD_TYPE=Release ..
  make
  </code></pre>
  <p>But it didn't work. It seems it still run in debug as the NVVP result shows:
  <a href="https://i.stack.imgur.com/t87O0.png" rel="nofollow noreferrer">cmake result</a><br />
  So how can I change to compile flag to release in static library of cuda.<br />
  I'm using Red Hat Enterprise Linux Server 7.1(Maipo)、cuda 8.0 、cmake version 2.8.12.2、GNU Make 3.82.</p>
  <h3>Update in 2019.01.12</h3>
  <p>I added <code>MESSAGE(STATUS &quot;Build type:&quot; ${CMAKE_BUILD_TYPE}&quot;)</code> in CMakeLists(2).txt. And the result is:</p>
  <pre><code>[root@node2 build]# cmake -DCMAKE_BUILD_TYPE=Release ..
  -- Build type: Release
  -- Configuring done
  -- Generating done
  </code></pre>
  <p>But the result in NVVP didn't change.</p>