Я новичок в использовании 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 не изменился.