CUDA and C++ function problems ( Visual Studio 2013) - c++

I am trying to call a cuda function that is defined in a cu file from a cpp file in Visual Studio but I keep receiving the following error.
TomColourCorrectionMain.obj : error LNK2019: unresolved external symbol "public: void __cdecl hwk::TomColourCorrection::brightness(int,int)" (?brightness#TomColourCorrection#hwk##QEAAXHH#Z) referenced in function "public: virtual void __cdecl hwk::TomColourCorrection::processCore(class std::shared_ptr)" (?processCore#TomColourCorrection#hwk##UEAAXV?$shared_ptr#VIImageProcessingContext#hwk###std###Z)
Now from reading other questions similar to this, I understand its to do with how the function is defined and that there is something wrong there but I can't see it from when I have defined in the header and cuda file.
This is the code I have (I am a novice at CUDA but I can compile CUDA fine and the code runs when I don't call this function in C++):
header file
#pragma once
#include "ImageProcessorWithProperties.h"
#include <iostream>
#include <cuda_runtime.h>
#include <cuda.h>
class TomColourCorrection : public ImageProcessorWithProperties, public PropertyConsumer<TomColourCorrection>{
public: TomColourCorrection(PropNodePtr n, std::function<void()> requestReprocess);
virtual void processCore(IImageProcessingContextPtr context);
static void DeclareSettings(hwk::PropNodePtr n);
virtual ~TomColourCorrection();
void brightness(int iw, int ih); (function I am talking about)
};
}
cpp file with function call //its just segments of the important code as the rest of it isn't necessary for the actual function itself
#include "stdafx.h"
#include "TomColourCorrection.h"
#include <opencv2/imgproc/imgproc.hpp>
#include <cv.h>
#include <highgui.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <cuda_runtime.h>
#include <cuda.h>
namespace hwk{
TomColourCorrection::TomColourCorrection(PropNodePtr n, std::function<void()> requestReprocess) :
ImageProcessorWithProperties("sandbox", n, requestReprocess),
PropertyConsumer<TomColourCorrection>(n)
{
}
void TomColourCorrection::processCore(IImageProcessingContextPtr context){
brightness(16, 16); (just generic numbers at the moment as I am trying to resolve this issue etc)
}
}
CUDA File and function definition
#include "TomColourCorrection.h"
#include "device_launch_parameters.h"
__global__ void brightness_kernel(int iw, int ih)
{
// Calculate our pixel's location
int x = (blockIdx.x * blockDim.x) + threadIdx.x;
int y = (blockIdx.y * blockDim.y) + threadIdx.y;
// Variables to store the sum
int count = 0;
float sum = 0.0;
// Do the blur operation by summing the surround pixels
/* for (int j = -(bh / 2); j <= (bh / 2); j++)
{
for (int i = -(bw / 2); i <= (bw / 2); i++)
{
// Verify that this offset is within the image boundaries
if ((x + i) < iw && (x + i) >= 0 && (y + j) < ih && (y + j) >= 0)
{
sum += (float)source[((y + j) * iw) + (x + i)];
count++;
}
}
}*/
// Average the sum
sum /= (float)count;
// dest[(y * iw) + x] = (unsigned char)sum;
}
void brightness(int iw, int ih) //, unsigned char *source, unsigned char *dest)
{
// allocate memory for the bitmap in GPU memory
unsigned char *dev_source, *dev_dest;
// cudaHostGetDevicePointer(&dev_source, source, 0);
// cudaHostGetDevicePointer(&dev_dest, dest, 0);
// Run the boxfilter kernel
dim3 blocks(iw / 16, ih / 16);
dim3 threads(16, 16);
// Execute the kernel
brightness_kernel << <blocks, threads >> >(iw, ih);
cudaThreadSynchronize();
}

Modify the TomColourCorrection.h like this:
#pragma once
#include "ImageProcessorWithProperties.h"
#include <iostream>
#include <cuda_runtime.h>
#include <cuda.h>
void brightness_wrapper(int, int);
class TomColourCorrection : public ImageProcessorWithProperties, public PropertyConsumer<TomColourCorrection>{
public:
TomColourCorrection(PropNodePtr n, std::function<void()> requestReprocess);
virtual void processCore(IImageProcessingContextPtr context);
static void DeclareSettings(hwk::PropNodePtr n);
virtual ~TomColourCorrection();
void brightness(int iw, int ih);
};
Modify your cpp file like this:
#include "stdafx.h"
#include "TomColourCorrection.h"
#include <opencv2/imgproc/imgproc.hpp>
#include <cv.h>
#include <highgui.h>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
#include <cuda_runtime.h>
#include <cuda.h>
namespace hwk{
void TomColourCorrection::brightness(int iw, int ih){
brightness_wrapper(iw, ih);}
TomColourCorrection::TomColourCorrection(PropNodePtr n, std::function<void()> requestReprocess) : ImageProcessorWithProperties("sandbox", n, requestReprocess), PropertyConsumer<TomColourCorrection>(n)
{
}
void TomColourCorrection::processCore(IImageProcessingContextPtr context){
brightness(16, 16);
}
}
And in your cuda file change this:
void brightness(int iw, int ih) //, unsigned char *source, unsigned char *dest)
to this:
void brightness_wrapper(int iw, int ih) //, unsigned char *source, unsigned char *dest)
This is mainly just spelling out the details of Ryck's answer.

I think you need change
void brightness(int iw, int ih)
to
void TomColourCorrection::brightness(int iw, int ih)
and move the implementation to your header file or a .cpp file.

Related

command spawnl() not executed

I have a code that is executable without error messages but it seems like it denies to run the code
I call by the "spawnl" command. This is my code and I receive "error=-1". I tried may different ways to solve the situation but I always receive the "-1" for an answer. I use Dev C++ compiler with 32bit release. My problem is to call the other program, sending the name of the file.
#include <stdlib.h>
#include <graphics.h>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <conio.h>
#include <process.h>
#include <ctype.h>
#include <dir.h>
#include <windows.h>
#include <dos.h>
#include <iostream>
#include <stddef.h>
void translate_to_ascii_files(),
save_mesh_data(),
make_no(),
give_names();
int load_patches(char *);
FILE *memco ;
int outnod[400] ;
float r_vector[21][21][3],cx[500],cy[500],cz[500] ;
int NOP1,NOP2; /* Number Of Points */
int patches;
char nams[26][26];
int num_of_files;
int kk,nv,nh,exnod,totnod ;
int no[4][400];
char filename[26];
void *buf;
COORD coord= {0,0};
HANDLE hConsole;
using namespace std; // std::cout, std::cin
void gotoxy(int x,int y) {
coord.X=x;
coord.Y=y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
}
int main(int argc,char *argv[]) {
char com_nam[26];
int counter1,counter2,i;
int error;
system("cls");
give_names();
printf("give the final filename:");scanf("%s",filename);
for(patches=1;patches<=num_of_files;patches++) {
strcpy(com_nam,nams[patches]);
load_patches(com_nam); /* load patches for meshing*/
i=1;
for(counter1=0;counter1<=NOP1;counter1++) {
for(counter2=0;counter2<=NOP2;counter2++) {
cx[i]=r_vector[counter1][counter2][0];
cy[i]=r_vector[counter1][counter2][1];
cz[i]=r_vector[counter1][counter2][2];
i=i+1;
}
}
nh=NOP1+1;nv=NOP2+1;
make_no();
save_mesh_data();
if(argc ==1){
error=spawnl(P_WAIT,"c:\\cpprog\\unitsrf.exe","",filename,NULL);
if (error ==0) {
else {printf ("error=%d\n",error); system("PAUSE");
} }
else{gotoxy(2,11);printf("error=%s\n\n",argv[1]);
system("PAUSE");
}
} translate_to_ascii_files();
}

Filling eigen matrix with values

sorry to bother. Could you know maybe how can i fix my code. It gives me this error:
/usr/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h:365: Eigen::DenseCoeffsBase<Derived, 1>::Scalar& Eigen::DenseCoeffsBase<Derived, 1>::operator()(Eigen::Index, Eigen::Index) [with Derived = Eigen::Matrix<float, -1, -1>; Eigen::DenseCoeffsBase<Derived, 1>::Scalar = float; Eigen::Index = long int]: Assertion `row >= 0 && row < rows() && col >= 0 && col < cols()' failed.
I think that I declared matrix in right way. My mistake (I think) is when i try to fill her with values in Possible transforms function. I think it might be wrong transform1(0, position)=.. I tried it to comment that lines of code and wrote a simple code like transform1(0, position)=1; and it gave the same error.
Sorry to bother,
Kind regards.
My code :
#include "ros/ros.h"
#include <cstdlib>
#include <fstream>
#include <stdio.h>
#include <regex>
#include "sensor_msgs/PointCloud2.h"
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/point_types.h>
#include <pcl/PCLPointCloud2.h>
#include <pcl/conversions.h>
#include <pcl_ros/transforms.h>
#include <boost/shared_ptr.hpp>
#include "pcl_ros/point_cloud.h"
#include "sensor_msgs/PointField.h"
#include <pcl/io/pcd_io.h>
#include "nav_msgs/Odometry.h"
#include "eigen3/Eigen/SVD"
#include "eigen3/Eigen/Dense"
#include "clustering/Track.h"
#include "eigen3/Eigen/Core"
#include "eigen3/Eigen/Sparse"
using namespace Eigen;
int number_od_possible_tracks = 15;
class Odometry_class {
ros::NodeHandle nodeh;
ros::Subscriber sub;
ros::Publisher pub;
public:
Odometry_class();
void Odometry(const sensor_msgs::PointCloud2 &msg);
bool Has_pointcloud_min3points(pcl::PointCloud<pcl::PointXYZIVSI> cloud);
bool Possible_transform(pcl::PointCloud<pcl::PointXYZIVSI> cloud);
void Restore_Ids();
pcl::PointCloud<pcl::PointXYZIVSI> last_cloud;
Eigen::MatrixXf transform1 = (Eigen::MatrixXf(3,15));
Eigen::MatrixXf transform2=(Eigen::MatrixXf(3,15));
int consecutive_Ids_current[15];
int consecutive_Ids_previous[15];
int position;
void Transform();
};
Odometry_class::Odometry_class(){
sub = nodeh.subscribe("trackers", 10, &Odometry_class::Odometry, this);
pub = nodeh.advertise<nav_msgs::Odometry>("odometry", 10);
}
void Odometry_class::Odometry(const sensor_msgs::PointCloud2 &msg ){
pcl::PCLPointCloud2 pcl_pc2;
pcl_conversions::toPCL(msg, pcl_pc2);
pcl::PointCloud<pcl::PointXYZIVSI> cloud;
pcl::fromPCLPointCloud2(pcl_pc2, cloud);
if(Possible_transform(cloud)){
ROS_INFO("Transformation is possible");
}
else{
ROS_INFO("Transformation is not possible");
}
Restore_Ids();
pcl::fromPCLPointCloud2(pcl_pc2, last_cloud);
}
void Odometry_class::Restore_Ids(){
int i=0;
while(consecutive_Ids_current[i]!=0){
consecutive_Ids_current[i]=0;
consecutive_Ids_previous[i]=0;
i++;
}
}
bool Odometry_class::Has_pointcloud_min3points(pcl::PointCloud<pcl::PointXYZIVSI> cloud){
bool has=false;
if(cloud.width>=3){
has=true;
}
return has;
}
bool Odometry_class::Possible_transform(pcl::PointCloud<pcl::PointXYZIVSI> cloud){
bool possible=false;
position=0;
if(Has_pointcloud_min3points(cloud)&Has_pointcloud_min3points(last_cloud)){
for(int i=0;i<cloud.width;i++){
for(int j=0;j<last_cloud.width;j++){
if(cloud[i].id==last_cloud[j].id){
consecutive_Ids_current[position]=i;
consecutive_Ids_previous[position]=j;
position++;
}
}
}
}
if(position>=3){
possible=true;
transform1.resize(3,position);
transform2.resize(3,position);
for(int i=0;i<position;i++){
transform1(0,position)= cloud[consecutive_Ids_current[i]].x;
transform1(1,position)= cloud[consecutive_Ids_current[i]].y;
transform1(2,position)= cloud[consecutive_Ids_current[i]].z;
transform2(0,position)= cloud[consecutive_Ids_previous[i]].x;
transform2(1,position)= cloud[consecutive_Ids_previous[i]].y;
transform2(2,position)= cloud[consecutive_Ids_previous[i]].z;
}
}
return possible;
}
int main(int argc, char **argv) {
ros::init(argc, argv, "Odometry");
Odometry_class Odometry;
ros::spin();
return 0;
}
I think you mixed up your loop variable, i, and upper limit, position. Using position as an index would result in accessing the matrix out of bounds, and the Eigen library catches that in an assertion. Using the loop variable should resolve the error.
transform1(0,i)= cloud[consecutive_Ids_current[i]].x;
And likewise for the rest of the transform1 and transform2 assignments.

Expected ; on CUDA kernel

I am having a very weird error while trying to create a CUDA kernel to execute a for loop:
#include <stdlib.h>
#include <stdio.h>
#include <thrust/reduce.h>
#include <cuda.h>
int main(int argc, char** argv)
{
float *arrayA;
cudaMalloc((void**)&arrayA, 4096 * 4096 * sizeof(float));
float *arrayB;
cudaMalloc((void**)&arrayB, 4096 * 4096 * sizeof(float));
__global__ void loopKernel(float* arrayA, float* arrayB)
{
int i = threadIdx.x + blockDim.x*blockIdx.x;
if (i < m)
{
//do stuf
}
}
loopKernel << 8, 256 >> (arrayA, arrayB);
}
the error is on the opening { for the kernel (line 14):
error: expected a ";"
it seems really odd as I get the same error on Visual Studio and linux terminal, so it is not an OS issue.
The file is also .cu so there is no way it's being sent to the wrong compiler.
Any help will be appreciated.
A __global__ function definition (i.e. kernel definition) is not something you do within the body of another function. We don't typically do this in C or C++ either (a C/C++ function definition is not usually placed within the body of another function definition).
Place your kernel definitions at global scope (i.e. outside the body of any other function definition, including main).
Something like this:
#include <stdlib.h>
#include <stdio.h>
#include <thrust/reduce.h>
#include <cuda.h>
__global__ void loopKernel(float* arrayA, float* arrayB)
{
int i = threadIdx.x + blockDim.x*blockIdx.x;
if (i < m)
{
arrayA[i] = 0.f;
arrayB[(n - 1)*m + i] = 0.f;
}
}
int main(int argc, char** argv)
{
float *arrayA;
cudaMalloc((void**)&arrayA, 4096 * 4096 * sizeof(float));
float *arrayB;
cudaMalloc((void**)&arrayB, 4096 * 4096 * sizeof(float));
loopKernel << 8, 256 >> (arrayA, arrayB);
}
There are various other issues with the posted code:
It provided no definition for m or n.
The kernel calling syntax is wrong, instead of <<...>> it should be <<<...>>>
For these types of basic issues, its probably better to study a simple (correct) code like the vectorAdd sample code.

opencv_NormalizeHist.cpp:47:34: error: 'NormalizeHist' was not declared in this scope

I have written the code to access opencv(Mainly used for image processing) function from Scilab(numerical computation software). When I run bilder gateway file, I am encountering below error.
opencv_NormalizeHist.cpp:47:34: error: 'NormalizeHist' was not declared in this scope.
#include <numeric>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace cv;
using namespace std;
extern "C"
{
#include "api_scilab.h"
#include "Scierror.h"
#include "BOOL.h"
#include <localization.h>
#include "../common.h"
int opencv_NormalizeHist(char *fname, unsigned long fname_len)
{
SciErr sciErr;
int iRows=0,iCols=0;
int *piAddr2 = NULL;
//checking input argument
CheckInputArgument(pvApiCtx, 2, 2);
CheckOutputArgument(pvApiCtx, 0, 0) ;
//Define histogram
Mat hist;
retrieveImage(hist,1);
double *factor;
//for value of factor
sciErr = getVarAddressFromPosition(pvApiCtx,2,&piAddr2);
if (sciErr.iErr)
{
printError(&sciErr, 0);
return 0;
}
sciErr = getMatrixOfDouble(pvApiCtx, piAddr2, &iRows, &iCols ,&factor);
if(sciErr.iErr)
{
printError(&sciErr, 0);
return 0;
}
NormalizeHist(hist, factor[0]); //Normalizing hist
string tempstring = type2str(hist.type());
char *checker;`enter code herek
checker = (char *)malloc(tempstring.size() + 1);
memcpy(checker, tempstring.c_str(), tempstring.size() + 1);
returnImage(checker,hist,1); //here, remove the temp as a parameter as it is not needed, and instead add 1 as the third parameter. 1 denotes that the first output argument will be this variable
free(checker); //free memory taken up by checker, i missed this earlier
//Assigning the list as the Output Variable
AssignOutputVariable(pvApiCtx, 1) = nbInputArgument(pvApiCtx) + 1;
//Returning the Output Variables as arguments to the Scilab environment
ReturnArguments(pvApiCtx);
return 0;
}
/* ==================================================================== */
}

