<jupyter_start><jupyter_text>Timing OpenCL kernelsMeasuring the performance of OpenCL kernels is important for finding out how well they peform. The OpenCL framework provides a way to get profiling information from kernels. We re-use the matrix multiplication code for this example. One optimisation that can be applied is to transpose the matrix before using it in the matrix computation as shown in the following figure:          Figure: Matrix transpose as a potential optimisation The theory behind this is that since memory elements in dimension 0 (the row dimension) are contiguous, memory accesses to and from matrix $A$ will be more efficient if $A$ was transposed ($A^{T}$) prior to computing the matrix multiplication. Then an element of matrix C at position $(m,n)$ is computed as the dot product of column $m$ from matrix $A^T$ and column $n$ from matrix $B$. The code [mat_mult_transpose](code/mat_mult_transpose.cpp) has been modified to include two additional kernels that transpose matrix A and use it in the matrix multiplication. It uses the same data as the simple matrix multiplication code, however we regenerate the data here for convenience.<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>After compilation you can just run the code and see how much faster the transposed version is compared to the standard matrix multiply.<jupyter_code>!cd code; ./mat_mult_transpose<jupyter_output>Platform 0: Experimental OpenCL 2.1 CPU Only Platform, vendor: Intel(R) Corporation, version OpenCL 2.1 LINUX
Platform 1: NVIDIA CUDA, vendor: NVIDIA Corporation, version OpenCL 1.2 CUDA 9.1.83
Platform 0 has 1 devices
Platform 1 has 0 devices
Matrix transpose took 9.201738 ms
Standard matrix multiply took 173.220850 ms
Transposed matrix multiply took 57.538626 ms
Transposed approach resulted in a speedup of 2.595444x
RMS difference is 0.000114229
Elapsed time is 0.473087seconds<jupyter_text>Try editing line 77 to switch from CPU devices to GPU devices if you have one available and recompile.from```Ccl_device_type target_device=CL_DEVICE_TYPE_CPU;```to```Ccl_device_type target_device=CL_DEVICE_TYPE_GPU;```<jupyter_code>!cd code; ./mat_mult_transpose<jupyter_output>Platform 0: Experimental OpenCL 2.1 CPU Only Platform, vendor: Intel(R) Corporation, version OpenCL 2.1 LINUX
Platform 1: NVIDIA CUDA, vendor: NVIDIA Corporation, version OpenCL 1.2 CUDA 9.1.83
Platform 0 has 0 devices
Platform 1 has 1 devices
Matrix transpose took 0.166912 ms
Standard matrix multiply took 18.401280 ms
Transposed matrix multiply took 97.909760 ms
Transposed approach resulted in a speedup of 0.187621x
RMS difference is 0.000114286
Elapsed time is 0.492796seconds
{'fraction_non_alphanumeric': 0.07055306427503737, 'fraction_numerical': 0.04394618834080718, 'mean_word_length': 5.732394366197183, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '3', 'dir': 'jupyter-structured-clean-dedup', 'id': '140997', 'license': 'CC-BY-3.0', 'n_tokens_mistral': 1097, 'n_tokens_neox': 963, 'n_words': 416, 'path': 'Timing_kernels.ipynb', 'repo_name': 'drtpotter/opencl_course', 'size': '3345'}