Skip to content

Commit

Permalink
working on info program
Browse files Browse the repository at this point in the history
  • Loading branch information
enjalot committed May 27, 2011
1 parent c3357ef commit 856aa43
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 89 deletions.
130 changes: 64 additions & 66 deletions info/cpp/cll.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include <stdio.h>
#include <string>
#include <cstdlib>
#include <iostream>

#include "cll.h"
#include "util.h"
Expand All @@ -9,51 +9,66 @@ CL::CL()
{
printf("Initialize OpenCL object and context\n");
//setup devices and context
cl_uint numPlatforms;
cl_platform_id platform = NULL;
status = clGetPlatformIDs(0, NULL, &numPlatforms);

//this function is defined in util.cpp
//it comes from the NVIDIA SDK example code
err = oclGetPlatformID(&platform);
///err = oclGetPlatformID(&platform);
//oclErrorString is also defined in util.cpp and comes from the NVIDIA SDK
printf("oclGetPlatformID: %s\n", oclErrorString(err));
///printf("oclGetPlatformID: %s\n", oclErrorString(err));
std::vector<cl::Platform> platforms;
err = cl::Platform::get(&platforms);
printf("cl::Platform::get(): %s\n", oclErrorString(err));
printf("number of platforms: %d\n", platforms.size());
if (platforms.size() == 0) {
printf("Platform size 0\n");
}


// Get the number of GPU devices available to the platform
// we should probably expose the device type to the user
// the other common option is CL_DEVICE_TYPE_CPU
err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices);
printf("clGetDeviceIDs (get number of devices): %s\n", oclErrorString(err));
///err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices);
///printf("clGetDeviceIDs (get number of devices): %s\n", oclErrorString(err));


// Create the device list
devices = new cl_device_id [numDevices];
err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numDevices, devices, NULL);
printf("clGetDeviceIDs (create device list): %s\n", oclErrorString(err));
///devices = new cl_device_id [numDevices];
///err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numDevices, devices, NULL);
///printf("clGetDeviceIDs (create device list): %s\n", oclErrorString(err));

//create the context
context = clCreateContext(0, 1, devices, NULL, NULL, &err);

//for right now we just use the first available device
//later you may have criteria (such as support for different extensions)
//that you want to use to select the device
deviceUsed = 0;
//create the context
///context = clCreateContext(0, 1, &devices[deviceUsed], NULL, NULL, &err);
//context properties will be important later, for now we go with defualts
cl_context_properties properties[] =
{ CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms[0])(), 0};

context = cl::Context(CL_DEVICE_TYPE_GPU, properties);
devices = context.getInfo<CL_CONTEXT_DEVICES>();
printf("number of devices %d\n", devices.size());

//create the command queue we will use to execute OpenCL commands
command_queue = clCreateCommandQueue(context, devices[deviceUsed], 0, &err);
///command_queue = clCreateCommandQueue(context, devices[deviceUsed], 0, &err);
try{
queue = cl::CommandQueue(context, devices[deviceUsed], 0, &err);
}
catch (cl::Error er) {
printf("ERROR: %s(%d)\n", er.what(), er.err());
}

cl_a = 0;
cl_b = 0;
cl_c = 0;
}

CL::~CL()
{
/*
printf("Releasing OpenCL memory\n");
if(kernel)clReleaseKernel(kernel);
if(program)clReleaseProgram(program);
if(command_queue)clReleaseCommandQueue(command_queue);

//need to release any other OpenCL memory objects here
if(cl_a)clReleaseMemObject(cl_a);
if(cl_b)clReleaseMemObject(cl_b);
Expand All @@ -63,61 +78,44 @@ CL::~CL()
if(devices)delete(devices);
printf("OpenCL memory released\n");
*/
}


void CL::loadProgram(const char* relative_path)
void CL::loadProgram(std::string kernel_source)
{
// Program Setup
//Program Setup
int pl;
size_t program_length;
//size_t program_length;
printf("load the program\n");

//CL_SOURCE_DIR is set in the CMakeLists.txt
std::string path(CL_SOURCE_DIR);
path += "/" + std::string(relative_path);
printf("path: %s\n", path.c_str());

//file_contents is defined in util.cpp
//it loads the contents of the file at the given path
char* cSourceCL = file_contents(path.c_str(), &pl);
//printf("file: %s\n", cSourceCL);
program_length = (size_t)pl;

// create the program
program = clCreateProgramWithSource(context, 1,
(const char **) &cSourceCL, &program_length, &err);
printf("clCreateProgramWithSource: %s\n", oclErrorString(err));

buildExecutable();

//Free buffer returned by file_contents
free(cSourceCL);
}

