Skip to content

Commit 36e757e

Browse files
committed
Fixed issues in ImageInverter CL code
1 parent a4cf3a3 commit 36e757e

File tree

6 files changed

+87
-27
lines changed

6 files changed

+87
-27
lines changed

source/FAST/Algorithms/ImageInverter/ImageInverter.cpp

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,15 @@ void ImageInverter::execute() {
3131

3232
if(input->getDimensions() == 3) {
3333
std::string buildOptions = "-DDATA_TYPE=" + getCTypeAsString(output->getDataType());
34-
cl::Program program = getOpenCLProgram(device, "3D", buildOptions);
35-
cl::Kernel kernel(program, "invert3D");
34+
auto kernel = getKernel("invert3D", "3D", buildOptions);
3635

37-
auto access = input->getOpenCLImageAccess(ACCESS_READ, device);
38-
auto access2 = output->getOpenCLBufferAccess(ACCESS_READ_WRITE, device);
39-
kernel.setArg(0, *access->get3DImage());
40-
kernel.setArg(1, *access2->get());
41-
kernel.setArg(2, min);
42-
kernel.setArg(3, max);
43-
kernel.setArg(4, output->getNrOfChannels());
36+
kernel.setArg("input", input);
37+
kernel.setArg("output", output);
38+
kernel.setArg("minIntensity", min);
39+
kernel.setArg("maxIntensity", max);
40+
kernel.setArg("outputChannels", output->getNrOfChannels());
4441

45-
queue.enqueueNDRangeKernel(
46-
kernel,
47-
cl::NullRange,
48-
cl::NDRange(size.x(), size.y(), size.z()),
49-
cl::NullRange
50-
);
42+
getQueue().add(kernel, size);
5143
} else {
5244
auto kernel = getKernel("invert2D", "2D");
5345

source/FAST/Algorithms/ImageInverter/ImageInverter2D.cl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ __kernel void invert2D(
1717
} else {
1818
value = convert_float4(read_imagei(input, sampler, pos));
1919
}
20-
value = (maxIntensity - minIntensity) - value;
20+
value = (maxIntensity + minIntensity) - value;
2121
if(dataType == CLK_FLOAT) {
2222
write_imagef(output, pos, value);
2323
} else if(dataType == CLK_UNSIGNED_INT8 || dataType == CLK_UNSIGNED_INT16 || dataType == CLK_UNSIGNED_INT32) {

source/FAST/Algorithms/ImageInverter/ImageInverter3D.cl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ __constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_NONE |
22

33
__kernel void invert3D(
44
__read_only image3d_t input,
5-
__global DATA_TYPE* output,
6-
__private float min,
7-
__private float max,
5+
__write_only __global DATA_TYPE* output,
6+
__private float minIntensity,
7+
__private float maxIntensity,
88
__private uint outputChannels
99
) {
1010
const int4 pos = {get_global_id(0), get_global_id(1), get_global_id(2), 0};
@@ -18,7 +18,7 @@ __kernel void invert3D(
1818
} else {
1919
value = convert_float4(read_imagei(input, sampler, pos));
2020
}
21-
value = (max - min) - value;
21+
value = (maxIntensity + minIntensity) - value;
2222

2323
output[(pos.x + pos.y*get_image_width(input) + pos.z*get_image_width(input)*get_image_height(input))*outputChannels] = value.x;
2424
if(outputChannels > 1)

source/FAST/Algorithms/ImageInverter/ImageInverterTests.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,12 @@ TEST_CASE("ImageInverter 2D", "[fast][ImageInverter]") {
88
auto importer = ImageFileImporter::create(Config::getTestDataPath() + "US/Heart/ApicalFourChamber/US-2D_0.mhd");
99

1010
auto inverter = ImageInverter::create()->connect(importer);
11-
inverter->run();
12-
}
11+
CHECK_NOTHROW(inverter->run());
12+
}
13+
14+
TEST_CASE("ImageInverter 3D", "[fast][ImageInverter]") {
15+
auto importer = ImageFileImporter::create(Config::getTestDataPath() + "CT/CT-Thorax.mhd");
16+
17+
auto inverter = ImageInverter::create()->connect(importer);
18+
CHECK_NOTHROW(inverter->run());
19+
}

source/FAST/OpenCLProgram.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ Kernel::Kernel(cl::Kernel clKernel, OpenCLDevice::pointer device) {
161161
m_device = device;
162162

163163
std::map<cl_kernel_arg_access_qualifier, KernelArgumentAccess> accessMap = {
164-
{CL_KERNEL_ARG_ACCESS_NONE, KernelArgumentAccess::NONE},
164+
{CL_KERNEL_ARG_ACCESS_NONE, KernelArgumentAccess::UNSPECIFIED},
165165
{CL_KERNEL_ARG_ACCESS_READ_ONLY, KernelArgumentAccess::READ_ONLY},
166166
{CL_KERNEL_ARG_ACCESS_WRITE_ONLY, KernelArgumentAccess::WRITE_ONLY},
167167
{CL_KERNEL_ARG_ACCESS_READ_WRITE, KernelArgumentAccess::READ_WRITE}
@@ -325,10 +325,10 @@ void Kernel::setArg(const std::string& name, OpenCLBuffer buffer) {
325325
template <>
326326
void Kernel::setArg(int index, Image::pointer image) {
327327
checkIndex(index);
328-
accessType access = ACCESS_READ;
328+
accessType access = ACCESS_READ_WRITE;
329329
auto kernelAccess = m_argInfoByIndex.at(index).access;
330-
if(kernelAccess == KernelArgumentAccess::WRITE_ONLY || kernelAccess == KernelArgumentAccess::READ_WRITE) {
331-
access = ACCESS_READ_WRITE;
330+
if(kernelAccess == KernelArgumentAccess::READ_ONLY) {
331+
access = ACCESS_READ;
332332
}
333333
setImageArg(index, image, access);
334334
}
@@ -342,6 +342,7 @@ template <>
342342
void Kernel::setArg(int index, std::unique_ptr<OpenCLBufferAccess> access) {
343343
checkIndex(index);
344344
m_kernel.setArg(index, *access->get());
345+
m_argGotValue.insert(index);
345346
}
346347
template <>
347348
void Kernel::setArg(const std::string& name, std::unique_ptr<OpenCLBufferAccess> access) {

source/FAST/OpenCLProgram.hpp

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,12 @@ class FAST_EXPORT OpenCLProgram : public Object {
4646
std::unordered_map<std::shared_ptr<OpenCLDevice>, std::map<std::string, cl::Program> > mOpenCLPrograms;
4747
};
4848

49+
/**
50+
* @brief Access qualifier of a kernel argument
51+
* @ingroup opencl
52+
*/
4953
enum class KernelArgumentAccess {
50-
NONE,
54+
UNSPECIFIED,
5155
READ_ONLY,
5256
WRITE_ONLY,
5357
READ_WRITE,
@@ -221,34 +225,86 @@ FAST_EXPORT void Kernel::setArg(const std::string& name, std::unique_ptr<OpenCLB
221225
class FAST_EXPORT Queue {
222226
public:
223227
Queue(cl::CommandQueue clQueue);
228+
/**
229+
* @brief Enqueue a Kernel to this command queue
230+
* @param kernel
231+
* @param globalSize total number of work-items for each dimension
232+
* @param offset work-item offset, if none is given, it is zero for all dimensions
233+
* @param groupSize How many work-items should be each work-group for each dimension.
234+
* If not provided, platform will decide automatically
235+
*/
224236
void add(const Kernel& kernel, std::vector<int> globalSize, std::vector<int> offset = std::vector<int>(), std::vector<int> groupSize = std::vector<int>());
237+
/**
238+
* @brief Block until entire command queue is finished
239+
*/
225240
void finish();
241+
/**
242+
* @brief Copy data from buffer on device to pointer on host
243+
* @param buffer OpenCL buffer to read from
244+
* @param block Whether this call should block and wait until the data operation is finished.
245+
* @param offset Byte offset in OpenCL buffer
246+
* @param size nr of bytes to read (e.g. elements*sizeof(datatype))
247+
* @param pointerToData Pointer to host memory to read data into. Must be allocated with big enough size
248+
*/
226249
void addReadBuffer(OpenCLBuffer buffer, bool block, std::size_t offset, std::size_t size, void* pointerToData);
250+
/**
251+
* @brief Write data from host pointer to OpenCL buffer
252+
* @param buffer OpenCL buffer to write data to
253+
* @param block Whether this call should block and wait until the data operation is finished.
254+
* @param offset Byte offset in OpenCL buffer to write data to
255+
* @param size nr of bytes to write (e.g. elements*sizeof(datatype))
256+
* @param pointerToData Pointer to host memory to read data from. Must be bigger than size.
257+
*/
227258
void addWriteBuffer(OpenCLBuffer buffer, bool block, std::size_t offset, std::size_t size, void* pointerToData);
259+
/**
260+
* @brief Copy data from one OpenCL buffer (source) to another (destination)
261+
* @param srcBuffer source OpenCL buffer
262+
* @param dstBuffer destination OpenCL buffer
263+
* @param srcOffset offset in bytes in source buffer
264+
* @param destOffset offset in bytes in destination buffer
265+
* @param size size in bytes (e.g. elements*sizeof(datatype))
266+
*/
228267
void addCopyBuffer(OpenCLBuffer srcBuffer, OpenCLBuffer dstBuffer, std::size_t srcOffset, std::size_t destOffset, std::size_t size);
229268
cl::CommandQueue getHandle() const;
230269
private:
231270
cl::CommandQueue m_queue;
232271
};
233272

273+
/**
274+
* @brief Access to OpenCL memory granted to kernel
275+
* @ingroup opencl
276+
*/
234277
enum class KernelMemoryAccess {
235278
READ_WRITE = 0,
236279
READ_ONLY,
237280
WRITE_ONLY
238281
};
282+
/**
283+
* @brief Access to OpenCL memory granted to host
284+
* @ingroup opencl
285+
*/
239286
enum class HostMemoryAccess {
240287
UNSPECIFIED = 0,
241288
READ_ONLY,
242289
WRITE_ONLY,
243290
//READ_WRITE,
244291
NONE
245292
};
293+
246294
/**
247295
* @brief OpenCL Buffer
248296
* @ingroup opencl
249297
*/
250298
class FAST_EXPORT OpenCLBuffer {
251299
public:
300+
/**
301+
* @brief Create OpenCL buffer
302+
* @param size in bytes (e.g. elements*sizeof(datatype))
303+
* @param device device
304+
* @param kernelAccess Access to memory to grant to kernel (default READ+WRITE)
305+
* @param hostAccess Access to memory to grant to host (default UNSPECIFIED)
306+
* @param data Pointer to data on host which is copied to the device (default nullptr/none)
307+
*/
252308
OpenCLBuffer(
253309
std::size_t size,
254310
OpenCLDevice::pointer device,
@@ -257,6 +313,10 @@ class FAST_EXPORT OpenCLBuffer {
257313
const void* data = nullptr
258314
);
259315
cl::Buffer getHandle() const;
316+
/**
317+
* @brief Get size of OpenCL buffer in bytes
318+
* @return number of bytes
319+
*/
260320
std::size_t getSize() const;
261321
private:
262322
cl::Buffer m_buffer;

0 commit comments

Comments
 (0)