Setenv: Type expression list treated as compound expression in initializer

Getting Type expression list treated as compound expression in initializer
On both these function calls -
char itoa(new_total, new_total_ch, 10);
int setenv("COUNT_TOTAL", new_total_ch, 1);
Here's the code snippet -
#include <iostream>
// create process team
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <ctime>
// initialize & process
#include <time.h>
#include <string>
#include <fstream>
#include <cmath>
#include <iosfwd>
// initialize & process
using std::ifstream;
using namespace std;
class Count3sProcessParallel {
public:
//int process();
int pr_count;
int process();
typedef int COUNT_TOTAL;
private:
int worker;
//declare process()
long unit_of_work;
long lower_bound;
long upper_bound;
int pr_i;
char * ct;
int ct_i;
int new_total;
char itoa();
char * new_total_ch;
int setenv();
};
int Count3sProcessParallel::process() {
// determine upper lower bounds
unit_of_work = in_length/workers_num;
lower_bound = (worker -1) * unit_of_work;
upper_bound = (worker * unit_of_work) -1;
// iterate and count
pr_count = 0;
for (pr_i = lower_bound; pr_i < upper_bound; pr_i++)
if (floor(in_buffer[pr_i] == 3))
pr_count++;
return pr_count;
//update COUNT_TOTAL
ct = getenv("COUNT_TOTAL");
ct_i = atoi(ct);
new_total = (pr_count + ct_i);
char * new_total_ch[33];
char itoa(new_total, new_total_ch, 10);
int setenv("COUNT_TOTAL", new_total_ch, 1);
delete[] in_buffer;
return 0;
}
How do I resolve this? Thanks.
Remove the leading types. Just use:
itoa(new_total, new_total_ch, 10);
setenv("COUNT_TOTAL", new_total_ch, 1);