How to combine Qt and CUDA?

I want to design my program with both Qt and CUDA under ubuntu 8.10. Qt for the GUI and CUDA for the calculation.
Does anyone know how I can ahieve this?
Thanks.

At work, we have done this by making a C++ shared library. This contains a nice object that allocatest device&host memory as needed and does the CUDA calls, etc. etc.

Then we link this into a Qt program. Easy!

Probably good that you kept them separate. moc + nvcc = probable badness.

Thanks. I’ll have a try.

Then, would you please tell me your suggestion?

If I want to program with cuda, what’s the best choice for GUI design? GTK or something?

No, I meant that it’s probably a good idea that he kept Qt and CUDA source separate, not that you shouldn’t use them together. We use Qt for the visual profiler. I personally have used Qt a lot and really like it. By all means, use Qt.

All I meant is that I’m a little concerned that if you try to use CUDART and compile with nvcc, what you get from Qt’s meta-object compiler might not get along with nvcc because it’s very bizarre C++. In that case, a library is probably the easiest way to use both. I’m just not sure what the toolchain for a file that has both CUDA and Qt source is, and it’s sufficiently far away enough from standard compilation that it might be slightly less than stable.

Oh, I got it.

Thanks a lot.

Hello kristleifur,

some time ago you replied to a request with on how to combine Qt and CUDA with

Well, it sounds easy and straightforward. I attach the Makefile below used to create a static library containing cuda code as well as other C++ code, but it does not work, actually the archiver complains.

Do I have to use GCC with some special flags, or “ar”?

How would I link my Qt application, i.e. what do I have to add to the .pro file? Do I need to link a second time with cudart?

Many thanks for your help in advance,

peter

PROCESSLIB := libprocess.a

all : $(PROCESSLIB)

CUDA_INSTALL_PATH ?= /usr/local/cuda

GCC		:= gcc

NVCC	   := $(CUDA_INSTALL_PATH)/bin/nvcc 

CXX		:= g++

CC		 := gcc

CUDALINKER := g++ -fPIC

LINKER	 := g++

SRCDIR	 ?= .

ROOTDIR	?= .

ROOTBINDIR ?= $(ROOTDIR)/bin

ROOTOBJDIR ?= $(ROOTDIR)/obj

CUDASDK_DIR := $(HOME)/NVIDIA_GPU_Computing_SDK/C

CUDASDK_LIBDIR := $(CUDASDK_DIR)/lib

CUDASDK_COMMONINCDIR := $(CUDASDK_DIR)/common/inc

CUDASDK_COMMONLIBDIR := $(CUDASDK_DIR)/common/lib/linux

VERBOSE :=

COMMONINCLUDES  += -I. -I../common

CUDAINCLUDES  += -I$(CUDA_INSTALL_PATH)/include -I$(CUDASDK_COMMONINCDIR)

COMMONFLAGS += -DUNIX

CXXFLAGS := \

	-W -Wall \

	-Wimplicit \

	-Wswitch \

	-Wformat \

	-Wchar-subscripts \

	-Wparentheses \

	-Wmultichar \

	-Wtrigraphs \

	-Wpointer-arith \

	-Wcast-align \

	-Wreturn-type \

	-Wno-unused-function \

	$(SPACE)

CFLAGS := $(CXXFLAGS) \

	-Wstrict-prototypes \

	-Wmissing-prototypes \

	-Wmissing-declarations \

	-Wnested-externs \

	-Wmain

	

NVCCFLAGS := \

	-c -Xopencc \

	-OPT:unroll_size=200000 

# Debug/release configuration

ifeq ($(dbg),1)

	COMMONFLAGS += -g

	NVCCFLAGS   += -D_DEBUG

	CXXFLAGS	+= -D_DEBUG

	CFLAGS	  += -D_DEBUG

	BINSUBDIR   := debug

	LIBSUFFIX   := D

else 

	COMMONFLAGS += -O2 

	BINSUBDIR   := release

	LIBSUFFIX   :=

	NVCCFLAGS   += --compiler-options -fno-strict-aliasing

	CXXFLAGS	+= -fno-strict-aliasing

	CFLAGS	  += -fno-strict-aliasing

