<jupyter_start><jupyter_text>IntroductionIn this tutorial we are going to setup OpenCL to do a simple matrix multiply or $$\textbf{A}\textbf{B}=\textbf{C}.$$ This is a matter of taking the dot product of every m'th row of matrix A with every n'th column of matrix B and storing the result in C at location (m,n) as shown in the figure below.        Figure: simple matrix multiplication Below is some Python code that performs a matrix multiplication and writes the matrices to disk. If you don't have Python installed on your system then don't worry. We can use the files that I made beforehand.<jupyter_code># Code to make the test file
import numpy as np
import os

nrows=1024
ncols=1024

# Make up some arrays of random numbers
matrix_A=np.random.random((nrows, ncols)).astype(np.float32)
matrix_B=np.random.random((nrows, ncols)).astype(np.float32)

# Make up the answer, the resulting Matrix C
matrix_C=np.matmul(matrix_A, matrix_B).astype(np.float32)

# Write the files to grid, notice how I unravel in column major (f) format
# before writing to file
matrix_A.ravel(order="f").tofile(os.path.join("code","array_A_1D.dat"))
matrix_B.ravel(order="f").tofile(os.path.join("code","array_B_1D.dat"))
matrix_C.ravel(order="f").tofile(os.path.join("code","array_C_answer_1D.dat"))<jupyter_output><empty_output><jupyter_text>The source code for the OpenCL example is called [mat_mult_cl.cpp](code/mat_mult_cl.cpp) and is located in the [code](code) directory of this tutorial. We are first going to get this code working, and then we explain every component of the process so you can follow along. In order to keep maximum compatibility across devices we are going to use OpenCL 1.2 with mostly C syntax. We will compile the code with a C++ compiler just in case we would like to use C++ features. The OpenCL 1.2 standard document is available at the following [link](https://www.khronos.org/registry/OpenCL/specs/opencl-1.2.pdf).  Running the codeNow that the application is compiled, run it and observe the results. On my system it shows the following: ```bash./mat_mult_clPlatform 0: Experimental OpenCL 2.1 CPU Only Platform, vendor: Intel(R) Corporation, version OpenCL 2.1 LINUXPlatform 1: NVIDIA CUDA, vendor: NVIDIA Corporation, version OpenCL 1.2 CUDA 9.1.83Platform 0 has 0 devicesPlatform 1 has 1 devicesRMS difference is 0.0001142```The RMS difference is the [root mean squared](https://en.wikipedia.org/wiki/Root_mean_square) difference between the Python result and the OpenCL result. A small number like this means the code worked successfully and there is very little difference between Python and OpenCL. We can check the result by reading the generated matrix (array_C_1D.dat) in and comparing it to the answer from Python (array_C_answer_1D.dat).<jupyter_code>### Checking the result
import numpy as np
import os
import matplotlib.pyplot as plt
% matplotlib notebook

# Read in the two arrays
nrows=1024
ncols=1024

array_C=np.fromfile(os.path.join("code","array_C_1D.dat"), dtype=np.float32)
array_C=array_C.reshape((nrows,ncols), order="f")
array_C_answer=np.fromfile(os.path.join("code","array_C_answer_1D.dat"), dtype=np.float32)
array_C_answer=array_C_answer.reshape((nrows,ncols), order="f")

# Plot the arrays and check the answer
[fig, ax]=plt.subplots(2,2, figsize=(8,6.45), sharex=True, sharey=True)
ax[0,0].set_title("OpenCL result")
ax[0,0].set_ylabel("row")
im1=ax[0,0].imshow(array_C, interpolation="nearest")
fig.colorbar(im1,ax=ax[0,0])
im2=ax[0,1].imshow(array_C_answer, vmin=np.min(array_C), vmax=np.max(array_C_answer), interpolation="nearest")
fig.colorbar(im2,ax=ax[0,1])
ax[0,1].set_title("Python result")
im3=ax[1,0].imshow(np.sqrt((array_C_answer-array_C)**2.0), interpolation="nearest")
ax[1,0].set_title("RMS Difference")
ax[1,0].set_xlabel("column")
ax[1,0].set_ylabel("row")
fig.colorbar(im3, ax=ax[1,0])
fig.delaxes(ax[1,1])
plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11451942740286299, 'fraction_numerical': 0.02632924335378323, 'mean_word_length': 6.063176895306859, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 2, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '270987', 'license': 'CC-BY-3.0', 'n_tokens_mistral': 1340, 'n_tokens_neox': 1275, 'n_words': 423, 'path': 'Basic_application.ipynb', 'repo_name': 'drtpotter/opencl_course', 'size': '3912'}