{"id":218,"date":"2011-09-28T20:16:36","date_gmt":"2011-09-28T20:16:36","guid":{"rendered":"http:\/\/41j.com\/blog\/?p=218"},"modified":"2011-09-28T20:16:36","modified_gmt":"2011-09-28T20:16:36","slug":"simple-opencl-example","status":"publish","type":"post","link":"https:\/\/41j.com\/blog\/2011\/09\/simple-opencl-example\/","title":{"rendered":"Simple OpenCL example"},"content":{"rendered":"<p>Adapted from here: http:\/\/developer.amd.com\/GPU\/ATISTREAMSDK\/pages\/TutorialOpenCL.aspx<\/p>\n<p>But tidied up a little and made to work on MacOS. It creates a OpenCL executor &#8220;thing&#8221; and tells it to run a kernel which writes &#8220;Hello World&#8221; to a buffer, this gets sent back to the main C++ program.<\/p>\n<p>#include &#8220;cl.hpp&#8221;<br \/>\n#include <iostream><br \/>\n#include <string><\/p>\n<p>std::string prog(<br \/>\n&#8220;#pragma OPENCL EXTENSION cl_khr_byte_addressable_store : enable\\n&#8221; \\<br \/>\n&#8220;__constant char hw[] = \\&#8221;Hello World\\&#8221;; \\n&#8221; \\<br \/>\n&#8220;__kernel void hello(__global char * out) {\\n&#8221; \\<br \/>\n&#8221;  size_t tid = get_global_id(0); \\n&#8221; \\<br \/>\n&#8221;  out[tid] = hw[tid]; \\n&#8221; \\<br \/>\n&#8220;}\\n&#8221;);<\/p>\n<p>int main(void) {<br \/>\n cl_int err;<\/p>\n<p> \/\/ Get list of platforms (things that can execute OpenCL on this host), get a &#8220;context&#8221; on the first executor.<br \/>\n std::vector<cl::Platform> platformList;<br \/>\n cl::Platform::get(&amp;amp;amp;platformList);<br \/>\n cl_context_properties cprops[3] = {CL_CONTEXT_PLATFORM, (cl_context_properties)(platformList[0])(), 0};<br \/>\n cl::Context context( CL_DEVICE_TYPE_CPU, cprops, NULL, NULL, &amp;amp;amp;err);<\/p>\n<p> \/\/ Allocate 100 bytes of memory which we will use to communicate with the OpenCL context, executor, whatever.<br \/>\n size_t mem_size = 100;<br \/>\n char * outH = new char[mem_size];<br \/>\n cl::Buffer outCL( context, CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR, mem_size, outH, &amp;amp;amp;err);<\/p>\n<p> \/\/ Give the OpenCL program embedded in the string above to OpenCL.<br \/>\n cl::Program::Sources source(1, std::make_pair(prog.c_str(), prog.length()+1));<\/p>\n<p> \/\/ Get devices used in this &#8220;context&#8221;<br \/>\n std::vector<cl::Device> devices;<br \/>\n devices = context.getInfo<CL_CONTEXT_DEVICES>();<\/p>\n<p> \/\/ Compile program against device<br \/>\n cl::Program program(context, source);<br \/>\n err = program.build(devices,&#8221;&#8221;);<\/p>\n<p> \/\/ create a kernel object, tell it we are using the kernel called &#8220;hello&#8221;, give it an argument which is the memory we alloc&#8217;d above.<br \/>\n cl::Kernel kernel(program, &#8220;hello&#8221;, &amp;amp;amp;err);<br \/>\n err = kernel.setArg(0, outCL);<\/p>\n<p> \/\/ Queue the kernel up to run<br \/>\n cl::CommandQueue queue(context, devices[0], 0, &amp;amp;amp;err);<br \/>\n cl::Event event;<br \/>\n err = queue.enqueueNDRangeKernel( kernel, cl::NullRange, cl::NDRange(mem_size), cl::NDRange(1, 1), NULL, &amp;amp;amp;event);<\/p>\n<p> \/\/ Use the event object above to block until processing has completed<br \/>\n event.wait();<\/p>\n<p> \/\/ Read the results out of the shared memory area.<br \/>\n err = queue.enqueueReadBuffer( outCL, CL_TRUE, 0, mem_size, outH);<\/p>\n<p> \/\/ Write to screen<br \/>\n std::cout << outH;\n}\n[\/sourcecode]\n\nOn MacOS compile it with: g++ .\/simple.cpp -framework OpenCL -o simple\n\nYou'll also need to C++ bindings for OpenCL which are available here: http:\/\/www.khronos.org\/registry\/cl\/api\/1.0\/cl.hpp\n\nTarball containing all this is <a href='http:\/\/41j.com\/blog\/wp-content\/uploads\/2011\/09\/Simple.tar.gz'>HERE<\/a> untar it and type make to build.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Adapted from here: http:\/\/developer.amd.com\/GPU\/ATISTREAMSDK\/pages\/TutorialOpenCL.aspx But tidied up a little and made to work on MacOS. It creates a OpenCL executor &#8220;thing&#8221; and tells it to run a kernel which writes &#8220;Hello World&#8221; to a buffer, this gets sent back to the main C++ program. #include &#8220;cl.hpp&#8221; #include #include std::string prog( &#8220;#pragma OPENCL EXTENSION cl_khr_byte_addressable_store : [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[1],"tags":[],"class_list":["post-218","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/p1RRoU-3w","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/218","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/comments?post=218"}],"version-history":[{"count":4,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/218\/revisions"}],"predecessor-version":[{"id":229,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/posts\/218\/revisions\/229"}],"wp:attachment":[{"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/media?parent=218"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/categories?post=218"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/41j.com\/blog\/wp-json\/wp\/v2\/tags?post=218"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}