Contents
See also: CUDADevelopersGuide
Detection of OpenCL
If an application is built and linked against OpenCL then it is expected that it will run on a machine which has an OpenCL implementation installed. A typical application should create a GPU context on hosts containing an OpenCL-capable GPU and/or a CPU context on hosts with CPU-only support. The ATI Stream SDK can be used to provide a CPU-only implementation on Linux-hosts containing just an AMD or Intel CPU. The implementation will parallelize on a CPU context across the available processors. If an ATI OpenCL-compatible GPU is present, then the application can also request a GPU context and run on the GPU(s) (or GPU+CPU combination). On a machine containing an Nvidia GPU, the Nvidia OpenCL driver should be installed. Finally, on Mac OS X Snow Leopard, the OS itself provides an implementation which provides minimally a CPU context and also a GPU context for OpenCL-capable ATI or Nvidia GPUs.
The opencl_algorithms library contains an implementation of Dijkstra's Single Source Shortest Path algorithm (used by mris_pmake) and demonstrates how to write an algorithm which will run on CPU-only, GPU-only, CPU+GPU, or multi-GPU.
Changes to enable OpenCL during configuration ( configure.in )
This section gives an overview of how configure.in is changed and what stuff it exports. More often than not, one need not tamper with configure.in -- it is already changed to accommodate OpenCL.
* OpenCL support is enabled by using a --with-opencl=<path of cuda>. This should be the path to either the ATI Stream SDK or Nvidia OpenCL root. On Mac OS X, configure.in will automatically look in the appropriate Mac OS X Snow Leopard System directories for the headers and framework. The ./configure exports certain things which are helpful in compiling OpenCL programs ( and which are to be used in Makefile.am )
Flags which configure.in exports
These flags are typically used in the Makefile.am of any binary which has a CUDA replacement.
OPENCL_CFLAGS : This variable contains the include path of OpenCL header files. (eg. OPENCL_CFLAGS="-I<opencl_include_dir>" )
OPENCL_LIBS : This variable contains the OpenCL libraries to link against (eg. OPENCL_LIBS="-L<opencl_lib_dir> -lOpenCL" )
BUILDOPENCL : This important variable is exported as AM_CONDITIONAL. If configure finds OpenCL, it sets this flag and any Makefile.am can test this flag and if it exists, compile OpenCL specific stuff. This is illustrated in the next section.
FS_CUDA : This is defined and will be placed on config.h if OpenCL is found. Example usage would be:
#ifdef FS_OPENCL
// We have implemented various flavors of the Dijkstra algorithm that runs
// with OpenCL using either CPU-only, GPU+CPU, Multi GPU, or Multi GPU + CPU.
// Based on what set of devices is available, this function will choose which
// implementation to use. This version of Dijkstra selects which devices to use
// automatically.
// If compiled with OpenCL support, run the OpenCL version of the
// algorithm
runDijkstraOpenCL(&graph, &sourceVertices, results, 1);
#else
// If not compiled with OpenCL, run the reference version of the
// algorithm
runDijkstraRef(&graph, &sourceVertices, results, 1);
#endif
Tweaking Makefile.am of the binary
Listing of Makefile.am of mris_pmake to illustrate how Makefile.am changes:
bin_PROGRAMS = mris_pmake
mris_pmake_SOURCES = \
abs2rel.c \
asynch.cpp \
c_label.cpp \
C_mpmProg.cpp \
c_SMessage.cpp \
c_SSocket.cpp \
c_surface.cpp \
c_vertex.cpp \
dijkstra.cpp \
env.cpp \
general.cpp \
help.cpp \
mris_pmake.cpp \
rel2abs.c \
scanopt.cpp \
surface.cpp
AM_CFLAGS=-I$(top_srcdir)/include
AM_CXXFLAGS=-I$(top_srcdir)/include -I../opencl_algorithms/
mris_pmake_LDFLAGS = $(OS_LDFLAGS)
if BUILDOPENCL # Include OpenCL version of algorithms
mris_pmake_LDADD = $(addprefix $(top_builddir)/, $(LIBS_MGH)) ../opencl_algorithms/libopencl_algorithms.a $(OPENCL_LIBS)
else # No OpenCL present
mris_pmake_LDADD = $(addprefix $(top_builddir)/, $(LIBS_MGH)) ../opencl_algorithms/libopencl_algorithms.a
endif
EXTRA_DIST=asynch.h c_label.h C_mpmProg.h c_SMessage.h c_SSocket.h \
c_surface.h c_vertex.h dijkstra.h env.h general.h help.h pathconvert.h \
pstream.h scanopt.h surface.h
# Our release target. Include files to be excluded here. They will be
# found and removed after 'make install' is run during the 'make
# release' target.
EXCLUDE_FILES=
include $(top_srcdir)/Makefile.extraAs one can notice, the Makefile.am of a OpenCL enabled code differs from normal Makefile.am only in the if BUILDOPENCL.. endif block.
Notes :
OpenCL support is to be enclosed in if BUILDCUDA.. endif block ( which is exported by configure.in if it finds OpenCL)
- The only difference is the need to link against $(OPENCL_LIBS)
Attribution
A lot of the code in oclCommon.cpp was derived from the NVIDIA GPU Computing SDK.