endif

	

CUDALIB := -L$(CUDA_INSTALL_PATH)/lib64 -L$(CUDASDK_LIBDIR) -L$(CUDASDK_COMMONLIBDIR)

CUDALIB += -lcudart -lcutil ${OPENGLLIB} $(PARAMGLLIB) $(RENDERCHECKGLLIB) $(CUDPPLIB) ${LIB}

TARGETDIR := $(ROOTBINDIR)/$(BINSUBDIR)

# Add common flags

NVCCFLAGS += $(COMMONFLAGS) $(COMMONINCLUDES) $(CUDAINCLUDES)

CFLAGS	+= $(COMMONFLAGS) $(COMMONINCLUDES) 

CXXFLAGS  += $(COMMONFLAGS) $(COMMONINCLUDES) 

OBJDIR := $(ROOTOBJDIR)/$(BINSUBDIR)

CUDAOBJS := \

	$(OBJDIR)/processspec.cpp.o \

	$(OBJDIR)/migration.cu.o

$(PROCESSLIB): directories $(CUDAOBJS) Makefile

	ar $(TARGETDIR)/$(PROCESSLIB) $(CUDAOBJS) $(CUDALIB)

$(OBJDIR)/processspec.cpp.o : $(SRCDIR)/processspec.cpp $(C_DEPS)

	$(VERBOSE)$(CXX) $(CXXFLAGS) -o $(OBJDIR)/processspec.cpp.o -c $(SRCDIR)/processspec.cpp

	

$(OBJDIR)/migration.cu.o : $(SRCDIR)/migration.cu $(CU_DEPS)

	$(VERBOSE)$(NVCC) $(NVCCFLAGS) -o $(OBJDIR)/migration.cu.o -c $(SRCDIR)/migration.cu

directories:

	$(VERBOSE)mkdir -p $(OBJDIR)

	$(VERBOSE)mkdir -p $(TARGETDIR)

clean:

	$(VERBOSE)rm -r $(ROOTOBJDIR)

	$(VERBOSE)rm -r $(ROOTBINDIR)

So it might be useful to other people having the same objective, here some code snippets to build a static library out of a cuda code file, processing.cu, then link a Qt application to that libary. It should be possible to build larger applications on top of this example.

Kind regards,

peter

Header file ./ProcessingLib/processing.h

int processingInit();

int processingExec(char *data);

int processingExit();

Cuda file ./ProcessingLib/processing.cu

int processingInit() {

	printf("processingInit\n");

	//initialisation goes here,

	return 0;

}

int processingExec(char *data) {

	printf("processingExec\n");

	//do your stuff here

	return 0;

}

int processingExit(){

	printf("processingExit\n");

	//cleanup goes here

	return 0;

}

./ProcessingLib/Makefile to generate libProcessingLib.a

PROCESSLIB := libProcessingLib.a

all : $(PROCESSLIB)

CUDA_INSTALL_PATH ?= /usr/local/cuda

NVCC	   := $(CUDA_INSTALL_PATH)/bin/nvcc 

CXX		:= g++

ARCHIVER   := ar cqs

TARGETDIR := ../lib

TARGET := $(TARGETDIR)/$(PROCESSLIB)

CUDASDK_DIR := $(HOME)/NVIDIA_GPU_Computing_SDK/C

CUDASDK_LIBDIR := $(CUDASDK_DIR)/lib

CUDASDK_COMMONINCDIR := $(CUDASDK_DIR)/common/inc

CUDASDK_COMMONLIBDIR := $(CUDASDK_DIR)/common/lib/linux

VERBOSE :=

CUDAINCLUDES  += -I$(CUDA_INSTALL_PATH)/include -I$(CUDASDK_COMMONINCDIR)

COMMONFLAGS += -DUNIX

CXXFLAGS := \

	-W -Wall \

	-Wimplicit \

	-Wswitch \

	-Wformat \

	-Wchar-subscripts \

	-Wparentheses \

	-Wmultichar \

	-Wtrigraphs \

	-Wpointer-arith \

	-Wcast-align \

	-Wreturn-type \

	-Wno-unused-function \

	$(SPACE)

	

