From 8df5e42a5bba9f007e49d1a2540057967859f696 Mon Sep 17 00:00:00 2001 From: gfuse Date: Mon, 23 Aug 2021 15:30:49 +0200 Subject: [PATCH] add banchmark image alignment --- CMakeLists.txt | 13 ++++++--- include/cl_class.h | 68 +++++++++++++++++++++++++++------------------- main.cpp | 2 +- readme.md | 23 ++++++++++------ src/cl_class.cpp | 43 +++++++++++++++++------------ 5 files changed, 90 insertions(+), 59 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 40453a7..e102c1b 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,14 +1,19 @@ cmake_minimum_required(VERSION 3.7) project(Vio_OpenCL) - +SET(CMAKE_BUILD_TYPE Release) # Release, RelWithDebInfo +SET(CMAKE_VERBOSE_MAKEFILE OFF) +SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/CMakeModules/") set(CMAKE_CXX_STANDARD 14) find_package (OpenCL REQUIRED) find_package(OpenCV REQUIRED) +FIND_PACKAGE(Eigen REQUIRED) +FIND_PACKAGE(Sophus REQUIRED) -include_directories (include ${OpenCL_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} kernel) +include_directories (include ${OpenCL_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} kernel ${Eigen_INCLUDE_DIRS} ${Sophus_INCLUDE_DIRS}) -add_executable(${PROJECT_NAME} main.cpp include/cl_class.h src/cl_class.cpp) +add_executable(${PROJECT_NAME} main2.cpp include/cl_class.h src/cl_class.cpp src/sparse_img_align_gpu.cpp src/math_utils.cpp src/robust_cost.cpp) target_compile_features(${PROJECT_NAME} PRIVATE cxx_range_for) -target_link_libraries(${PROJECT_NAME} ${OpenCL_LIBRARIES} ${OpenCV_LIBS}) +target_link_libraries(${PROJECT_NAME} ${OpenCL_LIBRARIES} ${OpenCV_LIBS} ${Sophus_LIBRARIES}) ADD_DEFINITIONS(-DTEST_DATA_DIR=\"${PROJECT_SOURCE_DIR}/test/data\") +ADD_DEFINITIONS(-DKERNEL_DIR=\"${PROJECT_SOURCE_DIR}/kernel\") diff --git a/include/cl_class.h b/include/cl_class.h index 7b1efa7..224c8ce 100644 --- a/include/cl_class.h +++ b/include/cl_class.h @@ -4,40 +4,39 @@ #ifndef VIO_OPENCL_CL_CLASS_H #define VIO_OPENCL_CL_CLASS_H -#include "cl.hpp" +#include #include #include #include #include #include +#include #include class kernel{ public: kernel(cl::Program* program,std::string name){_kernel = new cl::Kernel(*program,name.c_str());}; ~kernel(){ + for(auto&& i:_images)i.first.setDestructorCallback((void (*)(_cl_mem *, void *))notify, NULL); + for(auto&& i:_buffers)i.first.first.setDestructorCallback((void (*)(_cl_mem *, void *))notify, NULL); _buffers.clear(); _images.clear(); }; template int32_t write(size_t id/*buffer ID*/,T* buf,cl::CommandQueue* queue,cl::Context* context,size_t buf_size){ - _buffers.push_back(std::pair,size_t>(std::pair(cl::Buffer(*context, CL_MEM_READ_WRITE, sizeof(T) * buf_size), + _buffers.push_back(std::pair,size_t>(std::pair(cl::Buffer(*context, CL_MEM_READ_WRITE | CL_MEM_USE_HOST_PTR + , sizeof(T) * buf_size,buf), buf_size),id)); - cl_int err=queue->enqueueWriteBuffer(_buffers.back().first.first,CL_TRUE, 0, sizeof(T) * buf_size, buf); + cl_int err=_kernel->setArg(id,_buffers.back().first.first); if(err!=0){ - std::cerr<<"Error C:Kernel, F:write, L:enqueueWriteBuffer\n"<setArg(id,_buffers.back().first.first); - if(err!=0){ - std::cerr<<"Error C:Kernel, F:write, L3:setArg\n"<(cl::Image2D(*context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, + _images.push_back(std::pair(cl::Image2D(*context, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, cl::ImageFormat(CL_R, CL_UNSIGNED_INT8), buf.size().width, buf.size().height, @@ -46,7 +45,7 @@ public: cl_int err=_kernel->setArg(id,_images.back().first); if(err!=0){ - std::cerr<<"Error C:Kernel, F:write image, L:setArg\n"< int32_t reload(size_t id,T* buf,cl::CommandQueue* queue){ - try{ - if(id>_buffers.size())return CL_MAP_FAILURE; - for(auto i:_buffers)if(i.second==id) - queue->enqueueWriteBuffer(i.first.first,CL_TRUE, 0, sizeof(T) * i.first.second, buf); - return CL_SUCCESS; - }catch (std::exception& err){ - std::cerr<<"Reload buffer on GPU failed\n"<enqueueMapBuffer(i.first.first,CL_TRUE,CL_MAP_WRITE,0,sizeof(T) * i.first.second); + memcpy(Map_buf,buf,sizeof(T) * i.first.second); + if(queue->enqueueUnmapMemObject(i.first.first,Map_buf)!=CL_SUCCESS)std::cerr<<"Reload buffer on GPU failed"<<'\n'; } + return CL_SUCCESS; }; int32_t reload(size_t id,cv::Mat& buf,cl::Context* context){ try{ - for(auto i:_images)if(i.second==id) - i.first=cl::Image2D(*context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, + for(auto&& i:_images)if(i.second==id){ + i.first.setDestructorCallback((void (*)(_cl_mem *, void *))notify, NULL); + i.first=cl::Image2D(*context, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, cl::ImageFormat(CL_R, CL_UNSIGNED_INT8), buf.size().width, buf.size().height, 0, reinterpret_cast(buf.data)); + cl_int err=_kernel->setArg(id,i.first); + if(err!=0){ + std::cerr<<"Error C:Kernel, F:write image, L:setArg ID:\t"<,size_t>> _buffers; std::vector> _images; @@ -126,7 +132,7 @@ public: _kernels.at(id1).write(id2,buf,context); return CL_SUCCESS; }catch (std::exception& err){ - std::cerr<<"Write buffer on GPU failed\n"<flush(); if(z>1 && y>1){ err=queue->enqueueNDRangeKernel(*_kernels.at(id1)._kernel, cl::NullRange/*offset*/, cl::NDRange(x,y,z)/*Global*/, cl::NullRange/*local*/); }else if(z<2 && y>1){ @@ -162,27 +169,32 @@ public: }else{ err=queue->enqueueNDRangeKernel(*_kernels.at(id1)._kernel, cl::NullRange/*offset*/, cl::NDRange(x)/*Global*/, cl::NullRange/*local*/); }; - queue->finish(); if(err!=0){ std::cerr<<"kernel: "<<_kernels.at(id1)._kernel->getInfo(); std::cerr<<" ,Args: "<<_kernels.at(id1)._kernel->getInfo()<<" ,Run out: "<getInfo();++i) std::cerr<<"argument type "<getArgInfo(i)<<'\n'; } - return err; + return queue->finish(); } template void read(size_t id1/*kernal ID*/,size_t id2/*buffer ID*/, T* out){ queue->enqueueReadBuffer(_kernels.at(id1).read(id2).first, CL_TRUE, 0, sizeof(T) * _kernels.at(id1).read(id2).second, out); } + template + void read(size_t id1/*kernal ID*/,size_t id2/*buffer ID*/,size_t size/*size*/, T* out){ + T* Map_buf=(T*)queue->enqueueMapBuffer(_kernels.at(id1).read(id2).first,CL_TRUE,CL_MAP_READ,0,sizeof(T) * size); + memcpy(out,Map_buf,sizeof(T) * size); + if(queue->enqueueUnmapMemObject(_kernels.at(id1).read(id2).first,Map_buf)!=CL_SUCCESS)std::cerr<<"Read buffer on GPU failed"<<'\n'; + } void clear_buf(); private: std::vector _kernels; - cl::Context* context = NULL; - cl::Device device; - cl::Program* program = NULL; - cl::CommandQueue* queue=NULL; + cl::Context* context = nullptr; + cl::Device* device = nullptr; + cl::Program* program = nullptr; + cl::CommandQueue* queue= nullptr; }; #endif //VIO_OPENCL_CL_CLASS_H diff --git a/main.cpp b/main.cpp index 3cf023a..728c479 100755 --- a/main.cpp +++ b/main.cpp @@ -72,7 +72,7 @@ int main() { gpu.run(0,752,480,1); time_accumulator += ((cv::getTickCount() - t) / cv::getTickFrequency()); } - printf("OpenCL took %f s (average over %d trials).\n", time_accumulator, 1000 ); + printf("OpenCL took %f ms (average over %d trials).\n", time_accumulator/((double)1000)*1000.0, 1000 ); int icorner_[1]={0}; gpu.read(0,2,icorner_); cl_int2 corners[740*450]; diff --git a/readme.md b/readme.md index 32c6171..5bbc4e2 100755 --- a/readme.md +++ b/readme.md @@ -1,11 +1,16 @@ -sudo apt-get install -y gpg-agent wget -wget -qO - https://repositories.intel.com/graphics/intel-graphics.key | - sudo apt-key add - -sudo apt-add-repository \ - 'deb [arch=amd64] https://repositories.intel.com/graphics/ubuntu bionic main' + sudo apt-get install -y gpg-agent wge + wget -qO - https://repositories.intel.com/graphics/intel-graphics.key | sudo apt-key add - + sudo apt-add-repository 'deb [arch=amd64] https://repositories.intel.com/graphics/ubuntu bionic main' -sudo apt-get update -sudo apt install ocl-icd-* opencl-headers intel-level-zero-gpu level-zero intel-opencl intel-igc-opencl-devel level-zero-devel -CodeBlocks build -cmake .. -G"CodeBlocks - Unix Makefiles" + for installing apt-add-repository : + sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys F42ED6FBAB17C654 + sudo apt-get update + sudo apt-get install software-properties-common + + + sudo apt-get update + sudo apt install ocl-icd-* opencl-headers intel-level-zero-gpu level-zero intel-opencl intel-igc-opencl-devel level-zero-devel + + CodeBlocks build + cmake .. -G"CodeBlocks - Unix Makefiles" diff --git a/src/cl_class.cpp b/src/cl_class.cpp index fdfbc74..ed11c7f 100644 --- a/src/cl_class.cpp +++ b/src/cl_class.cpp @@ -1,7 +1,7 @@ // // Created by root on 4/27/21. // -#include "cl_class.h" +#include opencl::opencl() { std::vector all_platforms; cl::Platform::get(&all_platforms); @@ -12,7 +12,7 @@ opencl::opencl() { //get default device of the default platform std::vector all_devices; for(auto i:all_platforms){ - std::cout << "Find platform: " << i.getInfo() << "\n"; + std::cout << "Find platform number:"<< i.getInfo() << "\n"; i.getDevices(CL_DEVICE_TYPE_GPU, &all_devices); } @@ -20,29 +20,38 @@ opencl::opencl() { std::cout << " No devices found. Check OpenCL installation!\n"; exit(1); } - device = all_devices[0]; - std::cout << "CL_DEVICE_NAME: " << device.getInfo() <<'\n' - << "CL_DEVICE_OPENCL_C_VERSION: " <()<<'\n' - << "CL_DEVICE_BUILT_IN_KERNELS: " <()<<'\n' - << "CL_DEVICE_COMPILER_AVAILABLE: " <()<<'\n' - << "CL_DEVICE_LOCAL_MEM_SIZE: " <()<<'\n' - << "CL_DEVICE_GLOBAL_MEM_SIZE: " <()<<'\n'; - - context=new cl::Context({ device }); + device = new cl::Device(all_devices[0]); + std::cout << "CL_DEVICE_NAME: " << device->getInfo() <<'\n' + << "CL_DEVICE_OPENCL_C_VERSION: " <getInfo()<<'\n' + << "CL_DEVICE_BUILT_IN_KERNELS: " <getInfo()<<'\n' + << "CL_DEVICE_COMPILER_AVAILABLE: " <getInfo()<<'\n' + << "CL_DEVICE_LOCAL_MEM_SIZE: " <getInfo()<<'\n' + << "CL_DEVICE_GLOBAL_MEM_SIZE: " <getInfo()<<'\n'; + context=new cl::Context({ *device }); cl::Program::Sources sources; - read_cl fast("../kernel/fast-gray.cl"); + read_cl fast(std::string(KERNEL_DIR)+"/fast-gray.cl"); sources.push_back({ fast.src_str, fast.size }); + read_cl compute_residual(std::string(KERNEL_DIR)+"/compute-residual.cl"); + sources.push_back({ compute_residual.src_str, compute_residual.size }); program=new cl::Program(*context, sources); - if(program->build({ device },"-DFAST_THRESH=40") !=0) - std::cout << " Error building: " << program->getBuildInfo(device)<<'\n' - <getBuildInfo(device) << '\n'; - queue=new cl::CommandQueue(*context,device,0,NULL); + //296.724480,395.357280,317.877600,238.752640,1.016870 + std::string options="-DFAST_THRESH=40 -DPATCH_SIZE=2 -DPATCH_HALFSIZE=1 -DF_X="+ std::to_string((float)296.724480) + + " -DF_Y="+std::to_string((float)395.357280)+ + " -DC_X="+std::to_string((float)317.877600)+ + " -DC_Y="+std::to_string((float)238.752640)+ + " -DS="+std::to_string((float)1.016870); + if(program->build({ *device },options.c_str()) !=0) + std::cout << " Error building: " << program->getBuildInfo(*device)<<'\n' + <getBuildInfo(*device) << '\n'; + queue=new cl::CommandQueue(*context,*device,CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE,NULL); } opencl::~opencl() { + delete context; + delete device; } void opencl::clear_buf() { queue->finish(); - queue->flush(); _kernels.clear(); + delete program; }