Как изменить CMAKE статической библиотеки cuda с отладки на релиз? - PullRequest
0 голосов
/ 05 января 2019

Я новичок в использовании CMAKE. Я хочу использовать ядра в cuda как статическую библиотеку и использовать "extern "C" void function();" для ее вызова. Наконец, я буду использовать cmake для компиляции всего проекта. Но скорость его работы в GPU меня не удовлетворила. Так что я использовал Nsight eclispe, чтобы запустить его отдельно в отладке и выпуске. Проанализировав их в NVVP. Я обнаружил, что режим cmake по умолчанию в статической библиотеке - это режим отладки.

Так как я могу изменить режим отладки для выпуска в статической библиотеке?

Сначала я создаю проект в Nsight Eclipse.

Ниже приведен пример структуры файла, который у меня есть.

Test_in_stack  
-release
-debug
-src  
--GPU.cu
--simpleCUFFT.cu
-lib
--GPU.cuh
--Kernels.h

Содержимое src / simpleCUFFT.cu:

// includes, system
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>

// includes, project
// #include <Kernels.h>
#include <GPU.cuh>
#include <cuda_runtime.h>
#include <cufft.h>
#include <cufftXt.h>
#include <helper_functions.h>
#include <helper_cuda.h>
#include <device_functions.h>
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/sort.h>
#include <thrust/generate.h>
#include <thrust/sequence.h>
#include <thrust/device_ptr.h>
#include <thrust/extrema.h>
#include <thrust/execution_policy.h>
#include <thrust/equal.h>
#include <thrust/for_each.h>


// Complex data type
typedef float2 Complex;

#define FFT_NUM 1024
#define RANGE_NUM 1024
#define SIGNAL_SIZE RANGE_NUM*FFT_NUM

extern "C" 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 < 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();
}

Содержимое src / GPU.cu:

#include <Kernels.h>
#include <GPU.cuh>
#include <cuda_runtime.h>
#include <cufft.h>
#include <cufftXt.h>
#include <helper_functions.h>
#include <helper_cuda.h>
#include <device_functions.h>
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/sort.h>
#include <thrust/generate.h>
#include <thrust/sequence.h>
#include <thrust/device_ptr.h>
#include <thrust/extrema.h>
#include <thrust/execution_policy.h>
#include <thrust/equal.h>
#include <thrust/for_each.h>

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 **)&d_signal, SIGNAL_SIZE*sizeof(Complex));
    cudaMalloc((void **)&d_count, SIGNAL_SIZE*sizeof(int));
    cudaMalloc((void **)&d_signal_float, SIGNAL_SIZE*sizeof(float));
    cufftHandle plan;
    checkCudaErrors(cufftPlan1d(&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<RANGE_NUM;i++)
    {
        checkCudaErrors(cufftExecC2C(plan, d_signal+i*RANGE_NUM, d_signal+i*RANGE_NUM, CUFFT_FORWARD));
    }
    MatAbsNaive_float<<<dimgrid,dimblock>>>(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();
}

Содержимое lib / Kernels.h:

/*
 * Kernels.h
 *
 *  Created on: Jan 10, 2019
 *      Author: root
 */
#include "iostream"
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include "stdio.h"
#include <stdlib.h>
#include <string.h>
#include "math.h"
#include <mat.h>
#include "cuComplex.h"
#include "cublas.h"
#include <cufft.h>
#include <cufftXt.h>
#include <time.h>
#include <cublas_v2.h>


__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 < M) && (y < 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);
    }
}

Содержимое lib / GPU.cuh:

#ifndef GPU_CUH
#define GPU_CUH

#include <stdio.h>
#include "cuComplex.h"
typedef float2 Complex;
extern "C"
void GPU_Pro(Complex *h_signal,int *h_count);
#endif   

Результат отладки и выпуска NVVP:
отлаживать выпуск

Затем я помещаю те же файлы в cmake.

Ниже приведен пример структуры файла, который у меня есть.

Test_in_stack
-CMakeLists(1).txt
-build
-src  
--CMakeLists(2).txt
--simpleCUFFT.cpp
-lib
--CMakeLists(3).txt
--GPU.cu
--GPU.cuh
--Kernels.h

(1) 、 (2) 、 (3) - метки, настоящие имена файлов - CMakeLists.txt. И содержимое simpleCUFFT.cu и simpleCUFFT.cpp совпадают.
Содержимое CMakeLists (1) .txt:

cmake_minimum_required (VERSION 2.6)

PROJECT(GPU_MODE C CXX)
#PROJECT(GPU_MODE)
ADD_SUBDIRECTORY(src bin)
ADD_SUBDIRECTORY(lib)

Содержимое CMakeLists (2) .txt:

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)

Содержимое CMakeLists (3) .txt:

#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("Include" FILES ${CURRENT_HEADERS})
SOURCE_GROUP("Source" 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})

Я использовал командную строку в / build следующим образом:

cmake -DCMAKE_BUILD_TYPE=Release ..
make

Но это не сработало. Кажется, он все еще работает в режиме отладки, как показывает результат NVVP: cmake result
Итак, как я могу изменить флаг компиляции для выпуска в статической библиотеке CUDA. Я использую Red Hat Enterprise Linux Server 7.1 (Maipo) 、 cuda 8.0 、 cmake версия 2.8.12.2 、 GNU Make 3.82.

Обновление в 2019.01.12

Я добавил MESSAGE(STATUS "Build type:" ${CMAKE_BUILD_TYPE}") в CMakeLists (2) .txt. И результат:

[root@node2 build]# cmake -DCMAKE_BUILD_TYPE=Release ..
-- Build type: Release
-- Configuring done
-- Generating done

Но результат в NVVP не изменился.

1 Ответ

0 голосов
/ 13 января 2019

Ну, found Я нашел способ решить это.
Я изменяю строку 10 и строку 11 в CMakeLists (3) .txt на

SET(CUDA_NVCC_FLAGS -gencode arch=compute_52,code=sm_52;-lcufft;-lcudart;-lcublas)
SET(CMAKE_CUDA_FLAGS ${CUDA_NVCC_FLAGS} -O3 -DNDEBUG)

После выполнения

cmake -DCMAKE_BUILD_TYPE=Release ..
make clean
make

Результат в NVVP показывает, что он скомпилирован с режимом Release.

...