## Kernel Analysis

For GPU code generation, the primary mechanism for creating CUDA® kernels is by using `for`-loops. The way you write loops in your MATLAB® code has a significant impact on the number of kernels created as well as the performance of the generated code. When you generate GPU code, check the diagnostic report to see if your loop segment has `Loop not parallelized` notices. Calls to MATLAB functions in your code may also have `for`-loops that contain these notices. To get maximum performance, you want to ensure that compute intensive loop segments in your code are mapped to kernels and executed in parallel. The following recommendations help you in achieving this goal and generating efficient CUDA kernels.

### Mapping Nested Loops to Kernels

#### Condition

Consider a function that has nested `for`-loops.

```function y = foo(x) ... for i1 = 1:N1 for i2 = 1:N2 for i3 = 1:N3 for i4 = 1:N4 ... end end end end```

Assume that one of the intermediate loop `i3` is not parallelizable. When performs loop analysis to create kernels, GPU Coder™ it considers only the outermost parallel loops `i1,i2` and creates a kernel with the outer loop dimensions `N1,N2`. The loops `i3,i4` are within the kernel body and are executed sequentially. However if the innermost `i4` is large (iteration), then better performance may be achieved by creating kernels for the innermost loop.

#### Action

There are three ways in which you can parallelize the innermost loop:

• Rewrite the code so that the innermost code segment is not within a nested loop.

• If the iteration size of the outer loop is small, then attach the loop to a `coder.unroll` function. This function unrolls the `for`-loop by making a copy of the loop body for each loop iteration. For more information, see `coder.unroll`.

```function y = foo(x) ... for i1 = coder.unroll(1:N1) ... end```
• Make the outer loop dimension as dynamic bound. This way parallel loop analysis fails on the outer loop, whereas it succeeds on the inner loops.

```function y = foo(x,N1) ... for i1 = 1:N1 ... end```

### For-Loops with Break

#### Condition

Loops with break are not supported.

```while (i < N) ... ... if (cond2) ... ... break; end end```

#### Action

Remove breaks by creating a guard variable and conditional.

```cond = true; while (i< N) if(cond) ... ... if(cond2) cond = false; end end end```

### Dependence Analysis Parallel Loop Check Fails

#### Condition

Kernel extraction use parallel loop dependence analysis. There are cases where loop dependence analysis cannot detect a parallel for loop. The `coder.gpu.kernel` allows GPU Coder to override dependence analysis and force kernel creation. The caveat is for user to be sure that the loop is “for-all” loop with no inter-iteration dependencies.

#### Action

Use `coder.gpu.kernel` pragma explicitly on each of your for-loops.

### Logical Indexing of Arrays

#### Condition

GPU Coder may not create kernels when logical indexing is used for accessing array elements.

```i = (mag ~= 0); vx(i) = vx(i)./mag(i); vy(i) = vy(i)./mag(i); ```

#### Action

Rewrite the code by using a loop body and guarding with an appropriate conditional.

```for i = 1:numel(mag) if (mag(i) ~= 0) vx(i) = vx(i)./mag(i); vy(i) = vy(i)./mag(i); end end ```

### Unsupported Functions

#### Condition

Use of unsupported functions, coder pragmas, toolbox functions etc. inside a loop prevents them from becoming a kernel.

#### Action

Try rewriting unsupported functions using pure MATLAB.

### Loop Interchange

#### Condition

If smaller loops in a loop nest are the outer most loops, then a kernel could be created with just a subset of the loops in the nesting. If algorithm allows it, always put the largest loops in the outermost nesting.

#### Action

Rewrite loop nesting with larger loops as outer loops.
{"ft_lang_label":"__label__en","ft_lang_prob":0.77952164,"math_prob":0.87956595,"size":3982,"snap":"2022-27-2022-33","text_gpt3_token_len":930,"char_repetition_ratio":0.13423832,"word_repetition_ratio":0.021276595,"special_character_ratio":0.22677046,"punctuation_ratio":0.14158164,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.96540993,"pos_list":[0],"im_url_duplicate_count":[null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2022-06-26T17:18:33Z\",\"WARC-Record-ID\":\"<urn:uuid:fa802629-2c97-4ba7-9186-49fc5aeb25d4>\",\"Content-Length\":\"78524\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:4ac18e7c-80e1-40c1-814b-96d886ce7c35>\",\"WARC-Concurrent-To\":\"<urn:uuid:590f19b4-ac45-4192-949a-6ea5bc35cbec>\",\"WARC-IP-Address\":\"104.68.243.15\",\"WARC-Target-URI\":\"https://ch.mathworks.com/help/gpucoder/ug/kernel-analysis.html\",\"WARC-Payload-Digest\":\"sha1:3XLTRPRKDLI7PEPHMCVC3AAJKENOVR7L\",\"WARC-Block-Digest\":\"sha1:CVPKPEGCZRCNON3VWCYKOEVP4U6QC4SR\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2022/CC-MAIN-2022-27/CC-MAIN-2022-27_segments_1656103271763.15_warc_CC-MAIN-20220626161834-20220626191834-00167.warc.gz\"}"}