Inherit QObject in a cuda class
-
I am c++ beginner working on an app development that acquires data in C++, processes it in GPU, and plots it in GUI using Qcustom plot library. I am using signals and slots to share data pointers between classes. But how to inherit Qobject in Cuda class?
I will give a sample code to represent my problem.
cmake_minimum_required(VERSION 3.5) project(Trial04 VERSION 0.1 LANGUAGES CXX CUDA) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CUDA_STANDARD 11) set(CMAKE_CUDA_STANDARD_REQUIRED ON) find_package(Qt6 REQUIRED COMPONENTS Widgets PrintSupport) qt_standard_project_setup() include_directories(${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES}) add_executable(t04a mainwindow.ui mainwindow.cpp mainwindow.h main.cpp CudaProcessing.cu CudaProcessing.h ) target_link_libraries(t04 PRIVATE Qt6::Widgets) set_target_properties(t04 PROPERTIES WIN32_EXECUTABLE ON MACOSX_BUNDLE ON ) set_target_properties(t04 PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
//mainwindow.cpp MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); CudaProcessing *c1 = new CudaProcessing(this); c1->hello_world(); }
//CudaProcessing.cu #include "CudaProcessing.h" #include <stdio.h> using namespace std; __global__ void hello(){ printf("hello from GPU"); } void CudaProcessing::hello_world(){ hello<<<1,1>>>(); }
//CudaProcessing.h #pragma once class CudaProcessing{ public: CudaProcessing() {} void hello_world(); ~CudaProcessing() {} };
The above code without QObject inheritance works fine.
#include <QObject> class CudaProcessing:public QObject { Q_OBJECT public: CudaProcessing(QObject *parent):QObject(parent){ } void hello_world(); ~CudaProcessing() {} };
When I inherit QObject in the above CUDA class I am getting an error
error "Qt requires a C++17 compiler, and a suitable value for __cplusplus. On MSVC, you must pass the /Zc:__cplusplus option to the compiler."
If I add the following
if (MSVC) add_compile_options(/Zc:__cplusplus) endif()
to cmake file it shows a new error
error: Cannot specify link libraries for target "t04" which is not built by this project.
Is my approach of signal and slot in CUDA class right? If not, any suggestion would be greatly appreciated. Thanks
-
Hi,
As @Pl45m4 wrote, CUDA kernels are a different beast that you should keep separated from QObject.
You won't be able to use signals and slots from CUDA code anyway.
Make your QObject based classes use CUDA kernels and keep compilation units separate. -
@skishore1998 said in Inherit QObject in a cuda class:
I am using signals and slots to share data pointers between classes
I don't see any Qt signal-slot connection in your code?!
-
@skishore1998 said in Inherit QObject in a cuda class:
add_executable(t04a
in other places you use t04 - why? Fix you CMakeLists.txt file.
-
@Pl45m4
The purpose of inheriting Qobject is to use signals and slots. But I see the error immediately after inheriting Qobject. I have tried going ahead and implementing signals and slots in my main code but the error remains the same. -
@skishore1998 Please post the actual error
-
@jsulm Sorry, This is what I get at the compile output
18:32:43: Running steps for project Trial04... 18:32:43: Starting: "C:\Qt\Tools\CMake_64\bin\cmake.exe" --build D:/desktop_c/Kishore/qwt_testing/10_contour_ADQ_linked/build-Trial04-Desktop_Qt_6_6_1_MSVC2019_64bit-Debug --target all [1/3 20.0/sec] Building CUDA object CMakeFiles\t04.dir\CudaProcessing.cu.obj FAILED: CMakeFiles/t04.dir/CudaProcessing.cu.obj C:\PROGRA~1\NVIDIA~2\CUDA\v12.3\bin\nvcc.exe -forward-unknown-to-host-compiler -DQT_CORE_LIB -DQT_GUI_LIB -DQT_WIDGETS_LIB -DUNICODE -DWIN32 -DWIN64 -D_ENABLE_EXTENDED_ALIGNED_STORAGE -D_UNICODE -D_WIN64 -ID:\desktop_c\Kishore\qwt_testing\10_contour_ADQ_linked\build-Trial04-Desktop_Qt_6_6_1_MSVC2019_64bit-Debug\t04_autogen\include -I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.3\include" -isystem C:\Qt\6.6.1\msvc2019_64\include\QtWidgets -isystem C:\Qt\6.6.1\msvc2019_64\include -isystem C:\Qt\6.6.1\msvc2019_64\include\QtCore -isystem C:\Qt\6.6.1\msvc2019_64\mkspecs\win32-msvc -isystem C:\Qt\6.6.1\msvc2019_64\include\QtGui -D_WINDOWS -Xcompiler="/W3 /GR /EHsc" -Xcompiler="-MDd -Zi -Ob0 -Od /RTC1" /Zc:__cplusplus -MD -MT CMakeFiles\t04.dir\CudaProcessing.cu.obj -MF CMakeFiles\t04.dir\CudaProcessing.cu.obj.d -x cu -rdc=true -c D:\desktop_c\Kishore\qwt_testing\10_contour_ADQ_linked\Trial04\CudaProcessing.cu -o CMakeFiles\t04.dir\CudaProcessing.cu.obj -Xcompiler=-FdCMakeFiles\t04.dir\,-FS nvcc fatal : A single input file is required for a non-link phase when an outputfile is specified ninja: build stopped: subcommand failed. 18:32:44: The process "C:\Qt\Tools\CMake_64\bin\cmake.exe" exited with code 1. Error while building/deploying project Trial04 (kit: Desktop Qt 6.6.1 MSVC2019 64bit) When executing step "Build" 18:32:44: Elapsed time: 00:00.
-
@skishore1998 said in Inherit QObject in a cuda class:
The above code without QObject inheritance works fine.
I think it's not a good idea to make your CUDA class (including the
*.cu
file) aQObject
.
You need to compile your CUDA/cu file separately.Here is an example
(it's somewhat old and it uses QMake, you have to adapt it to CMake) -
Something is wrong with the nvcc.exe call, but I'm not a CUDA expert.
-
Hi,
As @Pl45m4 wrote, CUDA kernels are a different beast that you should keep separated from QObject.
You won't be able to use signals and slots from CUDA code anyway.
Make your QObject based classes use CUDA kernels and keep compilation units separate. -