//----------------------------------------------------------------------
void CL::buildExecutable()
{
// Build the program executable

printf("building the program\n");
// build the program
//err = clBuildProgram(program, 0, NULL, "-cl-nv-verbose", NULL, NULL);
err = clBuildProgram(program, 0, NULL, NULL, NULL, NULL);
printf("clBuildProgram: %s\n", oclErrorString(err));
//if(err != CL_SUCCESS){
cl_build_status build_status;
err = clGetProgramBuildInfo(program, devices[deviceUsed], CL_PROGRAM_BUILD_STATUS, sizeof(cl_build_status), &build_status, NULL);

char *build_log;
size_t ret_val_size;
err = clGetProgramBuildInfo(program, devices[deviceUsed], CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size);
pl = kernel_source.size();
printf("kernel size: %d\n", pl);
//printf("kernel: \n %s\n", kernel_source.c_str());
try
{
cl::Program::Sources source(1,
std::make_pair(kernel_source.c_str(), pl));
program = cl::Program(context, source);
}
catch (cl::Error er) {
printf("ERROR: %s(%s)\n", er.what(), oclErrorString(er.err()));
}

printf("build program\n");
try
{
err = program.build(devices);
}
catch (cl::Error er) {
printf("program.build: %s\n", oclErrorString(er.err()));
//if(err != CL_SUCCESS){
}
printf("done building program\n");
std::cout << "Build Status: " << program.getBuildInfo<CL_PROGRAM_BUILD_STATUS>(devices[0]) << std::endl;
std::cout << "Build Options:\t" << program.getBuildInfo<CL_PROGRAM_BUILD_OPTIONS>(devices[0]) << std::endl;
std::cout << "Build Log:\t " << program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(devices[0]) << std::endl;

build_log = new char[ret_val_size+1];
err = clGetProgramBuildInfo(program, devices[deviceUsed], CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL);
build_log[ret_val_size] = '\0';
printf("BUILD LOG: \n %s", build_log);
//}
printf("program built\n");
}

48 changes: 28 additions & 20 deletions info/cpp/cll.h
Original file line number Diff line number Diff line change
@@ -1,32 +1,34 @@
#ifndef ADVCL_CLL_H_INCLUDED
#define ADVCL_CLL_H_INCLUDED

#if defined __APPLE__ || defined(MACOSX)
#include <OpenCL/opencl.h>
#else
#include <CL/opencl.h>
#endif
#define __CL_ENABLE_EXCEPTIONS

#include <vector>
#include "CL/cl.hpp"

