File: itkOpenCLMemoryObject.h

package info (click to toggle)
elastix 5.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 42,480 kB
  • sloc: cpp: 68,403; lisp: 4,118; python: 1,013; xml: 182; sh: 177; makefile: 33
file content (253 lines) | stat: -rw-r--r-- 8,770 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
/*=========================================================================
 *
 *  Copyright UMC Utrecht and contributors
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0.txt
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
 *=========================================================================*/
#ifndef itkOpenCLMemoryObject_h
#define itkOpenCLMemoryObject_h

#include "itkOpenCLEventList.h"
#include "itkOpenCLSize.h"
#include "itkPoint.h"

namespace itk
{
/** \class OpenCLMemoryObject
 * \brief The OpenCLMemoryObject class represents all common memory objects
 * such as buffers and image objects.
 *
 * \ingroup OpenCL
 * \sa OpenCLContext
 */

// Forward declaration
class OpenCLContext;

class ITKOpenCL_EXPORT OpenCLMemoryObject
{
protected:
  /** Constructs a null OpenCL memory object and associates it with \a context. */
  OpenCLMemoryObject(OpenCLContext * context = 0)
    : m_Context(context)
    , m_Id(0)
  {}

  /** Constructs an OpenCL memory object from the native identifier \a id,
   * and associates it with \a context. This class takes over ownership
   * of \a id and will release it in the destructor. */
  OpenCLMemoryObject(OpenCLContext * context, const cl_mem id)
    : m_Context(context)
    , m_Id(id)
  {}

  /** Destructor for OpenCL memory object. After the memory object reference count
   * becomes zero and commands queued for execution on a command-queue(s) that
   * use memory object have finished, the memory object is deleted.
   * If memory object is a buffer object, memory object cannot be deleted until
   * all sub-buffer objects associated with memory object are deleted. */
  ~OpenCLMemoryObject();

public:
  /** Standard class typedefs. */
  using Self = OpenCLMemoryObject;
  using RectangleType = Size<4>;
  using PointType = Point<std::size_t, 2>;
  using SizeType = Size<2>;

  /** \enum OpenCLMemoryObject::Access
   * This enum defines the access mode to the OpenCL memory objects.
   * \value ReadWrite This flag specifies that the memory object will be read
   *  and written by a kernel. This is the default.
   *
   * \value WriteOnly This flags specifies that the memory object will be written
   *   but not read by a kernel.
   * \note Reading from a buffer or image object created with WriteOnly inside
   *   a kernel is undefined.
   * \note ReadWrite and WriteOnly are mutually exclusive.
   *
   * \value ReadOnly This flag specifies that the memory object is a read-only
   * memory object when used inside a kernel.
   * \note Writing to a buffer or image object created with ReadOnly inside a
   * kernel is undefined.
   * \note ReadWrite or WriteOnly and ReadOnly are mutually exclusive.
   */
  enum Access
  {
    ReadWrite = 0x0001,
    WriteOnly = 0x0002,
    ReadOnly = 0x0004
  };

  /** Returns true if this OpenCL memory object is null, false otherwise. */
  bool
  IsNull() const
  {
    return this->m_Id == 0;
  }

  /** Returns the native OpenCL identifier for this memory object. */
  cl_mem
  GetMemoryId() const
  {
    return this->m_Id;
  }

  /** Returns the OpenCL context that created this memory object. */
  OpenCLContext *
  GetContext() const
  {
    return this->m_Context;
  }

  /** Returns the memory object type used to create this object. */
  cl_mem_object_type
  GetMemoryType() const;

  /** Returns the access flags that were used to create this memory object. */
  cl_mem_flags
  GetFlags() const;

  /** Returns actual size of the data store associated with memory object in bytes. */
  std::size_t
  GetSize() const;

  /** Return the host pointer argument value specified when memory object is created.
   * Otherwise a NULL value is returned. */
  void *
  GetHostPointer() const;

  /** Returns map count. The map count returned should be considered immediately stale.
   * It is unsuitable for general use in applications. This feature is provided
   * for debugging. */
  cl_uint
  GetMapCount() const;

  /** Returns memory object reference count. The reference count returned should
   * be considered immediately stale. It is unsuitable for general use in
   * applications. This feature is provided for identifying memory leaks. */
  cl_uint
  GetReferenceCount() const;

