Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
mitkOclFilter.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 //Ocl
18 #include "mitkOclFilter.h"
19 #include "mitkOclUtils.h"
20 #include "mitkOpenCLActivator.h"
21 
22 //Mitk
23 #include <mitkLogMacros.h>
24 #include <mitkConfig.h>
25 
26 //usService
27 #include "usServiceReference.h"
28 #include <usServiceRegistration.h>
29 #include <usModuleContext.h>
30 #include <usGetModuleContext.h>
31 #include <usModule.h>
32 #include <usModuleResource.h>
33 #include <usModuleResourceStream.h>
34 
36  : m_ClCompilerFlags(""),
37  m_ClProgram(NULL),
38  m_CommandQue(NULL),
39  m_FilterID("mitkOclFilter"),
40  m_Preambel(" "),
41  m_Initialized(false)
42 {
43 }
44 
46  : m_ClCompilerFlags(""),
47  m_ClProgram(NULL),
48  m_CommandQue(NULL),
49  m_FilterID(filename),
50  m_Preambel(" "),
51  m_Initialized(false)
52 {
53  m_ClFiles.push_back(filename);
54 }
55 
57 {
58  MITK_DEBUG << "OclFilter Destructor";
59 
60  // release program
61  if (m_ClProgram)
62  {
65 
66  // remove program from storage
67  resources->RemoveProgram(m_FilterID);
68  }
69 }
70 
71 bool mitk::OclFilter::ExecuteKernel( cl_kernel kernel, unsigned int workSizeDim )
72 {
73  cl_int clErr = 0;
74 
75  clErr = clEnqueueNDRangeKernel( this->m_CommandQue, kernel, workSizeDim,
76  NULL, this->m_GlobalWorkSize, m_LocalWorkSize, 0, NULL, NULL);
77 
78  CHECK_OCL_ERR( clErr );
79 
80  return ( clErr == CL_SUCCESS );
81 }
82 
83 
85 {
88 
89  m_CommandQue = resources->GetCommandQueue();
90 
91  cl_int clErr = 0;
92  m_Initialized = CHECK_OCL_ERR(clErr);
93 
94  if ( m_ClFiles.empty())
95  {
96  MITK_ERROR<<"No OpenCL Source FILE specified";
97  return false;
98  }
99 
100  if (m_ClProgram == NULL)
101  {
102  try
103  {
104  this->m_ClProgram = resources->GetProgram( this->m_FilterID );
105  }
106  catch(const mitk::Exception& e)
107  {
108  MITK_INFO << "Program not stored in resource manager, compiling.";
109  this->CompileSource();
110  }
111  }
112 
113  return m_Initialized;
114 }
115 
116 void mitk::OclFilter::LoadSourceFiles(CStringList &sourceCode, ClSizeList &sourceCodeSize)
117 {
118  for( CStringList::iterator it = m_ClFiles.begin(); it != m_ClFiles.end(); ++it )
119  {
120  MITK_DEBUG << "Load file :" << *it;
121  us::ModuleResource mdr = GetModule()->GetResource(*it);
122 
123  if( !mdr.IsValid() )
124  MITK_WARN << "Could not load resource: " << mdr.GetName() << " is invalid!";
125 
126  us:ModuleResourceStream rss(mdr);
127 
128  // read resource file to a string
129  std::istreambuf_iterator<char> eos;
130  std::string source(std::istreambuf_iterator<char>(rss), eos);
131 
132  // add preambel and build up string to compile
133  std::string src(m_Preambel);
134  src.append("\n");
135  src.append(source);
136 
137  // allocate new char buffer
138  char* tmp = new char[src.size() + 1];
139  strcpy(tmp,src.c_str());
140 
141  // add source to list
142  sourceCode.push_back((const char*)tmp);
143  sourceCodeSize.push_back(src.size());
144  }
145 }
146 
148 {
149  // helper variable
150  int clErr = 0;
151  CStringList sourceCode;
152  ClSizeList sourceCodeSize;
153 
154  if (m_ClFiles.empty())
155  {
156  MITK_ERROR("ocl.filter") << "No shader source file was set";
157  return;
158  }
159 
160  //get a valid opencl context
163 
164  cl_context gpuContext = resources->GetContext();
165  // load the program source from file
166  LoadSourceFiles(sourceCode, sourceCodeSize);
167 
168  if ( !sourceCode.empty() )
169  {
170  // create program from all files in the file list
171  m_ClProgram = clCreateProgramWithSource(gpuContext, sourceCode.size(), &sourceCode[0], &sourceCodeSize[0], &clErr);
172  CHECK_OCL_ERR(clErr);
173 
174  // build the source code
175  MITK_DEBUG << "Building Program Source";
176  std::string compilerOptions = "";
177  compilerOptions.append(m_ClCompilerFlags);
178 
179  MITK_DEBUG("ocl.filter") << "cl compiler flags: " << compilerOptions.c_str();
180 
181  clErr = clBuildProgram(m_ClProgram, 0, NULL, compilerOptions.c_str(), NULL, NULL);
182  CHECK_OCL_ERR(clErr);
183 
184  // if OpenCL Source build failed
185  if (clErr != CL_SUCCESS)
186  {
187  MITK_ERROR("ocl.filter") << "Failed to build source";
188  oclLogBuildInfo(m_ClProgram, resources->GetCurrentDevice() );
189  oclLogBinary(m_ClProgram, resources->GetCurrentDevice() );
190  m_Initialized = false;
191  }
192 
193  // store the succesfully build program into the program storage provided by the resource service
194  resources->InsertProgram(m_ClProgram, m_FilterID, true);
195 
196  // free the char buffers with the source code
197  for( CStringList::iterator it = sourceCode.begin(); it != sourceCode.end(); ++it )
198  {
199  delete[] *it;
200  }
201  }
202  else
203  {
204  MITK_ERROR("ocl.filter") << "Could not load from source";
205  m_Initialized = false;
206  }
207 }
208 
209 void mitk::OclFilter::SetWorkingSize(unsigned int locx, unsigned int dimx, unsigned int locy, unsigned int dimy, unsigned int locz, unsigned int dimz)
210 {
211  // set the local work size
212  this->m_LocalWorkSize[0] = locx;
213  this->m_LocalWorkSize[1] = locy;
214  this->m_LocalWorkSize[2] = locz;
215 
216  this->m_GlobalWorkSize[0] = dimx;
217  this->m_GlobalWorkSize[1] = dimy;
218  this->m_GlobalWorkSize[2] = dimz;
219 
220  // estimate the global work size
221  this->m_GlobalWorkSize[0] = iDivUp( dimx, this->m_LocalWorkSize[0]) * this->m_LocalWorkSize[0];
222 
223  if ( dimy > 1)
224  this->m_GlobalWorkSize[1] = iDivUp( dimy, this->m_LocalWorkSize[1]) * this->m_LocalWorkSize[1];
225  if( dimz > 1 )
226  this->m_GlobalWorkSize[2] = iDivUp( dimz, this->m_LocalWorkSize[2]) * this->m_LocalWorkSize[2];
227 }
228 
229 void mitk::OclFilter::SetSourcePreambel(const char* preambel)
230 {
231  this->m_Preambel = preambel;
232 }
233 
235 {
236  m_ClFiles.push_back(filename);
237 }
238 
239 void mitk::OclFilter::SetCompilerFlags(const char* flags)
240 {
241  m_ClCompilerFlags = flags;
242 }
243 
244 
246 {
247  return m_Initialized;
248 }
#define CHECK_OCL_ERR(_er)
Definition: mitkOclUtils.h:25
unsigned int iDivUp(unsigned int dividend, unsigned int divisor)
Method to estimate an integer quotient C from given dividend and divisor higher or equal to the corre...
ServiceReferenceU GetServiceReference(const std::string &clazz)
virtual cl_command_queue GetCommandQueue() const =0
Returns a valid cl_command_queue related to the (one) OpenCL context.
OclFilter()
Constructor.
#define MITK_INFO
Definition: mitkLogMacros.h:22
void SetSourcePreambel(const char *preambel)
Add some source code on the beginning of the loaded source.
#define MITK_ERROR
Definition: mitkLogMacros.h:24
std::string GetName() const
bool Initialize()
Initialize all necessary parts of the filter.
#define MITK_DEBUG
Definition: mitkLogMacros.h:26
void oclLogBinary(cl_program clProg, cl_device_id clDev)
Logs the GPU Program binary code.
void CompileSource()
Compile the program source.
virtual bool IsInitialized()
Returns true if the initialization was successfull.
std::vector< const char * > CStringList
Definition: mitkOclFilter.h:66
void * GetService(const ServiceReferenceBase &reference)
virtual ~OclFilter()
Destructor.
#define MITK_WARN
Definition: mitkLogMacros.h:23
An object of this class represents an exception of MITK. Please don't instantiate exceptions manually...
Definition: mitkException.h:49
static const std::string filename
std::vector< vcl_size_t > ClSizeList
Definition: mitkOclFilter.h:67
CStringList m_ClFiles
List of sourcefiles that will be compiled for this filter.
Definition: mitkOclFilter.h:91
void oclLogBuildInfo(cl_program clProg, cl_device_id clDev)
Shows the OpenCL-Program build info, called if clBuildProgram != CL_SUCCES.
virtual void RemoveProgram(const std::string &name)=0
Remove given program from storage.
void SetCompilerFlags(const char *flags)
Set specific compilerflags to compile the CL source. Default is set to NULL; example: "-cl-fast-relax...
virtual cl_context GetContext() const =0
Returns a valid OpenCL Context (if applicable) or NULL if none present.
void SetWorkingSize(unsigned int locx, unsigned int dimx, unsigned int locy=1, unsigned int dimy=1, unsigned int locz=1, unsigned int dimz=1)
Set the working size for the following OpenCL kernel call.
bool ExecuteKernel(cl_kernel kernel, unsigned int workSizeDim)
Execute the given kernel on the OpenCL Index-Space defined by the local and global work sizes...
void LoadSourceFiles(CStringList &SourceCodeList, ClSizeList &SourceCodeSizeList)
Helper functions that load sourcefiles from the module context in the Initialize function.
static ModuleContext * GetModuleContext()
Returns the module context of the calling module.
void AddSourceFile(const char *filename)
Add a source file from the resource files to the OpenCL shader file list. Multiple files can be added...
Declaration of the OpenCL Resources micro-service.