class CL {
public:

//These are arrays we will use in this tutorial
cl_mem cl_a;
cl_mem cl_b;
cl_mem cl_c;
///cl_mem cl_a;
///cl_mem cl_b;
///cl_mem cl_c;
cl::Buffer cl_a;
cl::Buffer cl_b;
cl::Buffer cl_c;
int num; //the size of our arrays


size_t workGroupSize[1]; //N dimensional array of workgroup size we must pass to the kernel
//size_t workGroupSize[1]; //N dimensional array of workgroup size we must pass to the kernel

//default constructor initializes OpenCL context and automatically chooses platform and device
CL();
//default destructor releases OpenCL objects and frees device memory
~CL();

//load an OpenCL program from a file
//the path is relative to the CL_SOURCE_DIR set in CMakeLists.txt
void loadProgram(const char* relative_path);
//pass in the kernel source code as a string. handy way to get this from STRINGIFY macro in part1.cl
void loadProgram(std::string kernel_source);

//setup the data for the kernel
//these are implemented in part1.cpp (in the future we will make these more general)
Expand All @@ -37,27 +39,33 @@ class CL {
private:

//handles for creating an opencl context
cl_platform_id platform;
//cl_platform_id platform;

//device variables
cl_device_id* devices;
cl_uint numDevices;
//cl_device_id* devices;
//cl_uint numDevices;
unsigned int deviceUsed;
std::vector<cl::Device> devices;

cl_context context;
//cl_context context;
cl::Context context;

cl_command_queue command_queue;
cl_program program;
cl_kernel kernel;
//cl_command_queue command_queue;
cl::CommandQueue queue;
//cl_program program;
cl::Program program;
//cl_kernel kernel;
cl::Kernel kernel;


//debugging variables
cl_int err;
cl_event event;
///cl_event event;
cl::Event event;

//buildExecutable is called by loadProgram
//build runtime executable from a program
void buildExecutable();
//void buildExecutable();
};

#endif
42 changes: 39 additions & 3 deletions info/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,65 @@ using namespace std;

//Globally define all of our CL instances for convenience
vector<cl::Platform> platforms;

vector<cl::Context> contexts;

int main(int argc, char** argv)
{
printf("Hello, OpenCL\n");

/*
* Get available platforms and display relevant information
*/
try
{
//Get the available platforms on this machine
cl::Error err = cl::Platform::get(&platforms);
}
catch (cl::Error er) { printf("ERROR: %s (%s)\n", er.what(), oclErrorString(er.err())); }

printf("Number of platforms: %d\n", platforms.size());
printf("Number of platforms: %zd\n", platforms.size());
//Print out some information about each of the platforms
for(int i = 0; i < platforms.size(); i++)
{
string platform_name = platforms[i].getInfo<CL_PLATFORM_NAME>();
string platform_vendor = platforms[i].getInfo<CL_PLATFORM_VENDOR>();
string platform_extensions = platforms[i].getInfo<CL_PLATFORM_EXTENSIONS>();
printf("Platform %d: %s by %s\n with extensions:\n %s", i, platform_name.c_str(),
printf("Platform %d: %s by %s\n with extensions: %s\n", i, platform_name.c_str(),
platform_vendor.c_str(),
platform_extensions.c_str());


/*
* Get the Devices available on this platform and print out information about them
*/
vector<cl::Device> devices;
platforms[i].getDevices(CL_DEVICE_TYPE_ALL, &devices);
printf("Number of devices: %zd\n", devices.size());
for(int j = 0; j < devices.size(); j++)
{
cl::Device d = devices[j];
printf("====== Device %d ======\n", j);
printf("Type: %s\n", GetCLPropertyString(d.getInfo<CL_DEVICE_TYPE>()) );
printf("Name: %s\n", d.getInfo<CL_DEVICE_NAME>().c_str() );

//Number of parallel compute cores on the device
printf("Max Compute Units: %d\n", d.getInfo<CL_DEVICE_MAX_COMPUTE_UNITS>() );
//Maximum dimensions that specify the global and local work-item
//IDs used by the data parallel execution model
printf("Max Dimensions: %d\n", d.getInfo<CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS>() );
printf("======================\n");
}


//This is the most basic set of properties supported by the standard
//(specifying the platform) When doing OpenGL context sharing the
//OpenGL context is passed in as a property (technically this is an
//extension by the implementation)
cl_context_properties properties[] =
{ CL_CONTEXT_PLATFORM, (cl_context_properties)(platforms[i])(), 0};

cl::Context context = cl::Context(CL_DEVICE_TYPE_ALL, properties);

}


Expand Down
22 changes: 22 additions & 0 deletions info/cpp/util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,28 @@ char *file_contents(const char *filename, int *length)
return (char*)buffer;
}

//Some hacked together stuff to print out nice names for OpenCL enums
//filling it in as I go so it wont have all of them
const char* GetCLPropertyString(int prop)
{
switch(prop)
{
case(CL_DEVICE_TYPE_CPU):
return "CPU";
break;
case(CL_DEVICE_TYPE_GPU):
return "GPU";
break;
case(CL_DEVICE_TYPE_ACCELERATOR):
return "ACCELERATOR";
break;
case(CL_DEVICE_TYPE_DEFAULT):
return "DEFAULT";
break;


}
}


//NVIDIA's code follows
Expand Down
1 change: 1 addition & 0 deletions info/cpp/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ char *file_contents(const char *filename, int *length);
cl_int oclGetPlatformID(cl_platform_id* clSelectedPlatformID);
const char* oclErrorString(cl_int error);

const char* GetCLPropertyString(int prop);

#endif

0 comments on commit 856aa43

Please sign in to comment.