Thursday, 1 November 2012

Setting up OpenCL in Visual Studio

Introduction

As a relatively new OpenCL user I was looking online for a guide to setting up OpenCL in visual studio. I have about 9 years development experience, so I thought this wouldn’t be much of an issue but I did have a little trouble due to a few details of the setup not being common knowledge. In this article I’m going to provide step by step instructions on setting up OpenCL for both nVidia and ATI graphics cards in Visual Studio 2010. I assume that you have an OpenCL capable graphics card, if you are unsure please check your manufacturers website or leave a comment and I’ll check for you. In this tutorial I will be using an nVidia card but I will provide text instructions for AMD cards.

1.       Installing OpenCL

For nVidia graphics cards you need to install the CUDA toolkit and development drivers. As of the time of writing the current CUDA toolkit version was 5.0, this version includes the development drivers in the toolkit. It can be downloaded here:

For ATI graphics cards you will need to install the AMD APP SDK (formerly the AMD Stream SDK). This can be downloaded from:

2.       Setting up the Project

First thing to do is set up an empty VS project by choosing
  • ‘New Project->Visual C++->Win32 Console Application'
  • Enter a name for the project and choose OK
  • In the application creation wizard choose ‘Next’
  • Under ‘Additional options’ check the ‘Empty project’ box and click ‘Finish’

3.       Including OpenCL in the Project

The first step in including OpenCL is to create a C++ file, this enables the configuration options we will need.
  • Right click on the ‘Source Files’ folder in the solution explorer and select ‘Add-> New Item’
  • Select C++ File and give the file a name
  • Click the ‘Add’ button in the bottom right hand corner of the dialog box
  • Now we are ready to point the project to the include directories for OpenCL
  • Right click on the project name in the solution explorer and select ‘Properties’
  • From the ‘Configuration’ drop down box choose ‘All Configurations’
  • Navigate to ‘Configuration Properties-> C/C++ -> General’
  •  In the ‘Additional Include Directories’ field add the following information depending on your graphics card
    •  nVidia   -“$(CUDA_INC_PATH)”
    • AMD    -“$(AMDAPPSDKROOT)\include”

include path image

4.       Linking OpenCL

Now we are going to tell the project where to find the actual library file which contains OpenCL. This is where the actual implementation of OpenCL is contained.

Without closing the dialog box used above:
  • Choose ‘Linker-> General’
  • In  the ‘Additional Dependencies’ field enter the following, again this is based on your card vendor
    •  nVidia   - “$(CUDA_LIB_PATH)”
    • AMD      - “$(AMDAPPSDKROOT)\lib\x86” (for 64 bit users you may need to change the x86 to x86_64, I have no machine to test this on)

library path image
  • Still in the ‘Linker’ submenu, select ‘Input’
  • In the ‘Additional Dependencies’ field click on the arrow that appears at the end of the field and choose Edit…
  • In the dialog that appears enter “OpenCL.lib” (without the quotes obviously J)

library link image

  • Click OK in the dialog box
  • Click OK in the Properties dialog to bring you back to the main IDE
If you are a 32-bit user then your project is now set up for OpenCL (skip to the” Test Your Project” section), if you’re a 64-bit user then continue on to the next section.

5.       A Note for 64-Bit users

If you are using a 64-bit machine then you will need to add an x64 target to your project to be able to build it.
  • Again open the properties page of your project by right clicking on it and selecting ‘Properties’
  • Select ‘Configuration Manager…’ from the top right hand corner of the dialog (if it is greyed out expand ‘Configuration Properties’ on the left hand side to enable it)
  • Under ‘Active solution platforms’ select New...
  • Under ‘Type or select the new platform’ select x64 and click OK
  • Click Close
  • Click OK to get back to the main IDE


Your project should now be set up for OpenCL!! Wasn’t that a breeze ;)

6.       Testing your project

Below is the simplest OpenCL application to test that the install and configuration have worked. Copy this code into the C++ class that you created at the start of the tutorial:

Click the run button. If you get a console window that opens and then closes again, then congratulations!!! You have just taken the first step on your OpenCL/world domination journey. Happy coding guys! If I have made any errors please leave me a comment and I will correct it ASAP. 

32 comments:

  1. I followed your tutorial and got this error:
    Error 1 error C1083: Cannot open include file: 'CL/cl.h': No such file or directory c:\Users\Filip\documents\visual studio 2010\Projects\openCL1\openCL1\opencl.cpp 1 1 openCL1
    2 IntelliSense: cannot open source file "CL/cl.h" c:\users\filip\documents\visual studio 2010\projects\opencl1\opencl1\opencl.cpp 1 1 openCL1

    Do you know why the file is not recognized?

    ReplyDelete
    Replies
    1. This means that visual studio isn't finding the cl header files, try looking at the Including OpenCL in the project section again and make sure you followed all the steps correctly. Are you using an nVidia or ATI graphics card and are you sure installed the toolkit corectly?

      Delete
    2. Hey, just thought I'd let you know:
      #include
      references your search paths that are configured and
      #include "file.h"
      references a path relative to your project.

      Delete
    3. So apparently the comment system strips out the greater-than and less-than signs. Wrap file.h in a greater and less than sign (so it looks like an html tag)

      Delete
    4. If you installed the SDK and haven't restarted your computer that's why you're having this problem.

      Simply restart, so that Environment Variables can take effect.

      Delete
  2. hi i have installed VS 2010 and CUDA tool kit 4.2
    ,i did all the steps ;but when i try to crate anew project in VC++ and choose Opencl this message appears "parameter toolFile cannot be null" ; what is going wrong !!!!!!!

    ReplyDelete
  3. Thanks for making this tutorial. I followed another one but it didn't have the x64 part, so I would get errors when trying to compile.

    ReplyDelete
  4. Hello I just wanted to correct you with the x64 part.

    It has to be “$(AMDAPPSDKROOT)\lib\x86_64" iinstead of “$(AMDAPPSDKROOT)\lib\x64"

    (atleast in the current version of AMD APP SDK v2.8)

    ReplyDelete
    Replies
    1. Thanks for the correction, I appreciate it!

      Delete
  5. Hi
    I did all the steps above but this error appers to me
    q1.obj : error LNK2019: unresolved external symbol _clGetPlatformIDs@12 referenced in function _main

    1>C:\Program Files (x86)\Microsoft Visual Studio 9.0\ImportProjects\vcs\q1\Debug\q1.exe : fatal error LNK1120: 1 unresolved externals

    can any one help me

    ReplyDelete
    Replies
    1. Google is your friend here:
      I had the same problem. I thought I had to link with the 64bit library, but the way I set up my Visual Studio compiler, it was the 32 bit library that was the one to use, and then all went well.
      Explanation is here:
      http://devgurus.amd.com/thread/133986

      Delete
  6. Thanks, this worked for me for AMD x64!

    ReplyDelete
  7. I am getting following error "INK : fatal error LNK1104: cannot open file 'kernel32.lib'" What should I do in this case?

    ReplyDelete
  8. C:\Windows\System32\ntdll.dll'. Cannot find or open the PDB file.

    i am getting this error

    ReplyDelete
  9. For me in VS 2012 there was no CUDA_LIB_PATH or CUDA_INC_PATH macroses, was only CUDA_PATH, so I used $(CUDA_PATH)\lib\x64 and $(CUDA_PATH)\include respectively and it worked.

    ReplyDelete
    Replies
    1. Thx couldn't get it working without this comment!

      Delete
    2. hey thanks it was all messed up before i read your comment :) thnks

      Delete
    3. Thanks, this comment helped for VS 2010.

      Delete
  10. thank for tutorial!
    I got a problem when I run code sample

    "Unhandled exception at 0x0000000000000000 in OpenCL_Helloworld.exe: 0xC0000005: Access violation executing location 0x0000000000000000."

    ReplyDelete
  11. Hello I am a newby. After following the instructions, I got the following error, please help me.

    1>------ Build started: Project: JayTest, Configuration: Debug Win32 ------
    1>D:\OpenCLtestJay\JayTest\JayTest\JayTest.vcxproj : error MSB4014: The build stopped unexpectedly because of an internal failure.
    1>D:\OpenCLtestJay\JayTest\JayTest\JayTest.vcxproj : error MSB4014: Microsoft.Build.Exceptions.BuildAbortedException: Build was canceled. MSBuild.exe could not be launched as a child node as it could not be found at the location "C:\Windows\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe". If necessary, specify the correct location in the BuildParameters, or with the MSBUILD_EXE_PATH environment variable.
    1>D:\OpenCLtestJay\JayTest\JayTest\JayTest.vcxproj : error MSB4014: at Microsoft.Build.BackEnd.NodeManager.AttemptCreateNode(INodeProvider nodeProvider, NodeConfiguration nodeConfiguration)
    1>D:\OpenCLtestJay\JayTest\JayTest\JayTest.vcxproj : error MSB4014: at Microsoft.Build.BackEnd.NodeManager.CreateNode(NodeConfiguration configuration, NodeAffinity nodeAffinity)
    1>D:\OpenCLtestJay\JayTest\JayTest\JayTest.vcxproj : error MSB4014: at Microsoft.Build.Execution.BuildManager.PerformSchedulingActions(IEnumerable`1 responses)
    1>D:\OpenCLtestJay\JayTest\JayTest\JayTest.vcxproj : error MSB4014: at Microsoft.Build.Execution.BuildManager.HandleNewRequest(Int32 node, BuildRequestBlocker blocker)
    1>D:\OpenCLtestJay\JayTest\JayTest\JayTest.vcxproj : error MSB4014: at Microsoft.Build.Execution.BuildManager.IssueRequestToScheduler(BuildSubmission submission, Boolean allowMainThreadBuild, BuildRequestBlocker blocker)
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

    ReplyDelete
  12. Thanks so far! But, didn't get the "Linker" option in properties for cpp file. Instead put the additional details into project. Had the following two errors.

    Error 1 error LNK2019: unresolved external symbol _clGetPlatformIDs@12 referenced in function _main C:\Users\sony\documents\visual studio 2012\Projects\Parallel01\Parallel01\oicl.obj Parallel01
    Error 2 error LNK1120: 1 unresolved externals C:\Users\sony\documents\visual studio 2012\Projects\Parallel01\x64\Parallel01.exe Parallel01

    ReplyDelete
  13. In VS2010, even with the mentioned x64 setting, its still being compiled for 32 bit. So in the linker, instead of $(CUDA_PATH)\lib\x64 still use $(CUDA_PATH)\lib\Win32.

    ReplyDelete
  14. First, great tutorial! I appreciated the detail and screen-shots. I followed all the directions accept I started with an Opencl sample from AMD.

    The reason I'm writing is when I try to build the project I keep getting error message. C1083: Cannot open include file "CLUtil.hpp": No such file or directory

    I've searched the net and found no articles on how to resolve this issue. Are u familiar with this error message? If so, what can I do to complete the project to set-up and Opencl device to run guiminer?

    Here's the System info and what alternatives I already tried. GPU: AMD Athlon(tm) 64 X2 Duel Core Processor, AMD SDK 2.9, and MS Visual Studio 2012.

    1st, I tried building the project from scratch using your tutorial. At the end I was getting error message missing "CLcl/h".

    I resolved this this by changing the C/C++ Additional Include Directories to take the opencl files from the include folder at C:/program file(x86)/AMD SDK/2.9/include.

    Then Linker-> General Additional Library Directories to $(AMDAPPSDKROOT)\lib\x86_64

    Last I added Open.lib to the Input and added x64 under the Configuration Manager > Active Solutions Platform.

    Once I build the project I get error message C1083: Cannot open include file "CLUtil.hpp": No such file or directory.

    How do I fix this problem?

    ReplyDelete
  15. error LNK 1104: cannot open file 'corporation\NVIDIA.obj' i am getting this error :(

    ReplyDelete
  16. Worked great for a NVIDIA GPU on a x64 OS. Not problem at all. Thank you very much.

    ReplyDelete
  17. hey thanks it was all messed up before i read your comment :) thnks

    ReplyDelete
  18. Gaurav Khanna gkhanna@umassd.edu19 March 2014 at 21:08

    Chris, I'm interested in your MS thesis: "An OpenCL implementation of multi-precision arithmetic" .. where can get a PDF copy? Thanks very much!

    ReplyDelete
  19. Can anyone post RSA opencl code asap...or convert the below RSA code to opencl code..pls pls pls...help me out..


    #include "cuda_runtime.h"
    #include "device_launch_parameters.h"

    #include

    #include


    #include

    __device__ long long int mod(int base,int exponent,int den)
    {
    unsigned int a=(base%den)*(base%den);
    unsigned long long int ret=1;
    float size=(float)exponent/2;
    if(exponent==0)
    {
    return base%den;
    }
    else
    {
    while(1)
    {
    if(size>0.5)
    {
    ret=(ret*a)%den;
    size=size-1.0;
    }
    else if(size==0.5)
    {
    ret=(ret*(base%den))%den;
    break;
    }
    else
    {
    break;
    }
    }
    return ret;
    }
    }

    __global__ void rsa(int * num,int *key,int *den,unsigned int * result)
    {
    int i=threadIdx.x;
    int temp;

    if(i<3)
    {
    temp=mod(num[i],*key,*den);
    atomicExch(&result[i],temp);
    }
    }

    int main()
    {
    int num[3]={16,5,4};
    int key=5;
    int den=35;
    int devcount;
    cudaGetDeviceCount(&devcount);
    printf("%d CUDA devices found",devcount);

    if(devcount>0)
    {
    cudaSetDevice(1);
    printf("\nEnter the 8 digit word:");
    for(int i=0;i<3;i++)
    {
    printf("\n.");
    scanf("%d",&num[i]);
    }
    printf("\nEnter key parameter 1:");
    scanf("%d",&key);
    printf("\nEnter key parameter 2:");
    scanf("%d",&den);

    int *dev_num,*dev_key,*dev_den;
    unsigned int *dev_res;
    unsigned int res[3]={1,1,1};
    dim3 grid(1,1,1);
    dim3 block(3,3,1);

    cudaMalloc( (void **)&dev_num, 3*sizeof(int));
    cudaMalloc( (void **)&dev_key,sizeof(int));
    cudaMalloc( (void **)&dev_den, sizeof(int));
    cudaMalloc( (void **)&dev_res, 3*sizeof(unsigned int));

    cudaMemcpy(dev_num,num,3*sizeof(int),cudaMemcpyHostToDevice);
    cudaMemcpy(dev_key,&key,sizeof(int),cudaMemcpyHostToDevice);
    cudaMemcpy(dev_den,&den,sizeof(int),cudaMemcpyHostToDevice);
    cudaMemcpy(dev_res,res,3*sizeof(unsigned int),cudaMemcpyHostToDevice);
    rsa<<>>(dev_num,dev_key,dev_den,dev_res);
    cudaMemcpy(res,dev_res,3*sizeof(unsigned int),cudaMemcpyDeviceToHost);
    cudaFree(dev_num);
    cudaFree(dev_key);
    cudaFree(dev_den);
    cudaFree(dev_res);
    for(int i=0;i<3;i++)
    {
    printf("\n%d",res[i]);
    }
    }
    getch();
    return 0;
    }

    ReplyDelete
  20. I found this really helpful - thank you.

    ReplyDelete
  21. Had to create a blank .cl file under OpenCL files directory for this to work, but otherwise it was straightforward. Also, I use the Intel SDK which automatically fills in the values under the project Properties. Thanks! :)

    ReplyDelete
  22. Hello, I am new to OpenCL. I installed Intel SDK and used Visual Studio 2012 for OpenCL. Would you please give some configuration instructions regarding how to set up Visual Studio for OpenCL ? Thank you so much for your help!

    ReplyDelete