Skip to content

Commit

Permalink
updated a bunch of samples and added a bunch of descriptive text
Browse files Browse the repository at this point in the history
  • Loading branch information
bashbaug committed Nov 14, 2023
1 parent 9826bfe commit 4148699
Show file tree
Hide file tree
Showing 8 changed files with 752 additions and 96 deletions.
34 changes: 28 additions & 6 deletions samples/python/00_enumopencl/enumopencl.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,34 @@
"source": [
"# enumopencl\n",
"\n",
"### Copyright Information"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "163deb93-0c32-40c7-aaf0-a427b453ccc3",
"metadata": {},
"outputs": [],
"source": [
"# Copyright (c) 2023 Ben Ashbaugh\n",
"#\n",
"# SPDX-License-Identifier: MIT"
]
},
{
"cell_type": "markdown",
"id": "79250647-6a73-42d0-aee8-051aae55a2a8",
"metadata": {},
"source": [
"## Sample Purpose\n",
"\n",
"This is a very simple sample that demonstrates how to enumerate the OpenCL platforms that are installed on a machine, and the OpenCL devices that these platforms expose.\n",
"\n",
"This is a good first sample to run to verify that OpenCL is correctly installed on your machine, and that your environment is correctly setup.\n",
"\n",
"## Sample\n",
"\n",
"The first thing we will do is to import pyopencl so we have access to OpenCL from Python."
]
},
Expand Down Expand Up @@ -45,13 +67,13 @@
"metadata": {},
"outputs": [],
"source": [
"for platform in cl.get_platforms():\n",
" print(\"Platform:\")\n",
"for p, platform in enumerate(cl.get_platforms()):\n",
" print(\"Platform[{}]:\".format(p))\n",
" print(\" Name: \" + platform.get_info(cl.platform_info.NAME))\n",
" print(\" Vendor: \" + platform.get_info(cl.platform_info.VENDOR))\n",
" print(\" Driver Version: \" + platform.get_info(cl.platform_info.VERSION))\n",
" for i, device in enumerate(platform.get_devices()):\n",
" print(\"Device[{}]:\".format(i))\n",
" for d, device in enumerate(platform.get_devices()):\n",
" print(\"Device[{}]:\".format(d))\n",
" print(\" Type: \" + cl.device_type.to_string(device.get_info(cl.device_info.TYPE)))\n",
" print(\" Name: \" + device.get_info(cl.device_info.NAME))\n",
" print(\" Vendor: \" + device.get_info(cl.device_info.VENDOR))\n",
Expand All @@ -71,7 +93,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
Expand All @@ -85,7 +107,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.8.10"
"version": "3.10.12"
}
},
"nbformat": 4,
Expand Down
20 changes: 2 additions & 18 deletions samples/python/00_enumopencl/enumopencl.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,8 @@
#!/usr/bin/env python

# Copyright (c) 2019-2021 Ben Ashbaugh
# Copyright (c) 2019-2023 Ben Ashbaugh
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# SPDX-License-Identifier: MIT

import pyopencl as cl