NVCCFLAGS := \

	-c -Xopencc \

	-OPT:unroll_size=200000 

# Debug/release configuration

ifeq ($(dbg),1)

	COMMONFLAGS += -g

	NVCCFLAGS   += -D_DEBUG

	CXXFLAGS	+= -D_DEBUG

	CFLAGS	  += -D_DEBUG

	OBJDIR   := debug

	LIBSUFFIX   := D

else 

	COMMONFLAGS += -O2 

	OBJDIR   := release

	LIBSUFFIX   :=

	NVCCFLAGS   += --compiler-options -fno-strict-aliasing

	CXXFLAGS	+= -fno-strict-aliasing

	CFLAGS	  += -fno-strict-aliasing

endif

	

CUDALIB := -L$(CUDA_INSTALL_PATH)/lib64 -L$(CUDASDK_LIBDIR) -L$(CUDASDK_COMMONLIBDIR)

CUDALIB += -lcudart -lcutil ${OPENGLLIB} $(PARAMGLLIB) $(RENDERCHECKGLLIB) $(CUDPPLIB) ${LIB}

# Add common flags

NVCCFLAGS += $(COMMONFLAGS) $(COMMONINCLUDES) $(CUDAINCLUDES)

CFLAGS	+= $(COMMONFLAGS) $(COMMONINCLUDES) 

CXXFLAGS  += $(COMMONFLAGS) $(COMMONINCLUDES) 

CUDAOBJS := \

	$(OBJDIR)/processing.cu.o

$(PROCESSLIB): directories $(CUDAOBJS)

	$(ARCHIVER) $(TARGET) $(CUDAOBJS)

	

$(OBJDIR)/processing.cu.o : processing.cu processing.h $(CU_DEPS)

	$(VERBOSE)$(NVCC) $(NVCCFLAGS) -o $(OBJDIR)/processing.cu.o -c processing.cu

directories:

	$(VERBOSE)mkdir -p $(OBJDIR)

	$(VERBOSE)mkdir -p $(TARGETDIR)

clean:

	$(VERBOSE)rm -r $(OBJDIR)

	$(VERBOSE)rm -r $(TARGET)

Qt project file ./ProcessingTest/ProcessingTest.pro to build a simple application

INCLUDEPATH += ../ProcessingLib

	

CUDA_LIBDIR = /usr/local/cuda/lib64

CUDASDK_LIBDIR = /home/peter/NVIDIA_GPU_Computing_SDK/C/lib

CUDALIB = -L$$CUDA_LIBDIR -L$$CUDASDK_LIBDIR -lcudart -lcutil

QT	   -= gui

TARGET = ProcessLibTest

CONFIG   += console

CONFIG   -= app_bundle

TEMPLATE = app

SOURCES += main.cpp

LIBS += -L../lib -lProcessingLib $$CUDALIB

./ProcessingTest/main.cpp for application

#include <processinglib.h>

int main(){

	char data[1024];

	processingInit();

	processingExec(data);

	processingExit();

}

So it might be useful to other people having the same objective, here some code snippets to build a static library out of a cuda code file, processing.cu, then link a Qt application to that libary. It should be possible to build larger applications on top of this example.

Kind regards,

peter

Header file ./ProcessingLib/processing.h

int processingInit();

int processingExec(char *data);

int processingExit();

Cuda file ./ProcessingLib/processing.cu

int processingInit() {

	printf("processingInit\n");

	//initialisation goes here,

	return 0;

}

int processingExec(char *data) {

	printf("processingExec\n");

	//do your stuff here

	return 0;

}

int processingExit(){

	printf("processingExit\n");

	//cleanup goes here

	return 0;

}

./ProcessingLib/Makefile to generate libProcessingLib.a

PROCESSLIB := libProcessingLib.a

all : $(PROCESSLIB)

CUDA_INSTALL_PATH ?= /usr/local/cuda

NVCC	   := $(CUDA_INSTALL_PATH)/bin/nvcc 

