Repository navigation
Update OpenCL interop page so they discuss deleting of memory #2918
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,96 @@ | ||
| /******************************************************* | ||
| * Copyright (c) 2020, ArrayFire | ||
| * All rights reserved. | ||
| * | ||
| * This file is distributed under 3-clause BSD license. | ||
| * The complete license agreement can be obtained at: | ||
| * http://arrayfire.com/licenses/BSD-3-Clause | ||
| ********************************************************/ | ||
|
|
||
| // clang-format off | ||
| // ![interop_opencl_custom_kernel_snippet] | ||
| #include <arrayfire.h> | ||
| // 1. Add the af/opencl.h include to your project | ||
| #include <af/opencl.h> | ||
|
|
||
| #include <cassert> | ||
|
|
||
| #define OCL_CHECK(call) \ | ||
| if (cl_int err = (call) != CL_SUCCESS) { \ | ||
| fprintf(stderr, __FILE__ "(%d):Returned error code %d\n", __LINE__, \ | ||
| err); \ | ||
| } | ||
|
|
||
| int main() { | ||
| size_t length = 10; | ||
|
|
||
| // Create ArrayFire array objects: | ||
| af::array A = af::randu(length, f32); | ||
| af::array B = af::constant(0, length, f32); | ||
|
|
||
| // ... additional ArrayFire operations here | ||
|
|
||
| // 2. Obtain the device, context, and queue used by ArrayFire | ||
| static cl_context af_context = afcl::getContext(); | ||
| static cl_device_id af_device_id = afcl::getDeviceId(); | ||
| static cl_command_queue af_queue = afcl::getQueue(); | ||
|
|
||
| // 3. Obtain cl_mem references to af::array objects | ||
| cl_mem* d_A = A.device<cl_mem>(); | ||
| cl_mem* d_B = B.device<cl_mem>(); | ||
|
|
||
| // 4. Load, build, and use your kernels. | ||
| // For the sake of readability, we have omitted error checking. | ||
| int status = CL_SUCCESS; | ||
|
|
||
| // A simple copy kernel, uses C++11 syntax for multi-line strings. | ||
| const char* kernel_name = "copy_kernel"; | ||
| const char* source = R"( | ||
| void __kernel | ||
| copy_kernel(__global float* gA, __global float* gB) { | ||
| int id = get_global_id(0); | ||
| gB[id] = gA[id]; | ||
| } | ||
| )"; | ||
|
|
||
| // Create the program, build the executable, and extract the entry point | ||
| // for the kernel. | ||
| cl_program program = clCreateProgramWithSource(af_context, 1, &source, NULL, &status); | ||
| OCL_CHECK(status); | ||
| OCL_CHECK(clBuildProgram(program, 1, &af_device_id, NULL, NULL, NULL)); | ||
| cl_kernel kernel = clCreateKernel(program, kernel_name, &status); | ||
| OCL_CHECK(status); | ||
|
|
||
| // Set arguments and launch your kernels | ||
| OCL_CHECK(clSetKernelArg(kernel, 0, sizeof(cl_mem), d_A)); | ||
| OCL_CHECK(clSetKernelArg(kernel, 1, sizeof(cl_mem), d_B)); | ||
| OCL_CHECK(clEnqueueNDRangeKernel(af_queue, kernel, 1, NULL, &length, NULL, | ||
| 0, NULL, NULL)); | ||
|
|
||
| // 5. Return control of af::array memory to ArrayFire | ||
| A.unlock(); | ||
| B.unlock(); | ||
|
|
||
| /// A and B should not be the same because of the copy_kernel user code | ||
| assert(af::allTrue<bool>(A == B)); | ||
|
|
||
| // Delete the pointers returned by the device function. This does NOT | ||
| // delete the cl_mem memory and only deletes the pointers | ||
| delete d_A; | ||
| delete d_B; | ||
|
|
||
| // ... resume ArrayFire operations | ||
|
|
||
| // Because the device pointers, d_x and d_y, were returned to ArrayFire's | ||
| // control by the unlock function, there is no need to free them using | ||
| // clReleaseMemObject() | ||
|
|
||
| // Free the kernel and program objects because they are created in user | ||
| // code | ||
| OCL_CHECK(clReleaseKernel(kernel)); | ||
| OCL_CHECK(clReleaseProgram(program)); | ||
|
|
||
| return 0; | ||
| } | ||
| // ![interop_opencl_custom_kernel_snippet] | ||
| // clang-format on |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| /******************************************************* | ||
| * Copyright (c) 2020, ArrayFire | ||
| * All rights reserved. | ||
| * | ||
| * This file is distributed under 3-clause BSD license. | ||
| * The complete license agreement can be obtained at: | ||
| * http://arrayfire.com/licenses/BSD-3-Clause | ||
| ********************************************************/ | ||
|
|
||
| #pragma GCC diagnostic push | ||
| #pragma GCC diagnostic ignored "-Wunused-function" | ||
| #pragma GCC diagnostic ignored "-Wunused-parameter" | ||
| #pragma GCC diagnostic ignored "-Wignored-qualifiers" | ||
| #pragma GCC diagnostic ignored "-Wignored-attributes" | ||
| #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | ||
| #if __GNUC__ >= 8 | ||
| #pragma GCC diagnostic ignored "-Wcatch-value=" | ||
| #endif | ||
| // ![interop_opencl_external_context_snippet] | ||
| #include <arrayfire.h> | ||
| // 1. Add the af/opencl.h include to your project | ||
| #include <af/opencl.h> | ||
|
|
||
| #include <cassert> | ||
|
|
||
| // definitions required by cl2.hpp | ||
| #define CL_HPP_ENABLE_EXCEPTIONS | ||
| #define CL_HPP_TARGET_OPENCL_VERSION 120 | ||
| #define CL_HPP_MINIMUM_OPENCL_VERSION 120 | ||
| #include <CL/cl2.hpp> | ||
|
|
||
| // 1. Add arrayfire.h and af/opencl.h to your application | ||
| #include "af/opencl.h" | ||
| #include "arrayfire.h" | ||
|
|
||
| #include <cstdio> | ||
| #include <vector> | ||
|
|
||
| using std::vector; | ||
|
|
||
| int main() { | ||
| // 1. Set up the OpenCL context, device, and queues | ||
| cl::Context context; | ||
| try { | ||
| context = cl::Context(CL_DEVICE_TYPE_ALL); | ||
| } catch (const cl::Error& err) { | ||
| fprintf(stderr, "Exiting creating context"); | ||
| return EXIT_FAILURE; | ||
| } | ||
| vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>(); | ||
| if (devices.empty()) { | ||
| fprintf(stderr, "Exiting. No devices found"); | ||
| return EXIT_SUCCESS; | ||
| } | ||
| cl::Device device = devices[0]; | ||
| cl::CommandQueue queue(context, device); | ||
|
|
||
| // Create a buffer of size 10 filled with ones, copy it to the device | ||
| int length = 10; | ||
| vector<float> h_A(length, 1); | ||
| cl::Buffer cl_A(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, | ||
| length * sizeof(float), h_A.data()); | ||
|
|
||
| // 2. Instruct OpenCL to complete its operations using clFinish (or similar) | ||
| queue.finish(); | ||
|
|
||
| // 3. Instruct ArrayFire to use the user-created context | ||
| // First, create a device from the current OpenCL device + context + | ||
| // queue | ||
| afcl::addDevice(device(), context(), queue()); | ||
| // Next switch ArrayFire to the device using the device and context as | ||
| // identifiers: | ||
| afcl::setDevice(device(), context()); | ||
|
|
||
| // 4. Create ArrayFire arrays from OpenCL memory objects | ||
| af::array af_A = afcl::array(length, cl_A(), f32, true); | ||
| clRetainMemObject(cl_A()); | ||
|
|
||
| // 5. Perform ArrayFire operations on the Arrays | ||
| af_A = af_A + af::randu(length); | ||
|
|
||
| // NOTE: ArrayFire does not perform the above transaction using in-place | ||
| // memory, thus the underlying OpenCL buffers containing the memory | ||
| // containing memory to probably have changed | ||
|
|
||
| // 6. Instruct ArrayFire to finish operations using af::sync | ||
| af::sync(); | ||
|
|
||
| // 7. Obtain cl_mem references for important memory | ||
| cl_mem* af_mem = af_A.device<cl_mem>(); | ||
| cl_A = cl::Buffer(*af_mem, /*retain*/ true); | ||
|
|
||
| /// Delete the af_mem pointer. The buffer returned by the device pointer is | ||
| /// still valid | ||
| delete af_mem; | ||
|
|
||
| // 8. Continue your OpenCL application | ||
|
|
||
| // ... | ||
| return EXIT_SUCCESS; | ||
| } | ||
| // ![interop_opencl_external_context_snippet] | ||
|
|
||
| #pragma GCC diagnostic pop | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feel like this unnecessary extra retain.