Expand Down
254 changes: 254 additions & 0 deletions samples/python/01_copybuffer/copybuffer.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,254 @@
{
"cells": [
{
"cell_type": "markdown",
"id": "33e2ac4e-10a4-45dd-b8e2-0e6b5c1f7d4d",
"metadata": {},
"source": [
"# copybuffer\n",
"\n",
"### Copyright Information"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "8dcd0e61-f4e4-4546-b6cc-ab654286167d",
"metadata": {},
"outputs": [],
"source": [
"# Copyright (c) 2023 Ben Ashbaugh\n",
"#\n",
"# SPDX-License-Identifier: MIT"
]
},
{
"cell_type": "markdown",
"id": "64c7a35b-8247-41ea-a3a9-f18f4ddfb00c",
"metadata": {},
"source": [
"## Sample Purpose\n",
"\n",
"This is first example that uses OpenCL APIs to do work. In this very simple sample, OpenCL APIs are used to copy the contents of one buffer to another buffer on the OpenCL device. To do this, OpenCL APIs are used to create both buffers, to create the OpenCL command queue, and to initialize the source buffer and verify the contents of the destination buffer on the host.\n",
"\n",
"## Sample\n",
"\n",
"The first thing we will do is to import pyopencl so we have access to OpenCL from Python.\n",
"We will also import numpy."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "347bcdb3-0363-437b-9e2e-aede28b95ae4",
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"import pyopencl as cl"
]
},
{
"cell_type": "markdown",
"id": "5aebf3dd-81fa-42df-98c9-c92f5af4e489",
"metadata": {},
"source": [
"By default, this sample will run in the first enumerated OpenCL device on the first enumerated OpenCL platform.\n",
"To choose a different OpenCL platform, simply change the platform index or device index to a different value."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "21c2357c-459c-4927-a084-356cece3d78f",
"metadata": {},
"outputs": [],
"source": [
"if __name__ == \"__main__\":\n",
" platformIndex = 0\n",
" deviceIndex = 0\n",
"\n",
" platforms = cl.get_platforms()\n",
" print('Running on platform: ' + platforms[platformIndex].get_info(cl.platform_info.NAME))\n",
"\n",
" devices = platforms[platformIndex].get_devices()\n",
" print('Running on device: ' + devices[deviceIndex].get_info(cl.device_info.NAME))"
]
},
{
"cell_type": "markdown",
"id": "c202b133-e6b9-4368-a00d-caf77b5d61c3",
"metadata": {},
"source": [
"In order to create OpenCL objects we first need to create an OpenCL _context_.\n",
"An OpenCL context describes the state of an OpenCL application.\n",
"Most OpenCL objects created against one context cannot be used in a different context.\n",
"\n",
"To create an OpenCL context we must pass the set of OpenCL devices in the context.\n",
"It is most common to create an OpenCL context for a single OpenCL device, but a context can also be created for multiple OpenCL devices if the devices are in the same OpenCL platform.\n",
"In this example we are going to create an OpenCL context for a single OpenCL device."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "3fdae0d5-2116-4f46-8447-afdb1faeb6cf",
"metadata": {},
"outputs": [],
"source": [
" context = cl.Context([devices[deviceIndex]])"
]
},
{
"cell_type": "markdown",
"id": "74d31f4c-15eb-4f40-8a05-3e5db577e7fd",
"metadata": {},
"source": [
"Now that we have a context we can create an OpenCL command queue.\n",
"An OpenCL command queue is the way to submit work to an OpenCL device.\n",
"To create an OpenCL command queue we must pass the context that the command queue will be created in, and the OpenCL device that the command queue will submit work to.\n",
"We need to pass the OpenCL device becauase the OpenCL context may be created for multiple OpenCL devices."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1613f5d2-a8b5-4f86-b15f-0795694a8b1a",
"metadata": {},
"outputs": [],
"source": [
" commandQueue = cl.CommandQueue(context, devices[deviceIndex])"
]
},
{
"cell_type": "markdown",
"id": "2cd289b3-2edd-476c-931a-2bf405ba3c28",
"metadata": {},
"source": [
"In this example we are going to copy data from one OpenCL buffer to a different OpenCL buffer, on the OpenCL device.\n",
"To do this we need to create a source buffer to copy from and a destination buffer to copy to.\n",
"By default we will copy one million integers, but this can be changed by modifying the constant below."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e327b529-8604-45fd-8496-dbe77151712e",
"metadata": {},
"outputs": [],
"source": [
" numElems = 1024 * 1024\n",
" deviceMemSrc = cl.Buffer(context, cl.mem_flags.ALLOC_HOST_PTR, numElems * np.uint32().itemsize)\n",
" deviceMemDst = cl.Buffer(context, cl.mem_flags.ALLOC_HOST_PTR, numElems * np.uint32().itemsize)"
]
},
{
"cell_type": "markdown",
"id": "d3e1d757-94e0-4fff-bb5e-10118c263acb",
"metadata": {},
"source": [
"There are several ways to modify the data in an OpenCL buffer, but one of the most common ways is to map the buffer so it is accessible on the host.\n",
"We will map the source buffer to initialize its contents.\n",
"Mapping the buffer uses the command queue we created earlier."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a26446e0-3efc-43fc-a3ca-cccf5b496d35",
"metadata": {},
"outputs": [],
"source": [
" mapped_src, event = cl.enqueue_map_buffer(commandQueue, deviceMemSrc,\n",
" cl.map_flags.WRITE_INVALIDATE_REGION,\n",
" 0, numElems, np.uint32)\n",
" with mapped_src.base:\n",
" for i in range(numElems):\n",
" mapped_src[i] = i"
]
},
{
"cell_type": "markdown",
"id": "44a6ce2e-e2ec-4838-b8c1-fb88134b6ce1",
"metadata": {},
"source": [
"With the source buffer initialized, we can finally copy its contents to the destination buffer.\n",
"Copying memory is a common operation so there is a dedicated OpenCL function to perform the copy.\n",
"In a subsequent sample we will explore how to do the copy ourselves, instead.\n",
"For now though, we will simply call the OpenCL function to perform the copy.\n",
"Because the copy is executing on the OpenCL device it also uses the command queue we created earlier."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "85579595-39d4-49bc-88c6-a780416b8762",
"metadata": {},
"outputs": [],
"source": [
" event = cl.enqueue_copy(commandQueue, deviceMemDst, deviceMemSrc)"
]
},
{
"cell_type": "markdown",
"id": "365795d0-332f-464e-8923-adddc7e3cbed",
"metadata": {},
"source": [
"All that remains now is to verify that the copy succeeded!\n",
"To do this, we will map the destination buffer, and check that it has the same data we used to initilaize the source buffer."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e6686f52-ce08-4140-812f-805f4c3fdb7b",
"metadata": {},
"outputs": [],
"source": [
" mapped_dst, event = cl.enqueue_map_buffer(commandQueue, deviceMemDst,\n",
" cl.map_flags.READ,\n",
" 0, numElems, np.uint32)\n",
" with mapped_dst.base:\n",
" mismatches = 0\n",
" for i, val in enumerate(mapped_dst):\n",
" if val != i:\n",
" if mismatches < 16:\n",
" print('Mismatch! dst[{}] == {}, want {}'.format(i, val, i))\n",
" mismatches = mismatches + 1\n",
" if mismatches != 0:\n",
" print('Error: Found {} mismatches / {} values!!!'.format(mismatches, numElems))\n",
" else:\n",
" print('Success.')"
]
},
{
"cell_type": "markdown",
"id": "8c25b94a-f9e3-4916-aca0-a6c15ef61d4e",
"metadata": {},
"source": [
"If the copy executed correctly we expect to find zero mismatching elements."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.12"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
20 changes: 2 additions & 18 deletions samples/python/01_copybuffer/copybuffer.py
Original file line number Diff line number Diff line change
@@ -1,24 +1,8 @@
#!/usr/bin/env python

# Copyright (c) 2019-2021 Ben Ashbaugh
# Copyright (c) 2019-2023 Ben Ashbaugh
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# SPDX-License-Identifier: MIT

import numpy as np
import pyopencl as cl
Expand Down
Loading

0 comments on commit 4148699

Please sign in to comment.