CXX		:= g++

ARCHIVER   := ar cqs

TARGETDIR := ../lib

TARGET := $(TARGETDIR)/$(PROCESSLIB)

CUDASDK_DIR := $(HOME)/NVIDIA_GPU_Computing_SDK/C

CUDASDK_LIBDIR := $(CUDASDK_DIR)/lib

CUDASDK_COMMONINCDIR := $(CUDASDK_DIR)/common/inc

CUDASDK_COMMONLIBDIR := $(CUDASDK_DIR)/common/lib/linux

VERBOSE :=

CUDAINCLUDES  += -I$(CUDA_INSTALL_PATH)/include -I$(CUDASDK_COMMONINCDIR)

COMMONFLAGS += -DUNIX

CXXFLAGS := \

	-W -Wall \

	-Wimplicit \

	-Wswitch \

	-Wformat \

	-Wchar-subscripts \

	-Wparentheses \

	-Wmultichar \

	-Wtrigraphs \

	-Wpointer-arith \

	-Wcast-align \

	-Wreturn-type \

	-Wno-unused-function \

	$(SPACE)

	

NVCCFLAGS := \

	-c -Xopencc \

	-OPT:unroll_size=200000 

# Debug/release configuration

ifeq ($(dbg),1)

	COMMONFLAGS += -g

	NVCCFLAGS   += -D_DEBUG

	CXXFLAGS	+= -D_DEBUG

	CFLAGS	  += -D_DEBUG

	OBJDIR   := debug

	LIBSUFFIX   := D

else 

	COMMONFLAGS += -O2 

	OBJDIR   := release

	LIBSUFFIX   :=

	NVCCFLAGS   += --compiler-options -fno-strict-aliasing

	CXXFLAGS	+= -fno-strict-aliasing

	CFLAGS	  += -fno-strict-aliasing

endif

	

CUDALIB := -L$(CUDA_INSTALL_PATH)/lib64 -L$(CUDASDK_LIBDIR) -L$(CUDASDK_COMMONLIBDIR)

CUDALIB += -lcudart -lcutil ${OPENGLLIB} $(PARAMGLLIB) $(RENDERCHECKGLLIB) $(CUDPPLIB) ${LIB}

# Add common flags

NVCCFLAGS += $(COMMONFLAGS) $(COMMONINCLUDES) $(CUDAINCLUDES)

CFLAGS	+= $(COMMONFLAGS) $(COMMONINCLUDES) 

CXXFLAGS  += $(COMMONFLAGS) $(COMMONINCLUDES) 

CUDAOBJS := \

	$(OBJDIR)/processing.cu.o

$(PROCESSLIB): directories $(CUDAOBJS)

	$(ARCHIVER) $(TARGET) $(CUDAOBJS)

	

$(OBJDIR)/processing.cu.o : processing.cu processing.h $(CU_DEPS)

	$(VERBOSE)$(NVCC) $(NVCCFLAGS) -o $(OBJDIR)/processing.cu.o -c processing.cu

directories:

	$(VERBOSE)mkdir -p $(OBJDIR)

	$(VERBOSE)mkdir -p $(TARGETDIR)

clean:

	$(VERBOSE)rm -r $(OBJDIR)

	$(VERBOSE)rm -r $(TARGET)

Qt project file ./ProcessingTest/ProcessingTest.pro to build a simple application

INCLUDEPATH += ../ProcessingLib

	

CUDA_LIBDIR = /usr/local/cuda/lib64

CUDASDK_LIBDIR = /home/peter/NVIDIA_GPU_Computing_SDK/C/lib

CUDALIB = -L$$CUDA_LIBDIR -L$$CUDASDK_LIBDIR -lcudart -lcutil

QT	   -= gui

TARGET = ProcessLibTest

CONFIG   += console

CONFIG   -= app_bundle

TEMPLATE = app

SOURCES += main.cpp

LIBS += -L../lib -lProcessingLib $$CUDALIB

./ProcessingTest/main.cpp for application

#include <processinglib.h>

int main(){

	char data[1024];

	processingInit();

	processingExec(data);

	processingExit();

}