How to link sources and headers( cpp vs cu)

I try to build a dll for external program, which has worked fine previously. But… For some reason, if i try to compile the following in visual studio 2008 pro Sp1 (win7 64bit release)

intensityRescale<<>>(src_img_in_data, maxValue, minValue, 1);

I’ll get an error:

1>..\inte.cpp(37) : error C2059: syntax error : '<'

So i read somewhere that this has to be in a .cu file, then i tried the following:

In “inte.cpp” i have:

void inte( DM::Image img, float maxValue, float minValue )

{

#include "inte.h"

#include "Source1.h"

// Some stuff to get the pointer (float * img_data) //WORKS

intensityRescalec(img_data, maxValue, minValue,1);

}

In “inte.h” i just have:

void inte(DM::Image, float, float );

Then i made a .cu file “Source1.cu” :

#include "Source1.h"

__global__ void intensityRescale(float *image, float maxValu, float minValu, int typ)

{

const int tid = (blockIdx.y*MNBLOCKX + blockIdx.x)*blockDim.x + threadIdx.x;

if(tid < MNX0*MNY0*MNZ0)

{   

    if(typ>0)       

        image[tid] = (image[tid] - minValu)/(maxValu-minValu);

    else

        image[tid] = image[tid]*(maxValu-minValu) + minValu;

}

}

 void intensityRescalec(float *mimage, float mmaxValue, float mminValue,int mType)

{

dim3 Mnblocks;

Mnblocks.x = MNBLOCKX;

Mnblocks.y =  ((1 + (MNX0*MNY0*MNZ0 - 1)/MNTHREAD_PER_BLOCK) - 1) / MNBLOCKX + 1; 

intensityRescale<<<Mnblocks, MNTHREAD_PER_BLOCK>>>(mimage, mmaxValue,mminValue,     1);

}

And then in “Source1.h”:

#ifndef _Source1_h_INCLUDED__

#define _Source1_h_INCLUDED__

#include "cuda.h"

#include <cutil_inline.h>

#include <cublas.h>

#define MNBLOCKX 1024

#define MNX0 1024

#define MNY0 1024

#define MNZ0 1

#define MNBLOCKX 1024

#define MNTHREAD_PER_BLOCK 256

void intensityRescalec(float * da, float d, float f , int g);

void intensityRescale(float *image, float maxValu, float minValu, int typ);

#endif

Now if i have a custom build rule cuda64.rules it gives the following:

1>inte.obj : error LNK2019: unresolved external symbol "void __cdecl          intensityRescalec(float *,float,float,int)" (?intensityRescalec@@YAXPEAMMMH@Z) referenced  in function "void __cdecl inte(class Gatan_Image *,float,float)"  (?inte@@YAXPEAVGatan_Image@@MM@Z)

1>C:\ProgramData\Gatan\DMSDK\ITK\buildcmake\Release\ITK.dll : fatal error LNK1120: 1   unresolved externals

Without the rule:

1>C:\ProgramData\Gatan\DMSDK\ITK\buildcmake\Release\ITK.dll : fatal error LNK1169: one or more multiply defined symbols found

I don’t use the variables anywhere else so what does this mean?

Also i have to build this on Multi-threaded DLL (/MD) mode since some other libraries depend on this. I did not found the cutil64D.lib in CUDA 4. Is this deprecated or did i miss something.

I have downloaded all toolkits,drivers, cuda SDK,buildrules and followed the instructions therein. Also tried the CUDA VS Wizard.

I have spend days on this! NOTHING WORKS!!!

HELP!

Previously i did manage to build a fft project from CUFFT into the dll so… But this did not involve kernels.

Huge thanks for any feedback!

I’m not sure this is the cause of your problem, but you need to delete the line

void intensityRescale(float *image, float maxValu, float minValu, int typ);

from Source1.h as this prototype is wrong (you declare a host function of the same name as your kernel).

there is a “c” letter difference!

Or?

There is [font=“Courier New”]intensityRescalec()[/font] as well. But [font=“Courier New”]intensityRescale()[/font] is a kernel (a [font=“Courier New”]global[/font]) function in Source1.cu but it is a host function in Source1.h.

Thank you.
But unfortunately it did not resolve the situation…

BUHAHAHAHAHAHAHHAHAHAAAA!

It worked!

When i generate the project with Cmake, the Target machine Platform for Source1.cu is for some reason x86 even thought everything else is x64. How could i change this behaviour? Also the runtime library was [/MT] even though i have [/MD] everywhere else. So if someone else is having the same problems:

  1. Right click the project for Custom Build Rules and choose CUDA Runtime API Build Rule (v4.0)

  2. Then right click on the .cu file for properties and in CUDA runtime API->Host, change the target machine and runtime library

For me, i also change the code to the following

I changed the “Source1.h” to “Source1.cuh” :

#ifndef _Source1_h_

#define _Source1_h_

void intensityRescalec(float *,float,float);

#endif

And “Source1.cu” :

#include "Source1.cuh"

#ifndef _cuda_h_INCLUDED__

#define _cuda_h_INCLUDED__

#include <cuda.h>

#endif

#ifndef _cutil_inline_h_INCLUDED__

#define _cutil_inline_h_INCLUDED__

#include <cutil_inline.h>

#endif

#ifndef _cublas_h_INCLUDED__

#define _cublas_h_INCLUDED__

#include <cublas.h>

#endif

#define MNBLOCKX 1024

#define MNX0 1024

#define MNY0 1024

#define MNZ0 1

#define MNBLOCKX 1024

#define MNTHREAD_PER_BLOCK 256

dim3 Mnblocks;

__global__ void intensityRescale(float *image, float maxValu, float minValu)

{

const int tid = (blockIdx.y*MNBLOCKX + blockIdx.x)*blockDim.x + threadIdx.x;

if(tid < MNX0*MNY0*MNZ0)

{   

    //if(typ>0)     

        image[tid] = (image[tid] - minValu)/(maxValu-minValu);

    //else

        //image[tid] = image[tid]*(maxValu-minValu) + minValu;

}

}

void intensityRescalec(float *mimage, float mmaxValue, float mminValue)

{

Mnblocks.x = MNBLOCKX;

Mnblocks.y =  ((1 + (MNX0*MNY0*MNZ0 - 1)/MNTHREAD_PER_BLOCK) - 1) / MNBLOCKX + 1; 

intensityRescale<<<Mnblocks, MNTHREAD_PER_BLOCK>>>(mimage, mmaxValue, mminValue);

}

In “Inte.h” i just have:

void inte( DM_ImageToken, float, float );

And in “Inte.cpp” everything is the same expect of course for the #include “Source1.cuh”