  /** Returns the access mode that was used to create this memory object. */
  OpenCLMemoryObject::Access
  GetAccess() const;

  /** Requests a command to unmap a previously mapped region at \a ptr of a memory object.
   * This function will wait until the request has finished if the \a wait is true.
   * The request is executed on the active command queue for context.
   * \sa UnmapAsync(), OpenCLBuffer::Map() */
  void
  Unmap(void * ptr, const bool wait = false);

  /** Requests a command to unmap a previously mapped region at \a ptr of a memory object.
   * The request will be started after all events in \a event_list are finished.
   * Returns an event object that can be used to wait for the request to finish.
   * The request is executed on the active command queue for context().
   * \sa Unmap(), OpenCLBuffer::MapAsync() */
  OpenCLEvent
  UnmapAsync(void * ptr, const OpenCLEventList & event_list = OpenCLEventList());

  /** Registers a user callback function with a memory object.
   * Each call to \c{clSetMemObjectDestructorCallback} registers the specified
   * user callback function on a callback stack associated with memobj.
   * The registered user callback functions are called in the reverse order in
   * which they were registered. The user callback functions are called and then
   * the memory objects resources are freed and the memory object is deleted.
   * This provides a mechanism for the application (and libraries) using memobj
   * to be notified when the memory referenced by host_ptr, specified when the
   * memory object is created and used as the storage bits for the memory
   * object, can be reused or freed. */
  cl_int
  SetDestructorCallback(void(CL_CALLBACK * pfn_notify)(cl_mem, void *), void * user_data = nullptr);

protected:
  /** Helper function to pass cl_mem \a id. */
  void
  SetId(OpenCLContext * context, const cl_mem id);

  /** Helper function to get cl_map_flags from access. */
  cl_map_flags
  GetMapFlags(const OpenCLMemoryObject::Access access);

private:
  OpenCLContext * m_Context;
  cl_mem          m_Id;

  OpenCLMemoryObject(const Self & other) = delete;
  const Self &
  operator=(const Self &) = delete;
};

/** Operator ==
 * Returns true if \a lhs OpenCL memory object is the same as \a rhs, false otherwise.
 * \sa operator!= */
bool ITKOpenCL_EXPORT
     operator==(const OpenCLMemoryObject & lhs, const OpenCLMemoryObject & rhs);

/** Operator !=
 * Returns true if \a lhs OpenCL memory object identifier is not the same as \a rhs, false otherwise.
 * \sa operator== */
bool ITKOpenCL_EXPORT
     operator!=(const OpenCLMemoryObject & lhs, const OpenCLMemoryObject & rhs);

/** Stream out operator for OpenCLMemoryObject */
template <typename charT, typename traits>
inline std::basic_ostream<charT, traits> &
operator<<(std::basic_ostream<charT, traits> & strm, const OpenCLMemoryObject & memoryObject)
{
  if (memoryObject.IsNull())
  {
    strm << "OpenCLMemoryObject(null)";
    return strm;
  }

  const char indent = ' ';

  strm << "OpenCLMemoryObject\n"
       << indent << "Id: " << memoryObject.GetMemoryId() << '\n'
       << indent << "Context: " << memoryObject.GetContext() << '\n'
       << indent << "Memory type: " << memoryObject.GetMemoryType() << '\n'
       << indent << "Flags: " << memoryObject.GetFlags() << '\n'
       << indent << "Size: " << memoryObject.GetSize() << '\n'
       << indent << "Map count: " << memoryObject.GetMapCount() << '\n'
       << indent << "Reference count: " << memoryObject.GetReferenceCount() << '\n'
       << indent << "Host pointer: " << memoryObject.GetHostPointer() << '\n'
       << indent << "Access: ";

  switch (memoryObject.GetAccess())
  {
    case OpenCLMemoryObject::ReadWrite:
      strm << "Read Write";
      break;
    case OpenCLMemoryObject::WriteOnly:
      strm << "Write Only";
      break;
    case OpenCLMemoryObject::ReadOnly:
      strm << "Read Only";
      break;
    default:
      strm << "Unknown";
      break;
  }

  strm << std::endl;

  return strm;
}


} // end namespace itk

#endif /* itkOpenCLMemoryObject_h */