cf4ocl (C Framework for OpenCL)
v2.1.0
Object-oriented framework for developing and benchmarking OpenCL projects in C/C++
|
The buffer wrapper module provides functionality for simple handling of OpenCL buffer objects. More...
Macros | |
#define | ccl_buffer_enqueue_unmap(buf, cq, ptr, ewl, err) ccl_memobj_enqueue_unmap((CCLMemObj*) buf, cq, ptr, ewl, err) |
Enqueues a command to unmap a previously mapped buffer object. More... | |
#define | ccl_buffer_enqueue_unmap(buf, cq, ptr, ewl, err) ccl_memobj_enqueue_unmap((CCLMemObj*) buf, cq, ptr, ewl, err) |
Enqueues a command to unmap a previously mapped buffer object. More... | |
#define | ccl_buffer_ref(buf) ccl_wrapper_ref((CCLWrapper*) buf) |
Increase the reference count of the buffer wrapper object. More... | |
#define | ccl_buffer_ref(buf) ccl_wrapper_ref((CCLWrapper*) buf) |
Increase the reference count of the buffer wrapper object. More... | |
#define | ccl_buffer_unref(buf) ccl_buffer_destroy(buf) |
Alias to ccl_buffer_destroy(). More... | |
#define | ccl_buffer_unref(buf) ccl_buffer_destroy(buf) |
Alias to ccl_buffer_destroy(). More... | |
#define | ccl_buffer_unwrap(buf) ((cl_mem) ccl_wrapper_unwrap((CCLWrapper*) buf)) |
Get the OpenCL buffer object. More... | |
#define | ccl_buffer_unwrap(buf) ((cl_mem) ccl_wrapper_unwrap((CCLWrapper*) buf)) |
Get the OpenCL buffer object. More... | |
Typedefs | |
typedef struct ccl_buffer | CCLBuffer |
Buffer wrapper class. | |
Functions | |
void | ccl_buffer_destroy (CCLBuffer *buf) |
Decrements the reference count of the wrapper object. More... | |
CCLEvent * | ccl_buffer_enqueue_copy (CCLBuffer *src_buf, CCLBuffer *dst_buf, CCLQueue *cq, size_t src_offset, size_t dst_offset, size_t size, CCLEventWaitList *evt_wait_lst, CCLErr **err) |
Copy from one buffer object to another. More... | |
CCLEvent * | ccl_buffer_enqueue_copy_rect (CCLBuffer *src_buf, CCLBuffer *dst_buf, CCLQueue *cq, const size_t *src_origin, const size_t *dst_origin, const size_t *region, size_t src_row_pitch, size_t src_slice_pitch, size_t dst_row_pitch, size_t dst_slice_pitch, CCLEventWaitList *evt_wait_lst, CCLErr **err) |
Copy a 2D or 3D rectangular region from a buffer object to another buffer object. More... | |
CCLEvent * | ccl_buffer_enqueue_copy_to_image (CCLBuffer *src_buf, CCLImage *dst_img, CCLQueue *cq, size_t src_offset, const size_t *dst_origin, const size_t *region, CCLEventWaitList *evt_wait_lst, CCLErr **err) |
Copy a buffer object to an image object. More... | |
CCLEvent * | ccl_buffer_enqueue_fill (CCLBuffer *buf, CCLQueue *cq, const void *pattern, size_t pattern_size, size_t offset, size_t size, CCLEventWaitList *evt_wait_lst, CCLErr **err) |
Fill a buffer object with a pattern of a given pattern size. More... | |
void * | ccl_buffer_enqueue_map (CCLBuffer *buf, CCLQueue *cq, cl_bool blocking_map, cl_map_flags map_flags, size_t offset, size_t size, CCLEventWaitList *evt_wait_lst, CCLEvent **evt, CCLErr **err) |
Map a region of a buffer into the host address space and return a pointer to this mapped region. More... | |
CCLEvent * | ccl_buffer_enqueue_read (CCLBuffer *buf, CCLQueue *cq, cl_bool blocking_read, size_t offset, size_t size, void *ptr, CCLEventWaitList *evt_wait_lst, CCLErr **err) |
Read from a buffer object to host memory. More... | |
CCLEvent * | ccl_buffer_enqueue_read_rect (CCLBuffer *buf, CCLQueue *cq, cl_bool blocking_read, const size_t *buffer_origin, const size_t *host_origin, const size_t *region, size_t buffer_row_pitch, size_t buffer_slice_pitch, size_t host_row_pitch, size_t host_slice_pitch, void *ptr, CCLEventWaitList *evt_wait_lst, CCLErr **err) |
Read from a 2D or 3D rectangular region from a buffer object to host memory. More... | |
CCLEvent * | ccl_buffer_enqueue_write (CCLBuffer *buf, CCLQueue *cq, cl_bool blocking_write, size_t offset, size_t size, void *ptr, CCLEventWaitList *evt_wait_lst, CCLErr **err) |
Write to a buffer object from host memory. More... | |
CCLEvent * | ccl_buffer_enqueue_write_rect (CCLBuffer *buf, CCLQueue *cq, cl_bool blocking_write, const size_t *buffer_origin, const size_t *host_origin, const size_t *region, size_t buffer_row_pitch, size_t buffer_slice_pitch, size_t host_row_pitch, size_t host_slice_pitch, void *ptr, CCLEventWaitList *evt_wait_lst, CCLErr **err) |
Write a 2D or 3D rectangular region to a buffer object from host memory. More... | |
CCLBuffer * | ccl_buffer_new (CCLContext *ctx, cl_mem_flags flags, size_t size, void *host_ptr, CCLErr **err) |
Create a CCLBuffer wrapper object. More... | |
CCLBuffer * | ccl_buffer_new_from_region (CCLBuffer *buf, cl_mem_flags flags, size_t origin, size_t size, CCLErr **err) |
Creates a sub-buffer that represents a specific region in the given buffer. More... | |
CCLBuffer * | ccl_buffer_new_wrap (cl_mem mem_object) |
Get the buffer wrapper for the given OpenCL buffer. More... | |
The buffer wrapper module provides functionality for simple handling of OpenCL buffer objects.
All the functions in this module are direct wrappers of the respective OpenCL buffer functions, except for the ccl_buffer_new_from_region() function. This function wraps clCreateSubBuffer() but assumes that the sub-buffer will represent a specific region in the original buffer (which is the only sub-buffer type, up to OpenCL 2.1).
Buffer wrapper objects can be directly passed as kernel arguments to functions such as ccl_kernel_set_args_and_enqueue_ndrange() or ccl_kernel_set_args_v().
Information about buffer objects can be fetched using the info macros from the memory object module:
Instantiation and destruction of buffer wrappers follows the cf4ocl new/destroy rule.
Example:
#define ccl_buffer_enqueue_unmap | ( | buf, | |
cq, | |||
ptr, | |||
ewl, | |||
err | |||
) | ccl_memobj_enqueue_unmap((CCLMemObj*) buf, cq, ptr, ewl, err) |
Enqueues a command to unmap a previously mapped buffer object.
This is a utility macro that expands to ccl_memobj_enqueue_unmap(), casting buf
into a CCLMemObj object.
[in] | buf | A buffer wrapper object. |
[in] | cq | A command queue wrapper object. |
[in] | ptr | The host address returned by a previous call to ccl_buffer_enqueue_map(). |
[in,out] | ewl | List of events that need to complete before this command can be executed. The list will be cleared and can be reused by client code. |
[out] | err | Return location for a CCLErr object, or NULL if error reporting is to be ignored. |
Definition at line 199 of file ccl_buffer_wrapper.h.
#define ccl_buffer_enqueue_unmap | ( | buf, | |
cq, | |||
ptr, | |||
ewl, | |||
err | |||
) | ccl_memobj_enqueue_unmap((CCLMemObj*) buf, cq, ptr, ewl, err) |
Enqueues a command to unmap a previously mapped buffer object.
This is a utility macro that expands to ccl_memobj_enqueue_unmap(), casting buf
into a CCLMemObj object.
[in] | buf | A buffer wrapper object. |
[in] | cq | A command queue wrapper object. |
[in] | ptr | The host address returned by a previous call to ccl_buffer_enqueue_map(). |
[in,out] | ewl | List of events that need to complete before this command can be executed. The list will be cleared and can be reused by client code. |
[out] | err | Return location for a CCLErr object, or NULL if error reporting is to be ignored. |
Definition at line 199 of file ccl_buffer_wrapper.h.
#define ccl_buffer_ref | ( | buf | ) | ccl_wrapper_ref((CCLWrapper*) buf) |
Increase the reference count of the buffer wrapper object.
[in] | buf | The buffer wrapper object. |
Definition at line 207 of file ccl_buffer_wrapper.h.
#define ccl_buffer_ref | ( | buf | ) | ccl_wrapper_ref((CCLWrapper*) buf) |
Increase the reference count of the buffer wrapper object.
[in] | buf | The buffer wrapper object. |
Definition at line 207 of file ccl_buffer_wrapper.h.
#define ccl_buffer_unref | ( | buf | ) | ccl_buffer_destroy(buf) |
Alias to ccl_buffer_destroy().
[in] | buf | Buffer wrapper object to unreference. |
Definition at line 215 of file ccl_buffer_wrapper.h.
#define ccl_buffer_unref | ( | buf | ) | ccl_buffer_destroy(buf) |
Alias to ccl_buffer_destroy().
[in] | buf | Buffer wrapper object to unreference. |
Definition at line 215 of file ccl_buffer_wrapper.h.
#define ccl_buffer_unwrap | ( | buf | ) | ((cl_mem) ccl_wrapper_unwrap((CCLWrapper*) buf)) |
Get the OpenCL buffer object.
[in] | buf | The buffer wrapper object. |
Definition at line 223 of file ccl_buffer_wrapper.h.
#define ccl_buffer_unwrap | ( | buf | ) | ((cl_mem) ccl_wrapper_unwrap((CCLWrapper*) buf)) |
Get the OpenCL buffer object.
[in] | buf | The buffer wrapper object. |
Definition at line 223 of file ccl_buffer_wrapper.h.
void ccl_buffer_destroy | ( | CCLBuffer * | buf | ) |
Decrements the reference count of the wrapper object.
If it reaches 0, the wrapper object is destroyed.
[in] | buf | The buffer wrapper object. |
Definition at line 88 of file ccl_buffer_wrapper.c.
CCLEvent * ccl_buffer_enqueue_copy | ( | CCLBuffer * | src_buf, |
CCLBuffer * | dst_buf, | ||
CCLQueue * | cq, | ||
size_t | src_offset, | ||
size_t | dst_offset, | ||
size_t | size, | ||
CCLEventWaitList * | evt_wait_lst, | ||
CCLErr ** | err | ||
) |
Copy from one buffer object to another.
This function wraps the clEnqueueCopyBuffer() OpenCL function.
[in] | src_buf | Source buffer wrapper object where to read from. |
[out] | dst_buf | Destination buffer wrapper object where to write to. |
[in] | cq | Command-queue wrapper object in which the copy command will be queued. |
[in] | src_offset | The offset where to begin copying data from src_buffer. |
[in] | dst_offset | The offset where to begin copying data into dst_buffer. |
[in] | size | Size in bytes to copy. |
[in,out] | evt_wait_lst | List of events that need to complete before this command can be executed. The list will be cleared and can be reused by client code. |
[out] | err | Return location for a CCLErr object, or NULL if error reporting is to be ignored. |
Definition at line 408 of file ccl_buffer_wrapper.c.
CCLEvent * ccl_buffer_enqueue_copy_rect | ( | CCLBuffer * | src_buf, |
CCLBuffer * | dst_buf, | ||
CCLQueue * | cq, | ||
const size_t * | src_origin, | ||
const size_t * | dst_origin, | ||
const size_t * | region, | ||
size_t | src_row_pitch, | ||
size_t | src_slice_pitch, | ||
size_t | dst_row_pitch, | ||
size_t | dst_slice_pitch, | ||
CCLEventWaitList * | evt_wait_lst, | ||
CCLErr ** | err | ||
) |
Copy a 2D or 3D rectangular region from a buffer object to another buffer object.
This function wraps the clEnqueueCopyBufferRect() OpenCL function.
[in] | src_buf | Source buffer wrapper object where to read from. |
[out] | dst_buf | Destination buffer wrapper object where to write to. |
[in] | cq | Command-queue wrapper object in which the copy command will be queued. |
[in] | src_origin | The offset in memory associated with src_buf. |
[in] | dst_origin | The offset in memory associated with dst_buf. |
[in] | region | The (width in bytes, height in rows, depth in slices) of the 2D or 3D rectangle being copied. |
[in] | src_row_pitch | The length of each row in bytes to be used for the memory region associated with src_buf. |
[in] | src_slice_pitch | The length of each 2D slice in bytes to be used for the memory region associated with src_buf. |
[in] | dst_row_pitch | The length of each row in bytes to be used for the memory region associated with dst_buf. |
[in] | dst_slice_pitch | The length of each 2D slice in bytes to be used for the memory region associated with dst_buf. |
[in,out] | evt_wait_lst | List of events that need to complete before this command can be executed. The list will be cleared and can be reused by client code. |
[out] | err | Return location for a CCLErr object, or NULL if error reporting is to be ignored. |
Definition at line 972 of file ccl_buffer_wrapper.c.
CCLEvent * ccl_buffer_enqueue_copy_to_image | ( | CCLBuffer * | src_buf, |
CCLImage * | dst_img, | ||
CCLQueue * | cq, | ||
size_t | src_offset, | ||
const size_t * | dst_origin, | ||
const size_t * | region, | ||
CCLEventWaitList * | evt_wait_lst, | ||
CCLErr ** | err | ||
) |
Copy a buffer object to an image object.
This function wraps the clEnqueueCopyBufferToImage() OpenCL function.
[in] | src_buf | Source buffer wrapper object where to read from. |
[out] | dst_img | Destination image wrapper object where to write to. |
[in] | cq | Command-queue wrapper object in which the copy command will be queued. |
[in] | src_offset | The offset where to begin copying data from src_buffer. |
[in] | dst_origin | Defines the offset in pixels in the 1D, 2D or 3D image, the offset and the image index in the 2D image array or the offset and the image index in the 1D image array. |
[in] | region | The in pixels of the 1D, 2D or 3D rectangle, the in pixels of the 2D rectangle and the number of images of a 2D image array or the in pixels of the 1D rectangle and the number of images of a 1D image array. |
[in,out] | evt_wait_lst | List of events that need to complete before this command can be executed. The list will be cleared and can be reused by client code. |
[out] | err | Return location for a CCLErr object, or NULL if error reporting is to be ignored. |
Definition at line 492 of file ccl_buffer_wrapper.c.
CCLEvent * ccl_buffer_enqueue_fill | ( | CCLBuffer * | buf, |
CCLQueue * | cq, | ||
const void * | pattern, | ||
size_t | pattern_size, | ||
size_t | offset, | ||
size_t | size, | ||
CCLEventWaitList * | evt_wait_lst, | ||
CCLErr ** | err | ||
) |
Fill a buffer object with a pattern of a given pattern size.
This function wraps the clEnqueueFillBuffer() OpenCL function.
[out] | buf | Buffer wrapper object to fill. |
[in] | cq | Command-queue wrapper object in which the fill command will be queued. |
[in] | pattern | A pointer to the data pattern. |
[in] | pattern_size | Size of data pattern in bytes. |
[in] | offset | The location in bytes of the region being filled in buffer and must be a multiple of pattern_size. |
[in] | size | The size in bytes of region being filled in buffer. Must be a multiple of pattern_size. |
[in,out] | evt_wait_lst | List of events that need to complete before this command can be executed. The list will be cleared and can be reused by client code. |
[out] | err | Return location for a CCLErr object, or NULL if error reporting is to be ignored. |
Definition at line 1100 of file ccl_buffer_wrapper.c.
void * ccl_buffer_enqueue_map | ( | CCLBuffer * | buf, |
CCLQueue * | cq, | ||
cl_bool | blocking_map, | ||
cl_map_flags | map_flags, | ||
size_t | offset, | ||
size_t | size, | ||
CCLEventWaitList * | evt_wait_lst, | ||
CCLEvent ** | evt, | ||
CCLErr ** | err | ||
) |
Map a region of a buffer into the host address space and return a pointer to this mapped region.
This function wraps the clEnqueueMapBuffer() OpenCL function.
[in,out] | buf | Buffer wrapper object to be mapped. |
[in] | cq | Command-queue wrapper object in which the map command will be queued. |
[in] | blocking_map | Indicates if the map operation is blocking or non-blocking. |
[in] | map_flags | Flags which specify the type of mapping to perform. |
[in] | offset | The offset in bytes in the buffer object that is being mapped. |
[in] | size | The size of the region in the buffer object that is being mapped. |
[in,out] | evt_wait_lst | List of events that need to complete before this command can be executed. The list will be cleared and can be reused by client code. |
[out] | evt | An event wrapper object that identifies this particular map command. If NULL, no event will be returned. |
[out] | err | Return location for a CCLErr object, or NULL if error reporting is to be ignored. |
Definition at line 328 of file ccl_buffer_wrapper.c.
CCLEvent * ccl_buffer_enqueue_read | ( | CCLBuffer * | buf, |
CCLQueue * | cq, | ||
cl_bool | blocking_read, | ||
size_t | offset, | ||
size_t | size, | ||
void * | ptr, | ||
CCLEventWaitList * | evt_wait_lst, | ||
CCLErr ** | err | ||
) |
Read from a buffer object to host memory.
This function wraps the clEnqueueReadBuffer() OpenCL function.
[in] | buf | Buffer wrapper object where to read from. |
[in] | cq | Command-queue wrapper object in which the read command will be queued. |
[in] | blocking_read | Indicates if the read operations are blocking or non-blocking. |
[in] | offset | The offset in bytes in the buffer object to read from. |
[in] | size | The size in bytes of data being read. |
[out] | ptr | The pointer to buffer in host memory where data is to be read into. |
[in,out] | evt_wait_lst | List of events that need to complete before this command can be executed. The list will be cleared and can be reused by client code. |
[out] | err | Return location for a CCLErr object, or NULL if error reporting is to be ignored. |
Definition at line 175 of file ccl_buffer_wrapper.c.
CCLEvent * ccl_buffer_enqueue_read_rect | ( | CCLBuffer * | buf, |
CCLQueue * | cq, | ||
cl_bool | blocking_read, | ||
const size_t * | buffer_origin, | ||
const size_t * | host_origin, | ||
const size_t * | region, | ||
size_t | buffer_row_pitch, | ||
size_t | buffer_slice_pitch, | ||
size_t | host_row_pitch, | ||
size_t | host_slice_pitch, | ||
void * | ptr, | ||
CCLEventWaitList * | evt_wait_lst, | ||
CCLErr ** | err | ||
) |
Read from a 2D or 3D rectangular region from a buffer object to host memory.
This function wraps the clEnqueueReadBufferRect() OpenCL function.
[in] | buf | Buffer wrapper object where to read from. |
[in] | cq | Command-queue wrapper object in which the read command will be queued. |
[in] | blocking_read | Indicates if the read operations are blocking or non-blocking. |
[in] | buffer_origin | The offset in the memory region associated with buffer. |
[in] | host_origin | The offset in the memory region pointed to by ptr. |
[in] | region | The (width in bytes, height in rows, depth in slices) of the 2D or 3D rectangle being read or written. |
[in] | buffer_row_pitch | The length of each row in bytes to be used for the memory region associated with buffer. |
[in] | buffer_slice_pitch | The length of each 2D slice in bytes to be used for the memory region associated with buffer. |
[in] | host_row_pitch | The length of each row in bytes to be used for the memory region pointed to by ptr. |
[in] | host_slice_pitch | The length of each 2D slice in bytes to be used for the memory region pointed to by ptr. |
[out] | ptr | The pointer to buffer in host memory where data is to be read into. |
[in,out] | evt_wait_lst | List of events that need to complete before this command can be executed. The list will be cleared and can be reused by client code. |
[out] | err | Return location for a CCLErr object, or NULL if error reporting is to be ignored. |
Definition at line 690 of file ccl_buffer_wrapper.c.
CCLEvent * ccl_buffer_enqueue_write | ( | CCLBuffer * | buf, |
CCLQueue * | cq, | ||
cl_bool | blocking_write, | ||
size_t | offset, | ||
size_t | size, | ||
void * | ptr, | ||
CCLEventWaitList * | evt_wait_lst, | ||
CCLErr ** | err | ||
) |
Write to a buffer object from host memory.
This function wraps the clEnqueueWriteBuffer() OpenCL function.
[out] | buf | Buffer wrapper object where to write to. |
[in] | cq | Command-queue wrapper object in which the write command will be queued. |
[in] | blocking_write | Indicates if the write operations are blocking or non-blocking. |
[in] | offset | The offset in bytes in the buffer object to read from. |
[in] | size | The size in bytes of data being read. |
[in] | ptr | The pointer to buffer in host memory where data is to be written from. |
[in,out] | evt_wait_lst | List of events that need to complete before this command can be executed. The list will be cleared and can be reused by client code. |
[out] | err | Return location for a CCLErr object, or NULL if error reporting is to be ignored. |
Definition at line 250 of file ccl_buffer_wrapper.c.
CCLEvent * ccl_buffer_enqueue_write_rect | ( | CCLBuffer * | buf, |
CCLQueue * | cq, | ||
cl_bool | blocking_write, | ||
const size_t * | buffer_origin, | ||
const size_t * | host_origin, | ||
const size_t * | region, | ||
size_t | buffer_row_pitch, | ||
size_t | buffer_slice_pitch, | ||
size_t | host_row_pitch, | ||
size_t | host_slice_pitch, | ||
void * | ptr, | ||
CCLEventWaitList * | evt_wait_lst, | ||
CCLErr ** | err | ||
) |
Write a 2D or 3D rectangular region to a buffer object from host memory.
This function wraps the clEnqueueWriteBufferRect() OpenCL function.
[out] | buf | Buffer wrapper object where to write to. |
[in] | cq | Command-queue wrapper object in which the write command will be queued. |
[in] | blocking_write | Indicates if the write operations are blocking or non-blocking. |
[in] | buffer_origin | The offset in the memory region associated with buffer. |
[in] | host_origin | The offset in the memory region pointed to by ptr. |
[in] | region | The (width in bytes, height in rows, depth in slices) of the 2D or 3D rectangle being read or written. |
[in] | buffer_row_pitch | The length of each row in bytes to be used for the memory region associated with buffer. |
[in] | buffer_slice_pitch | The length of each 2D slice in bytes to be used for the memory region associated with buffer. |
[in] | host_row_pitch | The length of each row in bytes to be used for the memory region pointed to by ptr. |
[in] | host_slice_pitch | The length of each 2D slice in bytes to be used for the memory region pointed to by ptr. |
[in] | ptr | The pointer to buffer in host memory where data is to be written from. |
[in,out] | evt_wait_lst | List of events that need to complete before this command can be executed. The list will be cleared and can be reused by client code. |
[out] | err | Return location for a CCLErr object, or NULL if error reporting is to be ignored. |
Definition at line 833 of file ccl_buffer_wrapper.c.
CCLBuffer * ccl_buffer_new | ( | CCLContext * | ctx, |
cl_mem_flags | flags, | ||
size_t | size, | ||
void * | host_ptr, | ||
CCLErr ** | err | ||
) |
Create a CCLBuffer wrapper object.
[in] | ctx | Context wrapper. |
[in] | flags | OpenCL memory flags. |
[in] | size | The size in bytes of the buffer memory object to be allocated. |
[in] | host_ptr | A pointer to the buffer data that may already be allocated by the application. The size of the buffer that host_ptr points to must be >= size bytes. |
[out] | err | Return location for a CCLErr object, or NULL if error reporting is to be ignored. |
Definition at line 113 of file ccl_buffer_wrapper.c.
CCLBuffer * ccl_buffer_new_from_region | ( | CCLBuffer * | buf, |
cl_mem_flags | flags, | ||
size_t | origin, | ||
size_t | size, | ||
CCLErr ** | err | ||
) |
Creates a sub-buffer that represents a specific region in the given buffer.
This function wraps the clCreateSubBuffer() OpenCL function.
[in] | buf | A buffer wrapper object which cannot represent a sub-buffer. |
[in] | flags | Allocation and usage information about the sub-buffer memory object. |
[in] | origin | Offset relative to the parent buffer. |
[in] | size | Sub-buffer size. |
[out] | err | Return location for a CCLErr object, or NULL if error reporting is to be ignored. |
Definition at line 569 of file ccl_buffer_wrapper.c.
|
protected |
Get the buffer wrapper for the given OpenCL buffer.
If the wrapper doesn't exist, its created with a reference count of 1. Otherwise, the existing wrapper is returned and its reference count is incremented by 1.
This function will rarely be called from client code, except when clients wish to directly wrap an OpenCL buffer in a CCLBuffer wrapper object.
[in] | mem_object | The OpenCL buffer to be wrapped. |
Definition at line 72 of file ccl_buffer_wrapper.c.