# Developer Platform

Welcome to your team’s developer platform

<h2 align="center">WedoLow Developer Platform</h2>

<p align="center"><em><strong>Your Copilot for your optimized embedded code</strong></em></p>

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th><th data-hidden data-card-cover data-type="image">Cover image</th></tr></thead><tbody><tr><td><h4><i class="fa-window">:window:</i></h4></td><td><strong>beLow</strong></td><td>Comprehensive C/C++ optimization suite for embedded and hosted applications. Analyze code performance, identify bottlenecks, and automatically implement optimizations to improve execution speed.</td><td><a href="https://docs.wedolow.com/documentation/below/before-we-start">https://docs.wedolow.com/documentation/below/before-we-start</a></td><td><a href="/files/LHIOZGoI6dPF36TuRaxH">/files/LHIOZGoI6dPF36TuRaxH</a></td></tr><tr><td><h4><i class="fa-rotate-exclamation">:rotate-exclamation:</i></h4></td><td><strong>WedoLow MCP Server</strong></td><td>Connect AI Agent to beLow through the Model Context Protocol. Enable AI-assisted code analysis, optimization strategies, and seamless integration with your development workflow.</td><td><a href="https://docs.wedolow.com/documentation/wedolow-mcp-server/before-we-start">https://docs.wedolow.com/documentation/wedolow-mcp-server/before-we-start</a></td><td><a href="/files/IaUMODRBBSBL8eUaPX09">/files/IaUMODRBBSBL8eUaPX09</a></td></tr><tr><td><h4><i class="fa-question">:question:</i></h4></td><td><strong>Ressources</strong></td><td>Get answers to common questions about installation, configuration, and optimization workflows. Find solutions for build system compatibility and integration challenges.</td><td><a href="https://docs.wedolow.com/documentation/ressources/compatibility-guide">https://docs.wedolow.com/documentation/ressources/compatibility-guide</a></td><td><a href="/files/ebMoLMpZFyLqpzByuzrk">/files/ebMoLMpZFyLqpzByuzrk</a></td></tr></tbody></table>

***

{% columns %}
{% column width="41.66666666666667%" %}

<figure><img src="/files/2Dfx5J0xEzbCitdfBLvU" alt=""><figcaption></figcaption></figure>
{% endcolumn %}

{% column width="58.33333333333333%" %}

### What is beLow?

beLow is a comprehensive optimization suite designed for embedded and hosted C/C++ applications. It provides:

**Performance Analysis** - Deep insights into code execution, bottleneck identification, and optimization potential assessment

**Automated Optimization** - Access to multiple algorithmic optimization techniques implemented automatically and rapidly

**Build System Integration** - Compatible with CMake, Makefiles, Bazel, STM32CubeIDE, IAR Embedded Workbench, and more

**Target Platform Support** - Works with ARM Cortex-M/A/R, Intel, PowerPC, and custom embedded platforms

<a href="/spaces/RsAxaJ8tY0k2TfmHaCbZ" class="button secondary" data-icon="book">Documentation</a>
{% endcolumn %}
{% endcolumns %}

***

{% columns %}
{% column width="58.333333333333336%" %}

### Try out our MCP server

Experience the future of AI-assisted C/C++ embedded code generation by connecting beLow to AI Agents through our Model Context Protocol (MCP) server.&#x20;

**Project-Aware Analysis** - Access your complete project structure, dependencies, and compilation environment&#x20;

**Intelligent Optimization** - Apply performance optimization techniques iteratively with real feedback&#x20;

**Automated Metrics** - Gather performance data and refine code automatically&#x20;

**CPU-Targeted Results** - Generate code optimized specifically for your target processor

<a href="/spaces/0QIz5KAqRlqDkZF5bbgo/pages/oYp1QIRSDcjFBJ7nvagD" class="button primary" data-icon="book">Want to know more? </a>&#x20;

{% endcolumn %}

{% column width="41.66666666666668%" %}

<figure><img src="/files/cgwPAoXd6lCGaz8h3hvp" alt=""><figcaption></figcaption></figure>
{% endcolumn %}
{% endcolumns %}

<h2 align="center"></h2>

<h2 align="center"><i class="fa-slack">:slack:</i> Slack Community</h2>

<p align="center">Join our Slack community to share optimization experiences, get help with integration, and connect with other embedded developers using beLow.</p>

<p align="center"><a href="#slack-community-1" class="button primary">Join Slack</a></p>


# WedoLow Developer Platform

### Overview

WedoLow is your copilot for optimized embedded code. Whether you're looking to optimize your C/C++ applications or to integrate AI-assisted code generation into your workflow, you've come to the right place.

### :rocket: Jump right in

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><h4><i class="fa-bolt">:bolt:</i></h4></td><td><strong>beLow  suite</strong></td><td>Everything you need to get started with beLow</td><td></td><td></td><td><a href="/pages/h6Cq7j0z84NY6XMU68dG">/pages/h6Cq7j0z84NY6XMU68dG</a></td></tr><tr><td><h4><i class="fa-leaf">:leaf:</i></h4></td><td><strong>MCP Server</strong></td><td>Learn the basics of our MCP server</td><td></td><td></td><td><a href="/pages/pHiLl2MhFBJ0dANfdtGb">/pages/pHiLl2MhFBJ0dANfdtGb</a></td></tr><tr><td><h4><i class="fa-globe-pointer">:globe-pointer:</i></h4></td><td><strong>Ressources</strong></td><td>Guides, tutorials...</td><td></td><td></td><td><a href="/pages/aOjs4gC5WzIpifbjuGsn">/pages/aOjs4gC5WzIpifbjuGsn</a></td></tr></tbody></table>

***

### Key Features

WedoLow provides a comprehensive optimization and AI-assisted development platform for embedded and hosted C/C++ applications:

* **Performance Analysis**: Deep insights into code execution and optimization potential
* **Automated Optimization**: Multiple algorithmic optimization techniques applied automatically
* **AI-Assisted Code Generation:** Guide your AI agent to automatically generate optimized code
* **Build System Integration**: Compatible with CMake, Makefiles, Bazel, STM32CubeIDE, IAR, and more
* **Target Platform Support**: ARM Cortex-M/A/R, Intel, PowerPC, and custom platforms

### **Real Performance Results**

Proven results from industry leaders:

* [x] &#x20;**-45% execution time** - CNES satellite image processing servers (x86-64)&#x20;
* [x] **-40% execution time** - Bouygues TV box network frame processing (ARM Cortex A9)&#x20;
* [x] **-23% execution time** - Automotive transmission system sensor filtering (Infineon TriCore 299)

Check our case studies [here](https://www.wedolow.com/use-cases)!

***

### Quick Start by Use Case

{% columns %}
{% column %}

#### ⚡ Optimize my  C/C++ code

Explore [**beLow Optimization Suite**](/documentation/below/before-we-start) to discover performance analysis tools, automated optimization techniques, and deep insights into code execution.

* Performance analysis and bottleneck identification
* Automated optimization across multiple algorithms
* Build system integration (CMake, Makefiles, Bazel, and more)
  {% endcolumn %}

{% column %}

#### 🤖 Connect my AI coding Agent

Start with the [**MCP Server**](/documentation/wedolow-mcp-server/before-we-start) section to learn how to connect beLow to AI agents through our Model Context Protocol server.

* Project-aware analysis
* Intelligent code optimization & generation&#x20;
* CPU-targeted results
  {% endcolumn %}
  {% endcolumns %}

### Why Choose WedoLow? <a href="#why-choose-wedolow" id="why-choose-wedolow"></a>

**For Individual Developers**

* Accelerate optimization workflows with AI assistance
* Access professional-grade analysis tools
* Improve code performance with minimal manual effort

**For Development Teams**

* Standardize optimization practices across projects
* Integrate seamlessly with existing CI/CD pipelines
* Scale performance improvements across your codebase

**For Enterprise**

* Professional support and documentation
* Flexible deployment options
* Comprehensive compatibility with enterprise toolchains


# Welcome to WedoLow (old)

#### Advanced C/C++ Code Analysis & Optimization Platform <a href="#advanced-c-c-code-analysis-and-optimization-platform" id="advanced-c-c-code-analysis-and-optimization-platform"></a>

Transform your C/C++ development workflow with **beLow** - our professional-grade static and dynamic analysis platform that delivers measurable performance improvements and CPU-specific optimizations.

### Jump right in

<table data-view="cards"><thead><tr><th></th><th></th><th></th><th data-hidden data-card-cover data-type="files"></th><th data-hidden></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><h4><i class="fa-bolt">:bolt:</i></h4></td><td><strong>beLow Quick Start</strong> </td><td>Everything you need to get started with beLow</td><td></td><td></td><td><a href="/pages/7FvWQMF0kTK7HGhlQfmo">/pages/7FvWQMF0kTK7HGhlQfmo</a></td></tr><tr><td><h4><i class="fa-leaf">:leaf:</i></h4></td><td><strong>MCP Server</strong></td><td>Learn the basics of our MCP server</td><td></td><td></td><td><a href="/pages/pHiLl2MhFBJ0dANfdtGb">/pages/pHiLl2MhFBJ0dANfdtGb</a></td></tr><tr><td><h4><i class="fa-globe-pointer">:globe-pointer:</i></h4></td><td><strong>Ressources</strong></td><td>Guides, tutorials...</td><td></td><td></td><td><a href="/pages/aOjs4gC5WzIpifbjuGsn">/pages/aOjs4gC5WzIpifbjuGsn</a></td></tr></tbody></table>

***

#### What is beLow? <a href="#what-is-below" id="what-is-below"></a>

beLow is a comprehensive technical analysis and optimization platform designed for embedded and high-performance C/C++ development. Our platform provides:

* **Static and Dynamic Code Analysis** - Deep insights into your codebase structure and runtime behavior
* **CPU-Specific Optimizations** - Tailored performance improvements for your target architecture
* **Professional-Grade Tools** - Enterprise-ready analysis capabilities with detailed reporting
* **Build System Integration** - Seamless compatibility with CMake, Bazel, Makefiles, STM32CubeIDE, and IAR Embedded Workbench

**Real Performance Results:**

* [x] &#x20;**-45% execution time** - CNES satellite image processing servers (x86-64)&#x20;
* [x] **-40% execution time** - Bouygues TV box network frame processing (ARM Cortex A9)&#x20;
* [x] **-23% execution time** - Automotive transmission system sensor filtering (Infineon TriCore 299)

Check our case studies [here](https://www.wedolow.com/use-cases)!

***

#### &#x20;WedoLow MCP Server <a href="#introducing-the-wedolow-mcp-server" id="introducing-the-wedolow-mcp-server"></a>

**AI-Powered Code Optimization Made Simple**

**Coming Soon**: Experience the future of AI-assisted development with our Model Context Protocol (MCP) server integration.

**What Makes Our MCP Server Different?**

Unlike standard AI code generation, the WedoLow MCP Server gives AI agents access to professional development tools:

**Project-Aware Analysis** - Access your complete project structure, dependencies, and compilation environment

**Intelligent Optimization** - Apply performance optimization techniques iteratively with real feedback

**Automated Metrics** - Gather performance data and refine code automatically&#x20;

**CPU-Targeted Results** - Generate code optimized specifically for your target processor

**Proven AI-Optimization Results**

In controlled tests with small FFT projects, our MCP server achieved **up to 89% performance improvements** through intelligent, AI-guided optimization techniques.

**How It Works**

1. **Install** the WedoLow MCP package to your development environment
2. **Configure** your project with a simple configuration file or make your AI agent generate it for you
3. **Ask** your AI agent to optimize your code using beLow tools
4. **Get Results** - Your code is analyzed, optimized, and ready for production

**Supported AI Platforms**

Our MCP server has been tested and verified with:

* **GitHub Copilot** (VS Code & JetBrains) with GPT-4.1 and Claude Sonnet 4
* **Gemini CLI** and Gemini Pro 2.5
* **Junie (Beta)** (JetBrains - CLion) with GPT-5, Claude Sonnet 3.7 and Claude Sonnet 4
* Compatible with other MCP-enabled AI agents

***

#### 🛠️ Platform Compatibility <a href="#platform-compatibility" id="platform-compatibility"></a>

**Operating Systems**

* Windows 10, 11
* Ubuntu 20.04, 22.04, 24.04
* RHEL 8

**Build Systems**

* CMake
* Bazel (with acyclic query graph support)
* Makefiles (Windows compatible)
* STM32CubeIDE
* IAR Embedded Workbench for ARM
* Custom Docker environments

***

#### 📚 Getting Started <a href="#getting-started" id="getting-started"></a>

Ready to accelerate your C/C++ development? Explore our comprehensive documentation:

**Core Platform**

* **Installation Guide** - Get beLow running on your system
* **Getting Started** - Your first analysis and optimization
* **Compatibility Guide** - Ensure your tools work seamlessly

**Advanced Features**

* **Build System Integration** - Connect with your existing workflow
* **Performance Analysis** - Deep dive into optimization capabilities
* **Troubleshooting** - Solutions to common challenges

**MCP Server (Beta)**

* **MCP Server Overview** - Understand AI-powered optimization
* **Beta Program** - Join our exclusive testing program
* **API Documentation** - Technical integration details

***

#### 🎯 Why Choose WedoLow? <a href="#why-choose-wedolow" id="why-choose-wedolow"></a>

**For Individual Developers**

* Accelerate optimization workflows with AI assistance
* Access professional-grade analysis tools
* Improve code performance with minimal manual effort

**For Development Teams**

* Standardize optimization practices across projects
* Integrate seamlessly with existing CI/CD pipelines
* Scale performance improvements across your codebase

**For Enterprise**

* Professional support and documentation
* Flexible deployment options
* Comprehensive compatibility with enterprise toolchains

***

#### 🔗 Next Steps <a href="#next-steps" id="next-steps"></a>

1. **Install beLow** and experience professional C/C++ analysis
2. **Join our** [**MCP Beta Program**](https://tally.so/r/3jKQWR) for early access to AI-powered optimization
3. **Explore our tutorials** to master advanced optimization techniques

***


# Before we start

## beLow - Comprehensive Optimization Suite

beLow is a comprehensive optimization suite designed for **embedded and hosted C/C++ applications.** Get deep insights into performance, identify bottlenecks, and apply automated optimizations.

### Core Capabilities:

{% columns %}
{% column %}

#### Performance Analysis

* Deep insights into code execution patterns
* Bottleneck identification
* Optimization potential assessment
* Detailed metrics and profiling data
  {% endcolumn %}

{% column %}

#### Automated Optimization

* Access to multiple algorithmic optimization techniques
* Rapid optimization application
* Real-time performance feedback
* Iterative refinement
  {% endcolumn %}
  {% endcolumns %}

### Optimization Families

beLow analyzes your code and applies optimizations across five key families:

<table data-view="cards"><thead><tr><th></th><th></th></tr></thead><tbody><tr><td><strong>Memory Management</strong> </td><td>Reduce allocations, eliminate unnecessary copies, improve cache performance, and boost CPU efficiency through better memory usage.</td></tr><tr><td><strong>Arithmetic &#x26; Mathematical</strong></td><td>Use appropriate data types, replace expensive operations, and leverage hardware capabilities for faster math on embedded processors.</td></tr><tr><td><strong>Loop &#x26; Vectorization</strong></td><td>Transform loops for parallel execution with SIMD instructions and better utilization of modern processor capabilities.</td></tr><tr><td><strong>Compiler &#x26; Code Gen</strong></td><td>Optimize control flow and function calls for more efficient assembly code and processor-specific optimizations.</td></tr><tr><td><strong>Type System &#x26; Casting</strong></td><td>Eliminate hidden type conversions and enable architecture-specific features for your target embedded platform.</td></tr></tbody></table>

Each optimization is categorized by quality impact—bit-exact (no quality loss), permissive (identical quality but different computation type), or lossy (quality loss). beLow generates SNR metrics so you can verify quality loss is acceptable for your application.


# QuickStart

This guide will show you how to start and use the solution on a simple example, with a full local installation.

First, the product must be locally installed on your machine. If not already done, please refer to the [installation guide](/documentation/below/installation-guide).


# Start beLow

On a local installation, starting beLow server and runners is simplified by the use of the beLowCTL application.

{% hint style="info" %}
Before running beLowCTL, please make sure that Docker service is running.
{% endhint %}

{% tabs %}
{% tab title="Linux" %}
If using Gnome, open the Activities menu and click on beLowCTL.

![beLowCTL on Gnome](/files/03d7eb63c1b7594750a5e2f5797674d1b255a322)

Alternatively, run beLowCTL from a terminal to see live logs (useful for troubleshooting or support requests):

{% code title="Terminal" %}

```bash
belowctl
```

{% endcode %}

Running beLowCTL graphically requires the AppIndicator extension to be enabled (name may vary by UI environment).

{% hint style="warning" %}
On RHEL8 the graphical version of beLowCTL is not available. Prefer the terminal version or run the "beLowCTL - Headless" application instead.
{% endhint %}

When beLowCTL is running (graphical or terminal), an icon appears in the system tray (top bar on Gnome). Click the icon and then click Start in the menu to start beLow services.

![beLowCTL tray and Start](/files/4a6fe7a8be26c3978679290f0d365afd75df7797)

Running beLow services for the first time can take a few minutes depending on internet speed and CPU performance because Docker images need to be downloaded and extracted.

To run the beLow UI after services are started, open the beLow application from Activities / Start menu.

![beLow start page](/files/6d8558a8a38f64ddf679d5c0853246d5f088fe0b)
{% endtab %}

{% tab title="Windows" %}
Click on beLowCTL in the Start menu.

![beLowCTL on Windows Start menu](/files/bd5276a37307b19903e36df586ce6b408e2f1d94)

Alternatively, run beLowCTL from a terminal to see live logs (useful for troubleshooting or support requests):

{% code title="Terminal" %}

```bash
belowctl-cli
```

{% endcode %}

When beLowCTL is running, an icon appears in the system tray (bottom-right icons on Windows). Click the icon and then click Start in the menu to start beLow services.
{% endtab %}
{% endtabs %}

{% stepper %}
{% step %}

### Start beLow services

1. Launch beLowCTL (graphical or terminal).
2. Click the system tray icon and choose Start (or use the terminal command which shows live logs).
3. Wait for Docker images to download and services to initialize (first run may take several minutes).
   {% endstep %}

{% step %}

### Open beLow UI

After services are started, open the beLow application from Activities / Start menu to access the login page and UI.
{% endstep %}
{% endstepper %}

If you encounter problems running the services or the UI, see the Troubleshooting section: <https://docs.wedolow.com/below-technical-documentation/faq-troubleshooting/troubleshooting>

Let's now sign up and [log in to beLow](/documentation/below/quickstart/sign-up-log-in).


# Sign up/log in

When running beLow UI, a log in page appears.

![beLow start page](/files/49287fa69a5da93c5a3ee5654334abaeea2004bf)

{% stepper %}
{% step %}

### Create an account

To create an account, click on **Create an account**. On the account creation page, fill up the form and validate it.

![Account creation page](/files/28a73ea1ab51e847526c7e202213af89a99458c9)
{% endstep %}

{% step %}

### Email validation

After validating, a 6-digit code is sent to your email address.

{% hint style="info" %}
If you don't receive the email address validation email after a few minutes, please check your spam folder.
{% endhint %}

![Email validation](/files/257b669c8d24579414c9b565c2b637f40f37ba50)
{% endstep %}

{% step %}

### Account verification

Once validated, you reach the verification page.

![Account verification](/files/52d4a877d89138675b26fb11cc9db0e401945ac4)

As stated, a member of the WedoLow team needs to validate your account to authorize your access to beLow. You may either stop beLow while waiting or keep it open.
{% endstep %}

{% step %}

### Welcome page

Once authorization is given, the welcome page appears. Click **Next** to reach server URL setup.

![beLow welcome page](/files/f43e87cb345afcefd4d7ab6bff46bf88cb77be82)
{% endstep %}

{% step %}

### Server URL setup

Leave the URL empty to use the default address, activate **Remember my choice** and click **Connect to server**.

![beLow server URL setup](/files/1799f4562e970959a219c889527552ccbe5719eb)
{% endstep %}

{% step %}

### All done

beLow is ready! Click **Continue** to start using beLow.

![beLow is ready](/files/5942fde0a6d088e96fc5e0125d9b70217ec21294)
{% endstep %}
{% endstepper %}

Let's now [setup a new project](/documentation/below/quickstart/setup-a-new-project).


# Run an analysis

### Analysis process

After setting up the ***FFT-C*** project, you end up on the following page.

![FFT-C project details](/files/46752150cf52f49dd9178f95dffdf295b808104c)

Clicking on any element of the project will take you back to the configuration tunnel, allowing you to change any parameter at any time. In general, changing a parameter will require you to redo the rest of the tunnel, as most of the steps depend on the previous choices.

To run the analysis, click on ***Run analysis***.

![Analysis is running](/files/fb7ed77bc7b87a7e632db438d81660f61e18ce41)

{% stepper %}
{% step %}

### Static analysis

The source files and the compiled binary objects are related to produce an omniscient representation mapping each code statement to the associated instructions. The instructions are statically characterized in terms of functionality and impact, and by consequence, the associated code too.
{% endstep %}

{% step %}

### Dynamic analysis

The code is instrumented, built and executed to produce profile data.
{% endstep %}

{% step %}

### Fusion of static and dynamic data

Static and dynamic analysis data are fused so both can be leveraged through cost models, estimating self and cumulative costs for each function.
{% endstep %}

{% step %}

### Optimization potential detection

Optimization potentials are researched based on identification of advanced code patterns, knowledge of instruction costs for the target, and possible target-specific instructions.
{% endstep %}
{% endstepper %}

***

### Analysis results

#### General results

![Analysis is done](/files/b97c118a075986324cc1ce6a337ac186f307aaf2)

After the analysis is over, which can take some time depending on the project and analysis mode, you can see an estimation of how much the code could benefit in terms of performance (here **9.5%**). This result can be obtained by applying the **14 detected optimization points**.

Click ***See latest analysis*** to view further details.

#### Analysis dashboard

![](/files/0998016e868e7cf5e23ec971a1d6bef0bb071554)

![](/files/cc18332f6bca84a8250692bb80d1bdd0938fbbb4)

The analysis dashboard contains useful information about the code.

* The three first tiles represent the **potential gain score**, indicating possible improvements in performance (and energy) by applying optimizations in your source code.
* Each tile corresponds to a kind of optimization:
  * Bit-exact: optimizations that do not change application outputs (safe, no trade-off).
  * Permissive: may change binary representation of outputs without degrading quality (e.g., different data types or math functions).
  * Lossy: modify accuracy (e.g., float→fixed, polynomial approximations, smaller data sizes). These can yield large performance gains but come with accuracy trade-offs.

The **Detected optimization kinds** tile shows details about which optimizations were detected and their implications.

You may also see estimated **CPU cycles** for your program and its functions, both self and cumulative costs.

Functionality repartition shows how your code behaves over time: for each function, the relative weight of calculations, memory, or control instructions. This helps prioritize optimization efforts (e.g., a function heavy on memory operations when you expect it to be compute-bound may suggest problematic memory access patterns).

Code coverage informs:

* Static coverage: which parts of code map to machine instructions (helps identify statically dead code).
* Dynamic coverage: which parts were executed during dynamic analysis (helps assess if execution was representative).

![Call graph](/files/b17db5d33a48154deb603f7adf8dd4a08df5ada6)

A call graph summarizes all information. Functions shown in red and orange are the most costly and indicate where to focus optimization efforts first.

Once you've analyzed your code, you can [run the optimization](/documentation/below/quickstart/run-an-optimization).


# Run an optimization

{% stepper %}
{% step %}

### Analysis results

![](/files/644c8770b6fb53709a022de3bec0da2d9b04f07d)

On the analysis dashboard, click on *Optimize*.
{% endstep %}

{% step %}

### Optimization strategy settings

![](/files/078769a0583fd8b40dae192144ef703b863c7613)

On the optimization strategy page, you can see the details of all optimizations that were found on your code, and generate code for the ones that are automatically optimizable.

![](/files/2289ca5bc33e332d09db54b2eadf14dc4304cd6b)
{% endstep %}

{% step %}

### See optimization details

![](/files/e495fc95bbf3d0bab1cf92cb7fd1ef6ae6cf626e)

In the file tree, you may enter the files and functions where optimizations were found. For that, click on *See details*.

![](/files/7e74cbc05b49a71ca26e87f3687f332cc8f4f8e8)

There, you can see the optimizations that were found, where they have impact on the code, what parts of the code are concerned by the optimizations and how they work. Go back to the optimization strategy by clicking on the top left arrow.
{% endstep %}

{% step %}

### Go to optimization kinds selection

![](/files/1303c12646ecd601bfa5d79152b1e5c46c196efd)

On the main page, clicking on *Optimization kinds selection* on the project root, any directory, file or function allows to activate or not optimizations on that level. Click on it on the project root.

![](/files/1303c12646ecd601bfa5d79152b1e5c46c196efd)

There, activate all available automatic optimizations, and click on *Confirm*.
{% endstep %}

{% step %}

### Optimization preview

![](/files/c0945b67d610bcd995269fe86cbcfea939d6c2ac)

Click on the play button to start an optimization score preview. This way, you can have a quick estimation of the gains given the optimizations which were activated in your strategy.

![](/files/72c3b98ef8cb59c97b7eba180c231d216afd3676)

After a few seconds, we can see that automated optimizations could bring an estimated 9.2% performance improvement in the FFT-C code.
{% endstep %}

{% step %}

### Run the optimization

![](/files/70b3cc24930973160206fa3ddd6b90463521db18)

Click on *Run optimization* to actually generate modified source code implementing the selected optimizations.

At that point, you can click on *Download code* to get the optimized code.
{% endstep %}

{% step %}

### Optimized code analysis

![](/files/1436f2e5c933b23f56f5274c7b41d2109bf7af50)

To go further, you can run a new analysis on the optimized code to acknowledge better the impact of the newly generated code.

Click on *Run analysis*. After that, you can see the same metrics as for the initial analysis, but for the optimized code, to see the actual effects of the optimizations.

For instance, you can see that now, the app\_exec top function is estimated to take 7.92K cycles, while it originally took 8.62K cycles, leading to an 8.2% improvement. You can also check how the functionality repartition has changed.
{% endstep %}

{% step %}

### Code diff

![](/files/8e5b533d4fd00a1f7407318b9ab7625d642d9f13)

By coming back to the optimization details, in the file tree, you may click on *Compare file* to see the code difference between before and after optimization.

![](/files/21405cdf2541e7586ca289660702c12b1cb492c2)

Now, you may take advantage of the optimized code as you wish.

Don't forget to have a look at non-automatic optimizations too, so you can understand what is the problem and take decisions about what you could or could not be changing to improve your code performance even better.
{% endstep %}
{% endstepper %}


# Setup a new project

## Get the example project

For this example, we will use a code sample from the following open-source project: [here](https://github.com/wedolow/Codes-Samples).

You may retrieve it using any of these methods:

* Using the following command:

  ```bash
  git clone https://github.com/wedolow/Codes-Samples
  ```
* Downloading the latest version as a zip [here](https://github.com/wedolow/Codes-Samples/archive/refs/heads/main.zip) and unzipping it.

The code used in this example is contained in the subfolder `FFT-C`. This code implements a CPU-based Fast Fourier Transform algorithm, includes a Makefile to build it, and contains test cases to stimulate the algorithm.

{% hint style="info" %}
The code does **not** need to be able to build or run on your own system, as we will be using a Debian 11 Docker container for build, run, analysis and optimization, provided to you by WedoLow.
{% endhint %}

***

## Create a new project

{% stepper %}
{% step %}

### Open projects page and create a new project

Once logged in, you end up on the projects page.

![beLow projects page](/files/23fa8f1e626beb6ca87c4220b2e0c2228df4f85e)

Click on **Create a new project**.
{% endstep %}

{% step %}

### Enter project name and description

Enter a project name (for example: `FFT-C`), an optional description and click **Next**.

![Project name and description settings](/files/0ef7af3a5002cca0f3bdbfb548e894cfc64512bf)
{% endstep %}

{% step %}

### Select project mode and version

Select **Copy the project** and enter a version name.

* In *Copy* mode, beLow works on a copy of your project.
* In *Local* mode, it works directly in the project's directory (only possible for projects that can build on your own system).

![Project mode and version settings](/files/897cabcefd6ee6204b3f0fd1addd78e1e7a91258)
{% endstep %}

{% step %}

### Select the source folder

Provide the root directory of your project by either:

* Clicking **Browse** and selecting the `FFT-C` directory, or
* Drag-and-dropping the `FFT-C` directory from your file explorer.

Click **Confirm and next**.

![Source directory selection](/files/4f03845b0cfeb4113f08cf8404e85686300e0f5e)
{% endstep %}
{% endstepper %}

***

## Target platform, analysis and execution setup

In each project setup, define two platforms:

* Build platform: the system where all build actions, analyses and optimizations occur.
* Target platform: the system where the compiled code executes.

Example: if cross-compiling on Windows for a Raspberry Pi:

* Build platform: Windows (x86\_64 Intel Skylake)
* Target platform: Linux (AARCH64 Cortex-A53 ARMv8)

In this `FFT-C` example, build and target platforms are the same: Debian 11 Linux on x86\_64.

Even if your PC is not Skylake, select Skylake as a representative generic x86\_64 architecture.

![Platform and analysis settings](/files/d3b0bc8e5ed0456aaf36b5ee9ce570b7cb04f97d)

On the platform selection page:

* Select "Linux System - Debian GNU/Linux 11 (bullseye) - x86\_64 - Intel skylake".
* Activate "Dynamic analysis (auto)" so beLow automatically manages dynamic traces and profiling.
* Activate "Restructuring optimizations" to enable search for additional code optimizations when beLow can build/execute the project in a closed loop.

Click **Confirm and next**.

***

### Run script setup

Decide whether the execution script runs on the build platform or on the target platform.

* If on the build platform, the script must send the compiled binary to the target, execute it, and retrieve profiling data.
* If on the target platform, a beLow runner must be present to run and retrieve profiling data.

In this example the build and target are the same, so either option works.

Our test bench is the binary `app_test.exe` at the project root. Configure the run script as follows:

* Script content:

```bash
./app_test.exe
```

* Script execution path: (project root — leave empty)
* Shell: Bash or Sh

Click **Confirm and next**.

![Run script settings](/files/18cef87466c9a0c8badd86bab1db8439cdde2237)

***

### Target options

You may choose to install software/packages or inject environment variables on the target platform. For this example, no target additions are needed.

Click **Confirm and next**.

![Target options](/files/c919cdf635a6df3515732affdcdb6cc6fd06eff2)

***

## Build platform and build settings

![Build platform selection](/files/a8c6f4afea699b6aee40023269fd14a5c98ce3e7)

On this screen select the build platform. You may see two possible platforms:

* Linux System - Debian GNU/Linux 11 (bullseye) - x86\_64 - Any CPU (a Dockerized platform provided by beLow)
* Another platform corresponding to your own system

Select **Linux System - Debian GNU/Linux 11 (bullseye) - x86\_64 - Any CPU** and click **Confirm and next**.

***

### Build options — install required software

In build options, you need to install a package `check` required by the `FFT-C` build process.

* Unroll the "Software to install" section and wait while the package list loads (the first time the Debian 11 Docker image is downloaded/extracted — may take a few minutes).
* Use the search bar to find the `check` package and select it.
* Click **Confirm and next**.

![Build options](/files/0c9871fc277dc52b21f7c1e4720a15378c8c22ca)

***

### Build scripts setup

Tell beLow how to build the project for the selected target.

* Configure section: leave blank (no configuration required).
* Clean section:
  * Script content:

    ```bash
    make clean
    ```
  * Script execution path: project root (leave empty)
  * Shell: Bash or Sh

A clean script is optional but can help beLow understand the compilation process and run operations from a clean state.

* Build section:
  * Script content:

    ```bash
    make app_test.exe
    ```
  * Script execution path: project root (leave empty)
  * Shell: Bash or Sh

Click **Confirm and next**.

![Build scripts setup](/files/ad048bc42e98de1a805ff6dfc7d759427e6c8a0a)

***

### Build platform build and run scripts (for restructuring optimizations)

Because "Restructuring optimizations" is activated, provide build scripts that run on the build platform and how to run the executable on the build platform.

In this example the build and target platforms are the same, so these scripts are identical to the previous ones.

* Configure: leave blank
* Clean:

  ```bash
  make clean
  ```
* Build:

  ```bash
  make app_test.exe
  ```
* Run:

  ```bash
  ./app_test.exe
  ```
* Script execution path: project root (leave empty)
* Shell: Bash or Sh

Click **Confirm and next**.

![Host build scripts](/files/3254071470175500ca6bfd74f0ebaf7b6ee43a56)

***

## Build and exploration process

After setup, jobs are triggered to:

* Test your project build
* Attempt to understand your build actions
* Explore source code to identify functions and hierarchy

When the job finishes, you will see a table with the list of all project functions.

Select a top function that represents the highest level in the hierarchy to be analyzed/optimized. All functions called by this function (recursively) will be considered. Functions in independent graphs or upstream of the top function graph will not.

Click **View function tree** to inspect how functions relate (optional).

![Function tree](/files/6c078850188f619bd8d72f1db456d5dc9b153db0)

Close the graph when done.

In this example, select `app_exec` as the top function. The functions that call it are test bench setup functions that do not need optimization, and `app_exec` is the entry point for FFT function calls of interest.

![Top function selection](/files/8a32ac9643d4cfc2fff615f2b374a6265eb3cac0)

Leave quality settings untouched in this example.

After a short post-processing job, your project setup is complete. Proceed to run an analysis as described in your workflow.


# Installation guide

{% stepper %}
{% step %}

### Check compatibility

Check that your projects are [compatible with beLow](/documentation/ressources/compatibility-guide).
{% endstep %}

{% step %}

### Understand installation modes

Be sure to understand [possible installation modes](/documentation/below/installation-guide/installation-modes).
{% endstep %}

{% step %}

### Install the product

Proceed to the [installation of the product](/documentation/below/installation-guide/installation-instructions).
{% endstep %}
{% endstepper %}


# Installation modes

### Possible installation modes

The solution may be used two different ways:

* As a fully local solution
* As a distributed solution

The product is constituted of three elements:

* The server: it is unique and is necessary to make everything work together.
* The runners: they may be on the same machine as the server or not, they may be native or dockerized. They are required to run beLow's jobs in the contexts that you need: building your code, analysing your code, running your code, etc.
* The user interface (UI)

***

### Local solution

With this solution, everything is running on your machine and remains on your machine, except for authentication and licensing verification. Installing and running the local solution is very simple. Just follow the requirements and installation instructions for Linux or Windows, and the Getting started guide.

![Local solution scheme](/files/a45503a8a65937deb6f68d09074baf6db180ac79)

***

### Distributed solution

This solution allows you to run the server, runners and UI on different machines of the same network.

![Distributed solution scheme](/files/de002a55d4196111afc94add42452a79ad1e3a20)

In this section, we give the details on how to run the different required services on 3 machines, and make them work together:

* Server machine: hosts the central server part of the solution and exposes public APIs
* Runner machine: hosts a native runner
* UI machine: hosts the UI

For all three machines, make sure that you install everything that is needed on Linux or Windows. For what is next, we suppose that everything is correctly installed. If any command listed in this guide is not available in your terminal, please check your installation or contact WedoLow's support.

### Run the server

The server machine must be exposed to your users on their network. First decide the public endpoint for this server (numerical IP or DNS). Example used below: below-server.mycompany.org. We strongly advise protecting the server with HTTPS and using a reverse proxy to expose beLow server.

Create the following file if it does not exist yet:

{% tabs %}
{% tab title="Linux" %}

```bash
${HOME}/.config/wedolow/config.json
```

{% endtab %}

{% tab title="Windows" %}

```batch
%userprofile%\AppData\wedolow\config.json
```

{% endtab %}
{% endtabs %}

Fill this file with the following information (set `insecure` to `true` if you are using HTTP):

{% code title="config.json" %}

```json
{
    "core": {
        "s3": {
            "public_endpoint": "below-server.mycompany.org:19080",
            "insecure": false
        }
    }
}
```

{% endcode %}

{% tabs %}
{% tab title="Linux" %}
{% hint style="info" %}
To get current server configuration, run the following command:

```
belowctl-headless print-config
```

Any value of this configuration can be overriden in `config.json`file.
{% endhint %}
{% endtab %}

{% tab title="Windows" %}
{% hint style="info" %}
To get current server configuration, run the following command:

```
belowctl-headless-cli.exe print-config
```

Any value of this configuration can be overriden in `config.json`file.
{% endhint %}
{% endtab %}
{% endtabs %}

Once configured, you may now start the server. Docker service must be running and accessible:

{% tabs %}
{% tab title="Linux" %}

```
belowctl-headless server start
```

or to start in detached mode:

```
belowctl-headless server start -d
```

{% endtab %}

{% tab title="Windows" %}

```
belowctl-headless-cli.exe server start
```

or to start in detached mode:

```
belowctl-headless-cli.exe server start -d
```

{% endtab %}
{% endtabs %}

To check if server is running, run:

{% tabs %}
{% tab title="Linux" %}

```
belowctl-headless server status
```

{% endtab %}

{% tab title="Windows" %}

```
belowctl-headless-cli.exe server status
```

{% endtab %}
{% endtabs %}

which returns:

```json
{
  "state": "Running",
  "details": {
    "core": {
      "state": "Running",
      "docker_status": "Up 2 minutes (healthy)",
      "docker_state": "running"
    },
    "gateway": {
      "state": "Running",
      "docker_status": "Up 2 minutes",
      "docker_state": "running"
    },
    "minio": {
      "state": "Running",
      "docker_status": "Up 2 minutes (healthy)",
      "docker_state": "running"
    },
    "postgres": {
      "state": "Running",
      "docker_status": "Up 2 minutes (healthy)",
      "docker_state": "running"
    }
  }
}
```

To check if your server is accessible from a distant machine, you may try to contact the health endpoint from the main public API (to be adapted to your http scheme):

```bash
curl https://below-server.mycompany.org:18080/core/health
```

This should succeed with this kind of response:

```json
{
  "is_running": true,
  "build_information": {
    "date": "2024-11-22T09:44:43+0000",
    "git_hash": "21e87879b46995ac80b46c95765b974195bcd7f5",
    "version": "v1.5.5"
  },
  "services": [
    {
      "is_running": true,
      "name": "core"
    }
  ]
}
```

{% hint style="info" %}
Server services are run as Docker containers. Depending on your Docker configuration, services will continue to be available and running even after a reboot as long as you don't stop the server.
{% endhint %}

To stop the server, for instance for an update, run:

{% tabs %}
{% tab title="Linux" %}

```
belowctl-headless server stop
```

{% endtab %}

{% tab title="Windows" %}

```
belowctl-headless-cli.exe server stop
```

{% endtab %}
{% endtabs %}

### Add a runner

Runners are necessary to run jobs. There should at least be one declared and running in the whole system.

To register a runner, a token must be generated on the server machine by an administrator.

To do this, **on the server machine**, run the following command:

{% tabs %}
{% tab title="Linux" %}

```
belowctl-headless server get-registration-token --description "My first runner"
```

{% endtab %}

{% tab title="Windows" %}

```
belowctl-headless-cli.exe server get-registration-token --description "My first runner"
```

{% endtab %}
{% endtabs %}

This returns a token in the following form:

```json
{"token": "123XY"}
```

Remember this token.

**Get back to the runner machine**, where you must now configure, register and run the runner.

Create a directory where you want, e.g. called `below-runner` .

Inside this directory, create a file called `config.json` , with the following content:

{% tabs %}
{% tab title="Linux" %}

```json
{
  "version": "1.0.0",
  "dev_mode": false,
  "runner_mode": "local",
  "db": {
    "path": "/path/to/runner/runner-local.db"
  },
  "log": {
    "file": "/path/to/runner/logs.txt",
    "level": "info"
  },
  "core": {
    "url": "https://below-server.mycompany.org:18081/corerunner"
  },
  "s3": {
    "endpoint": "below-server.mycompany.org:19080",
    "endpoint_orchestrator": "below-server.mycompany.org:19080",
    "insecure": false,
    "region": "fr-par"
  },
  "orchestrator": {
    "local": {
      "exec_path": "/usr/local/bin/below-orchestrator",
      "llvm_mca_exec_path": "/usr/local/bin/below-llvm-mca",
      "clang_resource_dir": "/usr/local/lib/below-clang",
      "arm_none_eabi_include_dir": "/usr/local/arm-none-eabi/include"
    }
  },
  "workers": {
    "job_concurrency": 1,
    "job_fetch_period": "3s",
    "job_status_update_period": "1s"
  }
}
```

Replace `/path/to/runner` with the absolute path of the `runner` directory you just created. Also adapt the public URL of the server where it appears (`below-server.mycompany.org`), the http scheme and `insecure field`.
{% endtab %}

{% tab title="Windows" %}

```json
{
  "version": "1.0.0",
  "dev_mode": false,
  "runner_mode": "local",
  "db": {
    "path": "C:\\path\\to\\runner\\runner-local.db"
  },
  "log": {
    "file": "C:\\path\\to\\runner\\logs.txt",
    "level": "info"
  },
  "core": {
    "url": "https://below-server.mycompany.org:18081/corerunner"
  },
  "s3": {
    "endpoint": "below-server.mycompany.org:19080",
    "endpoint_orchestrator": "below-server.mycompany.org:19080",
    "insecure": false,
    "region": "fr-par"
  },
  "orchestrator": {
    "local": {
      "exec_path": "below-orchestrator.exe",
      "llvm_mca_exec_path": "below-llvm-mca.exe",
      "clang_resource_dir": "C:\\Program Files\\beLow\\runner\\clang",
      "arm_none_eabi_include_dir": "C:\\Program Files\\beLow\\runner\\arm-none-eabi\\include"
    }
  },
  "workers": {
    "job_concurrency": 1,
    "job_fetch_period": "3s",
    "job_status_update_period": "1s"
  }
}
```

Replace `C:\\path\\to\\runner` with the absolute path of the `runner` directory you just created. Also adapt the public URL of the server where it appears (`below-server.mycompany.org`), the http scheme and `insecure field`.
{% endtab %}
{% endtabs %}

You may already theck that the runner is succesfully contacting the server by running in a terminal:

{% tabs %}
{% tab title="Linux" %}

```
below-runner runner -c /path/to/runner/config.json is-registered
```

{% endtab %}

{% tab title="Windows" %}

```
below-runner.exe runner -c C:\path\to\runner\config.json is-registered
```

{% endtab %}
{% endtabs %}

The command should run with no error and print:

```json
{
  "registered": false,
  "registration_update_required": true,
  "runner": null
}
```

You may now register the runner using the token you got on server side:

{% tabs %}
{% tab title="Linux" %}

```
below-runner runner -c /path/to/runner/config.json register "123XY"
```

{% endtab %}

{% tab title="Windows" %}

```
below-runner.exe runner -c C:\path\to\runner\config.json register "123XY"
```

{% endtab %}
{% endtabs %}

If command succeeds, your runner is successfully registered to server.

Now, you can run your runner the following way:

{% tabs %}
{% tab title="Linux" %}

```
below-runner runner -c /path/to/runner/config.json start --self-update
```

{% endtab %}

{% tab title="Windows" %}

```
below-runner.exe runner -c C:\path\to\runner\config.json start --self-update
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
It is currently not possible yet to run the runner in detached mode. To run it as a service, please use the recommended way for your OS, e.g using [systemd](https://linuxhandbook.com/create-systemd-services/) for compatible Linux distributions, or creating a [Windows service](https://learn.microsoft.com/en-us/dotnet/framework/windows-services/walkthrough-creating-a-windows-service-application-in-the-component-designer). The easiest way for now is to let the runner command active in a minimized terminal.
{% endhint %}

To stop the runner gracefully, send a termination signal to the running command (CTRL+C in the terminal for instance).

### Limitations

In the product, when starting a new version for a project, you may choose between two modes:

* Copy mode
* Local mode

<figure><img src="/files/nd6txeQsUUvlfUMc6ZmN" alt=""><figcaption><p>Choosing between Copy mode or Local mode</p></figcaption></figure>

When beLow is fully installed on a unique machine, Local mode always works.

However, in distributed mode, Local mode only works if the jobs are run on the same machine as the UI. The following pattern will **not work** then:

* If you choose a build platform which is not compatible with the local runner
* If you choose a target platform which is not compatible with the local runner, in *dynamic auto* analysis mode
* If you choose any of both platforms described above that are also available on a distant runner. In this case, you may use the ***tags*** system while selecting the platforms, to target the local runner. To do so, when registering a new runner, you may add `--tag <your-tag>` (repeatable) in the registration command to add custom tags that you can identify, or use auto-generated tags such as `hostname:<your-machine-hostname>` tag.

<figure><img src="/files/ny2rRp6Wz1iVgmwrSE10" alt=""><figcaption><p>Forcing the usage of your local runner by hostname selection</p></figcaption></figure>


# Installation instructions

Welcome to beLow's installation instructions.

{% hint style="info" %}
Before installing, make sure to understand the different [possible installation modes](/documentation/below/installation-guide/installation-modes).
{% endhint %}

{% tabs %}
{% tab title="Linux" %}
Follow the Linux installation guide:

<https://docs.wedolow.com/below-technical-documentation/readme/installation-instructions/linux>
{% endtab %}

{% tab title="Windows" %}
Follow the Windows installation guide:

<https://docs.wedolow.com/below-technical-documentation/readme/installation-instructions/windows>
{% endtab %}
{% endtabs %}

Last updated 8 months ago


# Linux

Welcome to beLow's Linux installation guide.

Quick links:

* [Requirements](/documentation/below/installation-guide/installation-instructions/linux/requirements)
* [Installation](/documentation/below/installation-guide/installation-instructions/linux/installation)

Last updated: 1 year ago


# Requirements

Minimum hardware requirements to run the solution:

{% tabs %}
{% tab title="Full solution" %}

* 4-core x86-64 CPU (Intel, AMD) with virtualization capabilities
* 8GB RAM
* 5GB hard drive
  {% endtab %}

{% tab title="Server only" %}

* 2-core x86-64 CPU (Intel, AMD) with virtualization capabilities
* 8GB RAM
* 5GB hard drive
  {% endtab %}

{% tab title="Runner only" %}

* 2-core x86-64 CPU (Intel, AMD)
* 2GB RAM
* 1GB hard drive
  {% endtab %}
  {% endtabs %}

Note that additional hard drive space is required for use, depending on the size of your projects.

Officially supported distributions:

* Ubuntu 20.04 (x86\_64)
* Ubuntu 22.04 (x86\_64)
* RHEL 8 (x86\_64)

Software requirements:

{% tabs %}
{% tab title="Full solution" %}

* Docker engine ([Ubuntu](https://docs.docker.com/engine/install/ubuntu/), [RHEL 8](https://docs.docker.com/engine/install/rhel/))
* [Docker-compose plugin](https://docs.docker.com/compose/install/linux/) (min 2.21, often already installed with Docker engine)

On Ubuntu, to be able to run dynamic analysis in virtualized environment (e.g, executing code virtualized for ARM), you must also enable virtualization for your Docker containers, by running the following commands:

```bash
# Install QEMU dependencies
sudo apt-get install qemu binfmt-support qemu-user-static

# Virtualization registration
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
```

{% hint style="warning" %}
Virtualization is not available on RHEL 8. Therefore, automatic dynamic analysis targeting non-x86\_64 Linux platforms will not work on this system.
{% endhint %}
{% endtab %}

{% tab title="Server only" %}

* Docker engine ([Ubuntu](https://docs.docker.com/engine/install/ubuntu/), [RHEL 8](https://docs.docker.com/engine/install/rhel/))
* [Docker-compose plugin](https://docs.docker.com/compose/install/linux/) (min 2.21, often already installed with Docker engine)
  {% endtab %}

{% tab title="Runner only" %}
No dependency is needed for runner only.
{% endtab %}
{% endtabs %}


# Installation

## Preparation

First, be sure to meet all hardware and software [requirements](broken://pages/i2YVsRqOHhzqig2d0OaJ).

The Linux user installing beLow must be allowed to access Docker engine through the CLI (for full installation, server only or runner only in Dockerized mode). For this, follow Docker's [Linux post-installation steps for Docker Engine](https://docs.docker.com/engine/install/linux-postinstall/).

After a classical Docker installation on Ubuntu, the following commands should do the trick:

```sh
# Add current user to Docker group
sudo usermod -aG docker $USER
# Trick to avoid to perform a logout/login cycle (only works in current terminal)
newgrp docker
```

## Get installer

You can get the latest Linux package for your distribution from WedoLow's sales.

## Installation

{% hint style="warning" %}
Docker engine must be running during installation.
{% endhint %}

In a terminal, go to the folder of the package you downloaded (let's call it `beLow.xxx`). Then run:

{% tabs %}
{% tab title="Ubuntu" %}

```sh
sudo apt install ./beLow.deb
```

or

```sh
sudo dpkg -i ./beLow.deb
# If installation fails due to dependency, run the following command
sudo apt install -f
```

{% endtab %}

{% tab title="RHEL" %}

```sh
yum --nogpgcheck localinstall ./beLow.rpm
```

{% endtab %}
{% endtabs %}

{% hint style="warning" %}
Installing using the .deb or .rpm package requires an internet connection to retrieve package dependencies. If your installation is offline, you will find the packages to be pre-installed below.
{% endhint %}

Package dependencies:

{% tabs %}
{% tab title="Ubuntu" %}

<table><thead><tr><th width="158">Distribution</th><th>Dependencies</th></tr></thead><tbody><tr><td>Ubuntu 20.04</td><td>libayatana-appindicator3-1<br>libfuse2<br>libspdlog1<br>libgrpc++1</td></tr><tr><td>Ubuntu 22.04</td><td>libayatana-appindicator3-1<br>libfuse2<br>libspdlog1<br>libgrpc++1</td></tr><tr><td>Ubuntu 24.04</td><td>libayatana-appindicator3-1<br>libfuse2<br>libspdlog1.12<br>libgrpc++1.51t64</td></tr></tbody></table>
{% endtab %}

{% tab title="RHEL" %}
No non-native dependency is needed, the package is self-sufficient.
{% endtab %}
{% endtabs %}

If beLow suite is successfully installed, you now have access to the following desktop applications:

* beLow
* beLowCTL
* beLowCTL - Headless (RHEL only)

<figure><img src="/files/vS1wftAcLKnM8AXVu5pl" alt=""><figcaption><p>beLow apps</p></figcaption></figure>

## Removal

For a complete removal of beLow, run the following command:

{% tabs %}
{% tab title="Ubuntu" %}

```sh
sudo apt autoremove below
```

{% endtab %}

{% tab title="RHEL" %}

```sh
sudo yum remove beLow
```

{% endtab %}
{% endtabs %}

## Offline

You must have a zip file containing the required docker images. This file is provided by Wedolow.

1. Do the installation as explained before
2. Run the following commands:

```bash
cd /tmp && unzip docker-images-export.zip
belowctl-headless docker-images import --input /tmp/docker-images-export
```


# Windows

To install beLow, follow the guide for your OS:

* [Requirements](/documentation/below/installation-guide/installation-instructions/windows/requirements)
* [Installation](/documentation/below/installation-guide/installation-instructions/windows/requirements)

{% hint style="info" %}
Choose the appropriate link above for the installation step you need.
{% endhint %}

Last updated 1 year ago


# Requirements

Minimum hardware requirements to run the full solution locally:

{% tabs %}
{% tab title="Full solution" %}

* 4-core x86-64 CPU (Intel, AMD) with virtualization capabilities
* 16GB RAM
* 5GB hard drive
  {% endtab %}

{% tab title="Server only" %}

* 2-core x86-64 CPU (Intel, AMD) with virtualization capabilities
* 16GB RAM
* 10GB hard drive
  {% endtab %}

{% tab title="Runner only" %}

* 2-core x86-64 CPU (Intel, AMD) with virtualization capabilities (not needed for native runner)
* 8GB RAM
* 2GB hard drive
  {% endtab %}
  {% endtabs %}

Note that additional hard drive space is required for use, depending on the size of your projects.

Supported OS:

* Windows 10
* Windows 11

Software requirements:

{% tabs %}
{% tab title="Full solution" %}

* [Docker Desktop](https://docs.docker.com/desktop/install/windows-install/) (4.26.0 or later) or [Rancher Desktop](https://rancherdesktop.io/) (1.11.1 or later). Check that docker-compose version is at least 2.21.

{% hint style="info" %}
Note that Docker Desktop may be a non-free solution depending on the size or revenues or your company, so you may prefer Rancher Desktop in that case.
{% endhint %}

* [Visual Studio C++ Redistributable 2017](https://aka.ms/vs/17/release/vc_redist.x64.exe). Double-click on the downloaded file and follow the steps to install it.

{% hint style="info" %}
If you don't know if Visual Studio C++ Redistributable 2017 is already installed on your system, you may proceed with beLow installation without installing it and finally install it if it turns up that you are unable to run the user interface because of missing libraries.
{% endhint %}
{% endtab %}

{% tab title="Server only" %}

* [Docker Desktop](https://docs.docker.com/desktop/install/windows-install/) (4.26.0 or later) or [Rancher Desktop](https://rancherdesktop.io/) (1.11.1 or later). Check that docker-compose version is at least 2.21.
  {% endtab %}

{% tab title="Runner only" %}
No dependency is needed for runner only.
{% endtab %}
{% endtabs %}

To build/run code on your system (full solution or native runner only), running local scripts must be allowed on the system. To know if your system is able to run such scripts, run in a Powershell terminal:

```powershell
Get-ExecutionPolicy
```

If result is `Restricted`, then you must [change the execution policy](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-7.4) to `RemoteSigned` or `Unrestricted` (less safe). For this, open a Powershell terminal **as an administrator**.

You may do that by setting execution policy to your current user:

```powershell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
```

You may also apply it to the whole local machine:

```powershell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine
```

After running one of these commands, `Get-ExecutionPolicy` should return `RemoteSigned`.

{% hint style="warning" %}
You may still use beLow without changing execution policy, but jobs won't be able to run natively on your local system, and so you won't be able to run a Windows build or a Windows code execution.
{% endhint %}

To be able to support Docker virtualization for non-x86 platforms, the following command should be run in a non-admin Powershell terminal, while Docker Desktop or Rancher Desktop is running:

```sh
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes
```


# Installation

## Preparation

First, be sure to meet all hardware and software [requirements](broken://pages/i2YVsRqOHhzqig2d0OaJ).

## Get installer

You can get the latest Windows package for your distribution from WedoLow's sales.

## Installation

{% hint style="warning" %}
Docker must be running during installation.
{% endhint %}

First, unzip the downloaded *.zip* archive in a directory of your machine, and run the *.msi* file extracted from the archive by double-clicking on it.

{% hint style="warning" %}
Unzipping the archive is compulsory, running the *.msi* file directly from the archive will make the installation fail.
{% endhint %}

<figure><img src="/files/UXBj88S8X6B0XnhSEriq" alt=""><figcaption><p>Setup welcome message</p></figcaption></figure>

Click **Next** and accept the license agreement to continue.

Choose your setup.

<figure><img src="/files/dtfCpDg96YDgVtgjMRtK" alt=""><figcaption><p>Setup type selection</p></figcaption></figure>

For a classical usage, select **Complete** or **Typical**. Click **Next**, then **Install**. In **Custom** mode you may select:

* Everything for a full installation
* **UI** for UI installation only
* **beLowCTL** for server installation only
* **runner** for runner installation only

<figure><img src="/files/n4o3KSJx3rFEOHSWxmi7" alt=""><figcaption><p>Install confirmation screen</p></figcaption></figure>

<figure><img src="/files/x6W8ky4b5ScDZg3KoMuX" alt=""><figcaption><p>Install in progress</p></figcaption></figure>

Wait for installation to finish. beLow is now installed.

## Update

To update beLow, simply run the new *.msi* file provided to you, and follow the same steps as in [Installation section](#installation).

## Removal

You may remove beLow in **Apps & features** section of Windows.

<figure><img src="/files/qfcgNrqIJHvu6HtVK00s" alt=""><figcaption><p>Uninstall beLow</p></figcaption></figure>

Find beLow, click **Uninstall** and follow the instructions.

## Offline

You must have a zip file containing the required docker images. This file is provided by Wedolow.

1. Do the installation as explained before
2. Unzip the provided file on your desktop
3. Open a PowerShell terminal and run the following commands (assuming your username is `myName`):

```bash
belowctl-headless docker-images import --input c:\Users\myName\desktop\docker-images-export
```


# Before we start

## WedoLow MCP Server

WedoLow MCP Server connects beLow to your AI coding agents for intelligent, automated optimization. Guide code generation with real performance data.

### Core Capabilities

**Project-Aware Intelligence**

* Complete access to your project structure and dependencies
* Full visibility into compilation environment and build configuration
* Understanding of target platform and optimization constraints
* Context-driven AI optimization suggestions

**Iterative Optimization Loop**

* AI analyzes code and identifies optimization opportunities
* Real-time performance feedback and metrics gathering
* Automated application of optimizations
* Refinement based on measured results

### How It Works

**Setup** — Install MCP Server alongside beLow and configure your project

**Connect** — Link your AI agent (GitHub Copilot, Claude, Gemini, or other MCP-enabled LLM)

**Optimize** — Ask your AI agent to analyze and optimize your code

**Iterate** — AI refines optimizations based on performance metrics and your feedback

**Deploy** — Use optimized code in production

### Supported AI Platforms

* GitHub Copilot (VS Code & JetBrains) with GPT-4.1 and Claude Sonnet 4
* Claude (any MCP-enabled integration)
* Gemini CLI and Gemini Pro 2.5
* Junie (Beta) for JetBrains CLion
* Any MCP-enabled AI agent


# Server installation

## Compatibility

The Wedolow MCP Server is compatible with:

* Windows 10/11
* Ubuntu 20.04+
* Debian 11+
* Fedora 32+
* OpenSUSE 15.3+

## Prerequisites

{% tabs %}
{% tab title="Linux" %}
Install [Python 3.10 or higher](https://www.python.org/downloads/).
{% endtab %}

{% tab title="Windows" %}
Install [Python 3.10 or higher](https://www.python.org/downloads/).

Install [Visual Studio C++ Redistributable 2017](https://aka.ms/vs/17/release/vc_redist.x64.exe). Double-click on the downloaded file and follow the steps to install it.

Run the following command:

```powershell
Get-ExecutionPolicy
```

If result is `Restricted`, then you must [change the execution policy](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-7.4) to `RemoteSigned` or `Unrestricted` (less safe). For this, open a Powershell terminal **as an administrator**.

You may do that by setting execution policy to your current user:

```powershell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
```

You may also apply it to the whole local machine:

```powershell
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine
```

After running one of these commands, `Get-ExecutionPolicy` should return `RemoteSigned`.
{% endtab %}
{% endtabs %}

## Installation methods

### Using VSCode Extension

In VSCode, install [WedoLow extension](https://marketplace.visualstudio.com/items?itemName=WedoLow.wedolow) from the store.

<figure><img src="/files/DAThXPykOOvDa7SqnXWx" alt=""><figcaption><p>Install WedoLow extension</p></figcaption></figure>

Then, follow the instructions on the welcome page that shows up.

<figure><img src="/files/siaYi7iBmzhaKzk0BGs1" alt=""><figcaption><p>WedoLow extension welcome page</p></figcaption></figure>

### Manually

First, we advise you to use a Python virtual environment (generally recommended). In this guide, we will use a virtual environment `.venv-wedolow` created in the user workspace. To create the virtual environment and load it, and run:

{% tabs %}
{% tab title="Linux (Bash)" %}

```bash
python -m venv ~/.venv-wedolow
source ~/.venv-wedolow/bin/activate
```

{% endtab %}

{% tab title="Windows (PowerShell)" %}

```powershell
python -m venv "${env:USERPROFILE}\.venv-wedolow"
. "${env:USERPROFILE}\.venv-wedolow\Scripts\Activate.ps1"
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Depending on your Python installation, you may need to explicitly use `python3` instead of `python` command.
{% endhint %}

**In the same terminal**, install the WHL package (adapt the dame of the package):

{% tabs %}
{% tab title="Linux" %}

```bash
pip install --index-url https://__token__:<your_token>@gitlab.com/api/v4/projects/75458460/packages/pypi/simple/ wedolow-mcp-server-linux
```

{% endtab %}

{% tab title="Windows" %}

```
pip install --index-url https://__token__:<your_token>@gitlab.com/api/v4/projects/75458460/packages/pypi/simple/ wedolow-mcp-server-windows
```

{% endtab %}
{% endtabs %}

Replace `<your_token>` with the token which was sent to you to access the Beta.

{% hint style="warning" %}
If you previously installed WedoLow MCP Server from a .whl file (deprecated), please completely remove your virtual environment first, or run&#x20;
{% endhint %}

Everything is now installed to use Wedolow MCP Server on your system. Go to [Configuration section](/documentation/wedolow-mcp-server/server-configuration) to set it up.


# Server configuration

If you have not done it, first [install WedoLow MCP Server (Beta) package](/documentation/wedolow-mcp-server/server-installation).

{% hint style="warning" %}
If you installed and configured the WedoLow MCP server using WedoLow VSCode extension, your MCP Server is already configured for VSCode (GitHub Copilot).

If you want to use it with another AI agent, run VSCode command `MCP: List servers...`, select `wedolow-mcp-server` and then `Show Configuration`. This will show you the configuration to use for any other AI agent, then you just need to adapt the commands in the instructions below.
{% endhint %}

## General

The WedoLow MCP Server is an stdio MCP server, which is used as a subprocess by the AI agent that you will be using. To do that, you must know the path of the WedoLow MCP Server executable. If you installed the WedoLow MCP Server following this documentation, then the path is:

{% tabs %}
{% tab title="Linux" %}

```bash
~/.venv-wedolow/bin/wedolow-mcp-server
```

{% endtab %}

{% tab title="Windows" %}

```powershell
${env:USERPROFILE}\.venv-wedolow\Scripts\wedolow-mcp-server.exe
```

{% endtab %}
{% endtabs %}

If not, adapt what follows to the place where the MCP is installed.

{% hint style="info" %}
You may also add the executable directory to your user's path to access it with its base name.
{% endhint %}

## VSCode (GitHub Copilot)

First, install [GitHub Copilot extension](https://marketplace.visualstudio.com/items?itemName=GitHub.copilot).

To add WedoLow MCP Server to GitHub Copilot in VSCode, run VSCode command (CTRL+MAJ+P):

*MCP: Add server...* → *Command (stdio)*

Fill the following informations when asked:

* *Command*: Path to wedolow-mcp-server executable (you may use `${userHome}` as a variable)
* *Server ID*: wedolow-mcp-server
* *Where*: Global

WedoLow MCP Server is now available for all your projects.

{% hint style="info" %}
Instead of *Global*, you may select *Workspace* if you want to activate the MCP server only for the current workspace. This will create a `mcp.json` file in you project.
{% endhint %}

Try running the MCP Server by running VSCode command (CTRL+MAJ+P):

*MCP: List servers...* → *wedolow-mcp-server* → *Start Server*

You may see the WedoLow MCP Server output by going to:

*MCP: List servers...* → *wedolow-mcp-server* → *Show Output*

This could help troubleshooting if needed.

## CLion (Junie)

In CLion, enable MCP servers:

*Settings* → *Tools* → *MCP Server* → *Enable MCP Server*

Then, add WedoLow MCP Server:

*Settings* → *Tools* → *AI Assistant* → *Model Context Protocol (MCP)* → *Add Server*

Fill the following informations when asked:

* *Name*: wedolow-mcp-server
* Command: Path to wedolow-mcp-server executable

## Gemini CLI

Adding WedoLow MCP Server to Gemini CLI can be done with this one-liner in your terminal:

{% tabs %}
{% tab title="Linux" %}

```sh
gemini mcp add --trust --timeout=3600000 -s user wedolow-mcp-server "${HOME}/.venv-wedolow/bin/wedolow-mcp-server"
```

{% endtab %}

{% tab title="Windows" %}

```powershell
gemini mcp add --trust --timeout=3600000 -s user wedolow-mcp-server "${env:USERPROFILE}\.venv-wedolow\Scripts\wedolow-mcp-server.exe"
```

{% endtab %}
{% endtabs %}

## Claude Code

Adding WedoLow MCP Server to Claude Code can be done with this one-liner in your terminal:

{% tabs %}
{% tab title="Linux" %}

```sh
claude mcp add --scope user wedolow-mcp-server -t stdio "${HOME}/.venv-wedolow/bin/wedolow-mcp-server"
```

{% endtab %}

{% tab title="Windows" %}

```powershell
claude mcp add --scope user wedolow-mcp-server -t stdio "${env:USERPROFILE}\.venv-wedolow\Scripts\wedolow-mcp-server.exe"
```

{% endtab %}
{% endtabs %}

## Other AI agents

Though we could not test other AI agents, most of them support Model Context Protocol (MCP). You may find a compatibility list [here](https://modelcontextprotocol.io/clients).

Search for "MCP" in your AI agent public documentation to find how to register an MCP server.

Feel free to test any other AI agent and tell us more about your experience!


# Usage

If you have not done it yet, first [configure the WedoLow MCP Server](/documentation/wedolow-mcp-server/server-configuration).

If you did:

* Start with [Project configuration section](/documentation/wedolow-mcp-server/usage/project-configuration).
* Then, go to the [Optimize your project section](/documentation/wedolow-mcp-server/usage/optimize-your-project).

If running into any problem, you may find valuable resources in the[ Troubleshoot section](/documentation/wedolow-mcp-server/usage/troubleshoot).


# Project configuration

{% hint style="warning" %}
Before configuring your project, check that [your project is compatible with our tools](/documentation/ressources/compatibility-guide).
{% endhint %}

## Definition

Using WedoLow MCP Server requires a configuration for your project, so the tool knows:

* How to build your project
* How to test your project (optional)
* How to bench your project (optional)
* What is your target platform
* What is the top function of your project for the optimization
* What optimization techniques you wish to enable/disable (avanced usage)

This configuration should be written in file `wedolow_mcp_project_config.json` at the project root.

Here is a basic example:

{% code title="wedolow\_mcp\_project\_config.json" %}

```json
{
    "build_cmd": {
        "cmd": [
            "make"
        ],
        "run_dir": null
    },
    "clean_cmd": {
        "cmd": [
            "make",
            "clean"
        ],
        "run_dir": null
    },
    "test_cmd": {
        "cmd": [
            "make",
            "test"
        ],
        "run_dir": null
    },
    "benchmark_cmd": {
        "cmd": [
            "make",
            "bench"
        ],
        "run_dir": null
    },
    "top_function": {
        "name": "FFT",
        "file": "src/fft.cpp"
    },
    "target_platform": "native"
}
```

{% endcode %}

You may create this file manually, or rely on section [Generate your configuration](#generate-your-configuration) so your AI agent does it itself.

## Configure using VSCode extension

With VSCode extension, run command `WedoLow: Setup project`.

<figure><img src="/files/8dOx9bj8TjHFkp8ibWj7" alt=""><figcaption></figcaption></figure>

Then, use the configuration window to generate your configuration file.

<figure><img src="/files/OOvU0moSeQpzdPJQ9ny8" alt=""><figcaption></figcaption></figure>

## Configure manually

### Supported target platforms

To know the list of supported target platforms, you may simply ask your AI agent:

> Show me the list of target platforms supported by WedoLow MCP Server.

The AI agent will make the right call to give you the answer.

<figure><img src="/files/avNU2eUjxTG38sfGa7Sc" alt=""><figcaption><p>Asking Gemini CLI the list of supported target platforms</p></figcaption></figure>

{% hint style="info" %}
If your AI agent supports MCP resources, you may also find this information in the list of resources.
{% endhint %}

### Generate your configuration

The simplest way to configure your project is to ask help to your AI agent:

> Generate wedolow\_mcp\_project\_config.json config file for WedoLow MCP server using the following informations. My project compiles for the native target platform. It is built with command "make", cleaned with command "make clean" and tested with command "make test", benched with command "make bench". Using "make bench" command. The target platform is the native target. My top function is FFT function in src/fft.cpp file.

You know have a correct configuration file at the root of your project.

<figure><img src="/files/rVfqUgAf5fAbVwptbmJ1" alt=""><figcaption><p>Asking Gemini CLI to generate a configuration file for your project</p></figcaption></figure>

### Advanced usage: deactivate optimizations

If you wish to control which optimizations you want your AI agent to search for and apply, you may blacklist specific optimization techniques. To do that, a new section must be added in the configuration file.

```
{
    "optim_techniques": {
      "<optim-technique-name-1>": true,
      "<optim-technique-name-2>": false,
      "<optim-technique-name-3>": false
    }
}
```

If not defined here, optimization techniques default to **true** (activated)**.**

If you want to control this yourself, ask your AI agent to add this section:

> In my wedolow\_mcp\_project\_config.json, add section "optim\_techniques" and list all the available optimization techniques there. Default them all to true.

<figure><img src="/files/hb5xYuffGrBme17V8jWR" alt=""><figcaption><p>Asking Gemini CLI to add the explicit list of available optimization techniques</p></figcaption></figure>

Your project is fully configured. You may now [run the optimization](/documentation/wedolow-mcp-server/usage/optimize-your-project).

{% hint style="info" %}
When optimizing C++, the top function name must carry its namespace and classname, e.g, `mynamespace::MyClass::funcName`
{% endhint %}


# Optimize your project

## Start the optimization with VSCode extension (GitHub Copilot)

In the chat Window, type `/optimize_wedolow` and press enter. That's it!

<figure><img src="/files/xLmgCd05b0IxL6CQkPQa" alt=""><figcaption></figcaption></figure>

## Other agents and manual installation

Once [your project is configured](/documentation/wedolow-mcp-server/usage/project-configuration), everything is ready to optimize it. To run the optimization, just ask your AI agent:

> Optimize my project with WedoLow MCP Server. Start with getting the initial instructions.

Now, let the AI agent interact with the MCP server and your code until your code is fully optimized.

<figure><img src="/files/9MKwl6ELDOmehIDFu1I8" alt=""><figcaption><p>Gemini CLI working to optimize your code</p></figcaption></figure>

At some point, the MCP could require inputs from you:

* Allowing MCP Server specific tools access.
* Allowing commands in your terminal. The AI agent sometimes uses custom commands during the optimization process, for auto-correction or even to modify code based on substitutions.
* Asking you if you want to continue if running for a long time, or warn you about your usage.
* Ask you to make a choice about something.

When the AI agent stops to wait for an input, give the appropriate input based on your own judgement of the situation, and don't hesitate asking it explicitely to continue the optimization process.

When the optimization ends, the AI Agent generates an optimization report at the root of your project, named **wedolow\_optimization\_report.md**. This report sums up everything that happened during the optimization, what worked, what didn't and why, the performance improvements, etc.

Review the report and the code modifications, and feel free to use the result or ask your AI agent to revert some of the changes it did.

{% hint style="warning" %}
As a counterpart for the WedoLow MCP Server Beta, when an error occurs or the optimization is successful, the AI agent will send **your optimization report** and data present in **.wedolow\_mcp** directory to WedoLow server, as well as an anonymous ID for your system. Though your codebase is not sent to WedoLow, do not use WedoLow MCP Server beta with confidential code as there can be traces of it in the data sent.
{% endhint %}


# Troubleshoot

## The initial analysis always fails

* Check your configuration file and test the commands you entered.
* Add a clean command (`clean_cmd`), which can be necessary for WedoLow MCP Server to evaluate better your project from a clean state when needed.
* Check that your project is compatible with our tools in the [Compatibility guide](/documentation/ressources/compatibility-guide).

If the problem still occurs, check your WedoLow MCP Server installation.

## My AI agent stops working unexpectedly or seems not to follow the requested optimization process

C/C++ code optimization process is a complex problem, which requires the AI Agent to rely on a powerful enough LLM.

Some examples:

* With Gemini, you will get good results from **Gemini 2.5 Pro**, but you will get bad results or no result at all from **Gemini 2.5 Flash**.
* With GitHub Copilot, you may get good results from **Claude Sonnet 4.5**, average results with **GPT-4.1**, and bad results or no result at all with **GPT-4o**.

In general, a **paid plan with powerful LLMs** will get you excellent results, most free plans for AI agents won't (for weak LLM, small context and usage restrictions reasons).

## The WedoLow MCP Server responds that the access is unauthorized.

* Make sure that your internet connection works properly.
* Check that domain <https://below-public.s3.fr-par.scw.cloud> can be contacted by your system.
* Check if the WedoLow MCP Server Beta program is not over.

## My project top function is not found by the tool

Check the following elements:

* If you are doing C++, check that the namespace and class of your method are embedded in the function name (e.g, `mynamespace::MyClass::myName`)
* Use slashes as path separators for the source file and express the path with slashes even on Windows (e.g, `path/to/myfile.cpp` )


# Use case: An FFT in C

If you want to follow this example by doing it yourself, before following this use case do the following:

* Clone the FFT library:

  ```bash
  git clone https://github.com/muditbhargava66/FFT-implementation-in-C
  ```

### Create configuration file

{% hint style="info" %}
If you installed WedoLow VSCode extension, run command `WedoLow: Setup project` to help you create the configuration file using a form.
{% endhint %}

This configuration should be written in a file named <mark style="color:$primary;">wedolow\_mcp\_project\_config.json</mark> at the project root. Jump at the end of this section to copy the content of this file if you'd like faster:

* Build command:

  ```bash
  make
  ```
* Clean command:

  ```bash
  make clean 
  ```
* Test command:

  ```bash
  make test
  ```
* Benchmark command:

  ```bash
  make benchmark
  ```
* Top Function

  ```json
   "top_function": {
          "name": "radix2_dit_fft",
          "file": "algorithms/core/radix2_dit.c"
      }
  ```
* Target Platform

  ```json
  "target_platform": "native"
  ```
* Optimization techniques:&#x20;

  * For this example we select an arbitrary set of optimization techniques

  ```json
  "optim_techniques": {
          "math-libc-options": "false",
          "const-volatile": "false",
          "track-cast": "true",
          "libm-function-tracking": "true",
          "vector-reserve" : "false",
          "divide-hunter" : "true",
          "function-factorization" : "true",
          "copy-hunter" : "false",
          "branch-reordering" : "false",
          "memory-operations" : "true",
          "simd-external-functions" : "false",
          "simd-data-dependencies" : "true",
          "enum-switch" : "false",
          "nested-container-operations" : "false",
          "simd-control-flow" : "false",
          "rtti-remove-dynamic_cast" : "false",
          "aos-to-soa" : "false",
          "memory-access-optimization" : "true",
          "double-to-float": "false",
          "redundant-hash-calculations" : "false",
          "string-operations" : "false",
          "push-to-emplace-back" : "false"
      }
  ```

  * Every technique is activated by default so we could also write just this:

  ```json
  "optim_techniques": {
          "math-libc-options": "false",
          "const-volatile": "false",
          "vector-reserve" : "false",
          "copy-hunter" : "false",
          "branch-reordering" : "false",
          "simd-external-functions" : "false",
          "enum-switch" : "false",
          "nested-container-operations" : "false",
          "simd-control-flow" : "false",
          "rtti-remove-dynamic_cast" : "false",
          "aos-to-soa" : "false",
          "double-to-float": "false",
          "redundant-hash-calculations" : "false",
          "string-operations" : "false",
          "push-to-emplace-back" : "false"
      }
  ```

  * If you prefer to activate every optimization just don't fill this field of the config file or set it to null:

  ```json
  "optim_techniques": null
  ```
* Full configuration file

```json
{
  "build_cmd": {
    "cmd": [
      "make"
    ],
    "run_dir": "."
  },
  "clean_cmd": {
    "cmd": [
      "make",
      "clean"
    ],
    "run_dir": "."
  },
  "test_cmd": {
    "cmd": [
      "make",
      "test"
    ],
    "run_dir": "."
  },
  "benchmark_cmd": {
    "cmd": [
      "make",
      "benchmark"
    ],
    "run_dir": "."
  },
  "top_function": {
    "name": "fft",
    "file": "fft/fft.c"
  },
  "target_platform": "native",
  "optim_techniques": {
    "math-libc-options": "false",
    "const-volatile": "false",
    "vector-reserve": "false",
    "copy-hunter": "false",
    "branch-reordering": "false",
    "simd-external-functions": "false",
    "enum-switch": "false",
    "nested-container-operations": "false",
    "simd-control-flow": "false",
    "rtti-remove-dynamic_cast": "false",
    "aos-to-soa": "false",
    "double-to-float": "false",
    "redundant-hash-calculations": "false",
    "string-operations": "false",
    "push-to-emplace-back": "false"
  }
}
```

{% hint style="info" %}
You could also use your AI Agent to generate this file as presented in [Project configuration](/documentation/wedolow-mcp-server/usage/project-configuration#generate-your-configuration).
{% endhint %}

***

### Optimize your project!

{% hint style="info" %}
If using VSCode extension, you may just run `/optimize_wedolow` command in the Chat in agent mode.
{% endhint %}

The project is configured now, we're ready to optimize it with the WedoLow MCP Server.

* The simplest part for you, just ask your AI agent to:

> Optimize my project with WedoLow MCP Server. Start with getting the initial instructions.

{% hint style="info" %}
For a flawless experience you can enable the "auto-approve" option that some agents may suggest you.
{% endhint %}

Now, you just have to let the MCP Server do the work, and it'll modify the code directly in your IDE. Let the AI agent interact with the MCP server and your code until your code is fully optimized.

* Finally, you just have to read the <mark style="color:$primary;">wedolow\_optimization\_report.md</mark> which will provide you information on every optimization technique used in the project but also a summary of the global impact on the project.

<figure><img src="/files/pJBsV09HtyD4Ya0sx45q" alt=""><figcaption><p>Example of final agent output for this project - GitHub Copilot + Claude Sonnet 4 in VSCode</p></figcaption></figure>

You can see here the 3 possible decisions for a technique optimization after its analysis.&#x20;

It's either:

* **Successfully applied** if the analysis proves that the code modification better the performance within the tolerance boundaries of the code
* **Non-applicable** if the code is already optimized regarding this technique according to the WedoLow tool or if the es not align with the project's goals or requirements. The analysis shows that either there is no impact or the technique is irrelevant due to constraints or context of the project.
* **Reverted Solution** decision is made if the optimization attempt affects performance, introduces errors, or if the analysis fails. All the changes concerning this technique are then reverted.


# Compatibility guide

This section helps you make any of your projects compatible with beLow, when the general Compatibility section is meeting your needs.

{% stepper %}
{% step %}

### Read the general compatibility guide

First, it is important to read [Compatibility generalities](/documentation/ressources/compatibility-guide/compatibility-generalities) to understand how beLow understands your project.
{% endstep %}

{% step %}

### Configure project-specific settings

Then, [Compatibility specifics](/documentation/ressources/compatibility-guide/compatibility-specifics) can help you configure better your project depending on its specificities.
{% endstep %}

{% step %}

### Follow context-specific instructions

Finally, any of the following sections details how to make your project work depending on its context.
{% endstep %}
{% endstepper %}


# Compatibility Matrix

If your OS, target platform or build environment is not compatible with beLow, please contact us at <support@wedolow.com> to discuss your use case.

### Product

beLow is composed of multiple components (see [Installation modes section](https://docs.wedolow.com/below-technical-documentation/readme/installation-modes)). Each component set has its own set of compatibilities. These compatibilities are presented in the table below.

| OS / Distribution    | Full local solution | Server\* | Runner |  UI | CLI tool |
| -------------------- | :-----------------: | :------: | :----: | :-: | :------: |
| Windows 11 (amd64)   |          ✅          |     ✅    |    ✅   |  ✅  |     ✅    |
| Windows 10 (amd64)   |          ✅          |     ✅    |    ✅   |  ✅  |     ✅    |
| Ubuntu 24.04 (amd64) |          ✅          |     ✅    |    ✅   |  ✅  |     ✅    |
| Ubuntu 22.04 (amd64) |          ✅          |     ✅    |    ✅   |  ✅  |     ✅    |
| Ubuntu 22.04 (ARM64) |          ❌          |     ❌    |    ✅   |  ❌  |     ❌    |
| Ubuntu 20.04 (amd64) |          ✅          |     ✅    |    ✅   |  ✅  |     ✅    |
| RHEL 8 (amd64)       |          ✅          |     ✅    |    ✅   |  ✅  |     ✅    |

{% hint style="info" %}
\*The Server part requires Docker.
{% endhint %}

### Languages

beLow is compatible with C and C++ code using any standard.

### Target platforms

beLow is compatible with multiple target platforms, listed below.

* ARM (32-bit)
* ARM (64-bit)
* Tricore (32-bit)
* x86\_64 (64-bit)
* Power-ISA (64-bit)
* Cortex-M0 (ARMv6-M)
* Cortex-A72 (ARMv8)
* Infineon TC29x
* Intel Skylake
* NXP PowerPC E6500
* Cortex-M0+ (ARMv6-M)
* Cortex-A76AE (ARMv8)
* Cortex-A15 (ARMv7)
* Cortex-M3 (ARMv7)
* Cortex-M4 (ARMv7)
* Cortex-R5 (ARMv7)

### Compilers

beLow is compatible with multiple compilers:

* GNU gcc/g++
* Clang
* HighTec Tricore gcc
* ICCARM (IAR Embedded Workbench for ARM compiler)

### Build environment

beLow is compatible with multiple build environments, depending on the build OS.

| Build system / Environment     | Linux | Windows |
| ------------------------------ | :---: | :-----: |
| Makefiles                      |   ✅   | ✅\*\*\* |
| CMake                          |   ✅   |    ✅    |
| Bazel                          |   ✅   |    ✅    |
| STM32CubeIDE                   |   ✅   |    ✅    |
| IAR Embedded Workbench for ARM |   ✅   |    ✅    |
| Compilation database\*         |   ✅   |    ✅    |
| Docker container\*\*           |   ✅   |    ✅    |
| Custom scripts                 |   ✅   |    ❌    |

{% hint style="info" %}

* A [compilation database](https://clang.llvm.org/docs/JSONCompilationDatabase.html) is a structured JSON representation of all compilation invocations in your project. Many build frameworks/IDEs can generate one.

\*\* Building from a Docker container requires it to be compatible with the compatibility list of the Runner service in the Product section: <https://docs.wedolow.com/below-technical-documentation/compatibility#product>

\*\*\* Makefiles for Windows are only compatible when using GCC-based compilers for now.
{% endhint %}

For more information about making your projects compatible with beLow, see the [compatibility guide](/documentation/ressources/compatibility-guide).


# Compatibility generalities

First, make sure that your project meets the compatibilities listed [here](https://docs.wedolow.com/below-technical-documentation/compatibility).

To be able to understand your project, beLow must:

* Get a [compilation database](https://clang.llvm.org/docs/JSONCompilationDatabase.html) as an input, or
* Be able to generate one.

In general **on Linux**, the generation of a compilation database is straightforward and invisible for the user. In this case, beLow uses [Bear](https://github.com/rizsotto/Bear), which is distributed packed with the solution. Making your Linux project work with beLow is generally effortless, as long as the compilation is effectively fully executed on the machine (and not cached from servers for instance).

**On Windows**, compilation database generation is generally possible but may require some tweaks in the way the compilation is presented to beLow. This page mainly focuses on this.

**For any operating system**, you must be able to provide scriptable build commands to build your project.


# Compatibility specifics

### Disk location-dependent build process

Either on Linux or Windows, your project build process might be disk location-dependent, i.e. your build does not work any more if the project is copied to another location. This happens when:

* your build scripts or your build system uses absolute paths to determine the position of the C/C++ files, or
* your build scripts use dependencies which are outside of your project and referred to using relative paths (e.g. for a compile command running at the root of the project, using includes with flag `-I../mylib`).

If you are not sure if your build system is location-dependent, copy your project directory elsewhere and attempt to build it using your usual script. If the script fails, it is location-dependent.

In case your project is location-dependent, you have to use **local mode** when setting up your project.

![Use local mode with your location-dependent project](/files/9b1fd398a5605b5863afc097bf67116d3b8aa030)

When using **local mode**, you can only run builds on your own machine (and not on runners running on another machine), and beLow will work directly in your project. During the whole usage of beLow, from setting your project up to the optimization process, you **must not** modify any of the source code or build scripts, otherwise beLow's behaviour would be unpredictable.

**Local mode** is also recommended if your project has thousands of files and/or an important volume on disk.

### Specify your target

When using beLow, you should focus on building a single target. If your scripts are able to build multiple targets, try to specify the one you are interested in for the current project (you may create one project per target, for instance).

For example, using CMake, if you have multiple targets like `myprogram` and `mylib` in your `CMakeLists.txt`, do not run the generic build command that builds all targets, because some sources could be compiled multiple times in different ways and beLow will not know which of these compilations corresponds to your target.

Instead of:

```bash
# Configure
cmake -B build .

# Clean
cmake --build build --target clean

# Build
cmake --build build
```

use the target-specific build command if you are interested in `myprogram`:

```bash
# Configure
cmake -B build .

# Clean
cmake --build build --target clean

# Build
cmake --build build --target myprogram
```

### Working with compilation databases

In the general case, making your project compatible with beLow is equivalent to providing a compilation database file, or scripts to generate one, or leaving beLow to generate it.

If you provide or generate it, this compilation database must be named `compile_commands.json` and must be generated in the project. If multiple `compile_commands.json` files are present in the project, only the first one found is kept.

When setting up your project, if a `compile_commands.json` file is found, it is automatically taken as the source of truth about your compilation process.

If you directly provide a `compile_commands.json` file, as the elements in this file are in general absolute paths, you must choose to work in **local mode**. See the Disk location-dependent build process section: <https://docs.wedolow.com/below-technical-documentation/compatibility-guide/compatibility-specifics#disk-location-dependent-build-process>

However, the best way to work with compilation databases is to provide location-independent scripts which are able to generate one wherever the project is located. This way, beLow can work in copies of your code, allowing **copy mode** to be used.

If you are able to provide a command generating a compilation database, it is recommended to inform it in *Configure commands*.

![Generate your compile\_commands.json file during project configuration](/files/0a76951cd53061d4c8d1110595fb89c9ffc21b15)

Generate your `compile_commands.json` during project configuration

If you are using a build framework able to generate a compilation database, make it generate it during configuration. If you can generate a compilation database at that point, beLow will work more reliably.

In the next sections of the original documentation you will see how to generate one with different specific frameworks.


# CMake

### Generate a compilation database with CMake

CMake can generate a compilation database at configuration. When using a CMake project you have two ways of generating it:

* Using the CMAKE\_EXPORT\_COMPILE\_COMMANDS variable globally (from CMake 3.5): <https://cmake.org/cmake/help/latest/variable/CMAKE\\_EXPORT\\_COMPILE\\_COMMANDS.html>
* Using the EXPORT\_COMPILE\_COMMANDS target property for the specific target you want to analyze (from CMake 3.20): <https://cmake.org/cmake/help/latest/prop\\_tgt/EXPORT\\_COMPILE\\_COMMANDS.html#prop\\_tgt:EXPORT\\_COMPILE\\_COMMANDS>

Compilation database generation with CMake is only available with Makefiles and Ninja generators. Any other generator will ignore these variables and the compilation database will not be generated.

{% hint style="warning" %}
If your CMake configuration has multiple targets, it is strongly recommended to activate compile commands generation only for the target you want to analyze. Generating compile commands globally in multi-target projects may lead to undefined behaviour if some sources are compiled multiple times with different commands.
{% endhint %}

{% stepper %}
{% step %}

### Enable compile commands globally

You can enable global generation either from the CMake command line:

{% code title="Command" %}

```bash
cmake -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_EXPORT_COMPILE_COMMANDS=ON .
```

{% endcode %}

or by setting it in the root `CMakeLists.txt`:

{% code title="CMakeLists.txt" %}

```cmake
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
```

{% endcode %}
{% endstep %}

{% step %}

### Prefer enabling per-target (recommended for multi-target projects)

First, force the global generation off:

{% code title="CMakeLists.txt" %}

```cmake
set(CMAKE_EXPORT_COMPILE_COMMANDS OFF)
```

{% endcode %}

Then, enable it for the specific target:

{% code title="CMakeLists.txt" %}

```cmake
set_target_properties(mytarget PROPERTIES EXPORT_COMPILE_COMMANDS ON)
```

{% endcode %}
{% endstep %}
{% endstepper %}

When running CMake, `compile_commands.json` is generated in the build directory. For example, running:

{% code title="Command" %}

```bash
cmake -B build -DCMAKE_BUILD_TYPE=Release .
```

{% endcode %}

will produce `./build/compile_commands.json`.

In beLow, enter the CMake command as the "Configure script" when asked; beLow will find the `compile_commands.json` file by name.

Try not to leave any stale `compile_commands.json` files in your project root if you can generate them at configuration or build time. A leftover file may be used in priority and cause issues if it is out of date or uses absolute paths (in copy mode).

### Windows specificities

On Windows, CMake's compile-commands generation can produce commands with unexpected escaping of backslashes and quotes. A common problematic case is when injecting include file names via preprocessor definitions.

Example C/C++ usage you might try:

{% code title="source.c / source.cpp" %}

```c
#include LIB_HEADER_FILE
```

{% endcode %}

And in `CMakeLists.txt`:

{% code title="CMakeLists.txt (problematic)" %}

```cmake
add_definitions(-DLIB_HEADER_FILE="lib.h")
```

{% endcode %}

CMake may generate an over-escaped entry in `compile_commands.json` like `-DLIB_HEADER_FILE=\"lib.h\"`, which breaks the intended injection.

There are two ways to address this:

* Modify the compilation database after generation with a script (not recommended).
* Prefer rewriting the macro so the compiler adds the quotes. This is the recommended approach.

Recommended fix in source:

{% code title="source.c / source.cpp" %}

```c
#define INCLUDE_FILE(x) #x
#include INCLUDE_FILE(LIB_HEADER_FILE)
```

{% endcode %}

Then, in your `CMakeLists.txt`, define the macro without quotes:

```cmake
add_definitions(-DLIB_HEADER_FILE=lib.h)
```

or for a target:

```cmake
target_compile_definitions(<your-target> PUBLIC LIB_HEADER_FILE=lib.h)
```

With this approach, after running CMake configuration the generated compilation database will be correct.

Last updated 1 month ago


# Makefiles on Windows

{% hint style="info" %}
Though the methods on this page work on both Linux and Windows, on Linux you may rely on the integrated Bear process to generate the compilation database and therefore use your usual build process flawlessly.
{% endhint %}

When using the make command to build your project, beLow can generate a compilation database file using the below-make-intercept tool (also available as a CLI tool when installing beLow).

A fake make command is injected while running your build script; it instruments calls to make to run them in dry-run mode, parses the log and injects a new log so a compilation database can be generated.

To work with make, give your make command as the Build script when asked.

Generating compile commands from a make command is only possible when run from a clean state. Always provide a Clean script if you can, or ensure your project is in a clean state before running the intercept.

{% hint style="warning" %}
If your call to make is wrapped by a script or a command that calls make by its absolute path or uses path injection, this method will not work.

Example: If you use STM32CubeIDE and build via the stm32cubeidec CLI tool, this method will not work because that tool calls make using its own injected make path. See the STM32CubeIDE compatibility page for more information: <https://docs.wedolow.com/below-technical-documentation/compatibility-guide/stm32cubeide-on-windows>
{% endhint %}

As stated above, you can also directly use the below-make-intercept tool to generate a compilation database outside of beLow (in this case, use local mode). Use it to check whether beLow can generate a compilation database for your make command.

{% stepper %}
{% step %}

### Run below-make-intercept

In a terminal in your project, run:

```bash
below-make-intercept "your-command"
```

The compilation database is printed to standard output.
{% endstep %}

{% step %}

### Example: writing compile\_commands.json

To generate a compile\_commands.json file:

```bash
make clean
below-make-intercept "make all" > compile_commands.json
```

On Windows, to ensure compile\_commands.json is encoded in a neutral encoding (not depending on system language), prefer this PowerShell form:

```powershell
make clean
below-make-intercept "make all" | Out-File -Encoding ASCII -FilePath .\compile_commands.json
```

{% endstep %}
{% endstepper %}

If beLow cannot generate compile\_commands.json automatically from your build scripts for any reason, you may use below-make-intercept directly in the Configure script.


# STM32CubeIDE on Windows

{% hint style="info" %}
Though the methods in this page work both on Linux and Windows, on Linux you may rely on integrated Bear process to generate the compilation database, and therefore use your usual build process flawlessly.
{% endhint %}

STM32CubeIDE projects are generating Makefiles that can then be used using the strategy defined in [Makefiles compatibility section](/documentation/ressources/compatibility-guide/makefiles-on-windows), with a few extra configuration steps.

STM32CubeIDE projects works the following way to compile a project:

* Generation of Makefiles
* Instrumentation of the PATH variable to make use of the right tools (make command, compiler, linker, etc)
* Execution of the `make` command.

This method conflicts with the method used by `below-make-intercept` to generate a compilation database. Because of this, the `below-make-intercept` must be run after PATH variable instrumentation, which must be replicated.

To do that, the user must:

* Generate the Makefiles (using STM32CubeIDE directly, by running at least one build).
* Find the paths used by STM32CubeIDE for:
  * The `make` command
  * The compiler invokations
* Inject these paths
* Call `below-make-intercept` directly on the `make` command.

This section details how to do that, taking the STM32CubeIDE example project 53L1A2\_MultiSensorRanging, targeting NUCLEO-F401RE (Cortex-M4), on Windows.

The project is possible to setup quickly by clicking on ***File -> New -> STM32 Project***.

There, on tab ***Example selector***, select project ***53L1A2\_MultiSensorRanging*** for NUCLEO-F401RE.

<figure><img src="/files/AOIAahpaUiCqzokEenmG" alt=""><figcaption><p>Project selection in STM32CubeIDE</p></figcaption></figure>

On the newly imported project, set ***Release*** target active.

<figure><img src="/files/WXxt7xHs9JoA4sqhzYEv" alt=""><figcaption><p>Set Release target active</p></figcaption></figure>

Then, build the project. This will generate the build files, hence the Makefiles. Then, clean the project to be in a clean state.

Let's now build the project from a terminal instead of STM32CubeIDE. **Open Release directory** in the system explorer, and then **open a PowerShell terminal** from Release directory.

<figure><img src="/files/1wUgDV6x92kkzK4DYYxm" alt=""><figcaption><p>Open Release folder</p></figcaption></figure>

<figure><img src="/files/Cwzd554aTnGYIFYWxvxh" alt=""><figcaption><p>Open a terminal </p></figcaption></figure>

Now, the objective is to make the command `make all` work in this terminal. To do that, we must setup the environment so `make` command and `arm-none-eabi-gcc` are recognized.

To find the required environment, in STM32CubeIDE, go to **project properties**, in **C/C++ Build -> Environment** and check the content of the PATH variable, so you can identify where the commands are. In general, both are in different directories. On a classical installation of STM32CubeIDE, the directory containing the `make` command is something like:

```
C:\ST\STM32CubeIDE_1.18.0\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.make.win32_2.2.0.202409170845\tools\bin
```

The directory containing the `arm-none-eabi-gcc` command is something like:

```
C:\ST\STM32CubeIDE_1.18.0\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.13.3.rel1.win32_1.0.0.202411081344\tools\bin
```

In the PowerShell terminal, we may now inject these paths and build the project.

{% code overflow="wrap" lineNumbers="true" %}

```powershell
$env:PATH="C:\ST\STM32CubeIDE_1.18.0\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.make.win32_2.2.0.202409170845\tools\bin;C:\ST\STM32CubeIDE_1.18.0\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.13.3.rel1.win32_1.0.0.202411081344\tools\bin;$env:PATH"
make all
```

{% endcode %}

The project compiles! Now, from the same terminal, we can generate a compilation database by using `below-make-intercept` tool, as descripted in [the previous section](broken://pages/TlZQjfD5frWIOQKStRNw).

The best thing to do here is to create a PowerShell script with the following content:

{% code title="generate-cdb.ps1" overflow="wrap" lineNumbers="true" %}

```powershell
$env:PATH="C:\ST\STM32CubeIDE_1.18.0\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.make.win32_2.2.0.202409170845\tools\bin;C:\ST\STM32CubeIDE_1.18.0\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.13.3.rel1.win32_1.0.0.202411081344\tools\bin;$env:PATH"
make clean
below-make-intercept "make all" | Out-File -Encoding ASCII -FilePath .\compile_commands.json
```

{% endcode %}

Now, calling this script directly in the ***Configure script*** in beLow will generate the required compilation database.

If you don't wish to modify your global environment, you may also create a clean and a build script.

{% code title="clean.ps1" overflow="wrap" lineNumbers="true" %}

```powershell
$env:PATH="C:\ST\STM32CubeIDE_1.18.0\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.make.win32_2.2.0.202409170845\tools\bin;C:\ST\STM32CubeIDE_1.18.0\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.13.3.rel1.win32_1.0.0.202411081344\tools\bin;$env:PATH"
make clean
```

{% endcode %}

{% code title="build.ps1" overflow="wrap" lineNumbers="true" %}

```powershell
$env:PATH="C:\ST\STM32CubeIDE_1.18.0\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.make.win32_2.2.0.202409170845\tools\bin;C:\ST\STM32CubeIDE_1.18.0\STM32CubeIDE\plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.13.3.rel1.win32_1.0.0.202411081344\tools\bin;$env:PATH"
make all
```

{% endcode %}

Therefore, the typical commands setup in beLow would be the following ones.

For ***Configure*** section, enter:

* Script content:

```powershell
.\generate-cdb.ps1
```

* Script execution path: In the target directory
* Shell: **Pwsh**

For ***Clean*** section, enter:

* Script content:

```powershell
.\clean.ps1
```

* Script execution path: In the target directory
* Shell: **Pwsh**

For ***Build*** section, enter:

* Script content:

```powershell
.\build.ps1
```

* Script execution path: In the target directory
* Shell: **Pwsh**


# IAR Embedded Workbench for ARM

beLow is compatible with IAR Embedded Workbench for ARM. To make a project compatible with beLow, the iarbuild command must be used in the Build script.

IAR Embedded Workbench for ARM creates a project metadata file with extension .ewp.

Commands to build your project

* Incremental build

{% code title="Incremental build (recommended)" %}

```powershell
iarbuild .\path\to\MyProject.ewp -make "MyConfig"
```

{% endcode %}

* Clean build

{% code title="Clean build" %}

```powershell
iarbuild .\path\to\MyProject.ewp -build "MyConfig"
```

{% endcode %}

We recommend using the incremental build for better performance.

{% hint style="warning" %}
iarbuild must be in your PATH when running beLow. Also the IAR ARM tools (for example iccarm) must be in your PATH as well.
{% endhint %}

Default installation paths (IAR Embedded Workbench 9.2)

* Default path of iarbuild:

```
C:\Program Files\IAR Systems\Embedded Workbench 9.2\common\bin
```

* Default path of ARM tools (including iccarm):

```
C:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\bin
```

For beLow to work properly with IAR Embedded Workbench for ARM, add these paths to your user's Path environment variable.

![Edit your user's environment variables](/files/bcd9abc4db244ddb4b8a0a3a218ea0fd5f650cef)

Edit your user's environment variables

{% stepper %}
{% step %}

### Add IAR tools to your PATH

Add the following directories to your user's Path environment variable:

* C:\Program Files\IAR Systems\Embedded Workbench 9.2\common\bin
* C:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\bin
  {% endstep %}

{% step %}

### Verify commands in a new terminal

After updating the environment, open a new terminal and verify the commands work:

{% code title="Verify commands" %}

```powershell
iarbuild --help
iccarm --help
```

{% endcode %}
{% endstep %}

{% step %}

### Restart beLowCTL

beLowCTL should be restarted after changing the user's environment for the changes to be recognized.
{% endstep %}

{% step %}

### Test building your project

In a terminal, check that your project can be built using iarbuild (example incremental build):

{% code title="Test build" %}

```powershell
iarbuild .\path\to\MyProject.ewp -make "MyConfig"
```

{% endcode %}
{% endstep %}
{% endstepper %}

Configuring beLow project scripts

* Configure section: leave blank.
* Clean section:
  * Script content:

{% code title="Clean script" %}

```powershell
iarbuild .\path\to\MyProject.ewp -clean "MyConfig"
```

{% endcode %}

* Script execution path: In the target directory
* Shell: Pwsh
* Build section:
  * Script content:

{% code title="Build script" %}

```powershell
iarbuild .\path\to\MyProject.ewp -make "MyConfig"
```

{% endcode %}

* Script execution path: In the target directory
* Shell: Pwsh

{% hint style="info" %}
Do not wrap your iarbuild command in another script: beLow needs to recognize the iarbuild command directly in the script to perform instrumentation for compilation database generation. The iarbuild command must appear directly in your script.
{% endhint %}


# Custom Docker image

## Add beLow dependencies to your build image

For beLow to work, your image must embed `below-orchestrator` and its dependencies. WedoLow provides installers for multiple Linux distributions (Ubuntu 22.04, Debian 11, RHEL8...).

We will take the example of an Ubuntu 22.04 Docker image for the example unrolled in this section.

{% stepper %}
{% step %}

### Prepare and build your base image

Example initial Dockerfile with your build dependencies:

{% code title="Dockerfile (base)" %}

```dockerfile
FROM ubuntu:22.04

# The installation of your own dependencies go here...
```

{% endcode %}

Build and tag this Docker image (skip if already built or tagged):

{% code title="Terminal" %}

```bash
docker build -t mybuildimage:latest .
```

{% endcode %}
{% endstep %}

{% step %}

### Create a Docker image embedding below-orchestrator

In a separate directory, place the `below-orchestrator.deb` installer provided by WedoLow and create a new Dockerfile like the following:

{% code title="Dockerfile (with below-orchestrator)" %}

```dockerfile
FROM mybuildimage:latest

# Copy Orchestrator installer
COPY below-orchestrator.deb below-orchestrator.deb

# Install Orchestrator
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive && \
    apt-get install -y ./below-orchestrator.deb && \
    rm -rf /var/lib/apt/lists/* && \
    rm below-orchestrator.deb

ENTRYPOINT [ "/usr/local/bin/below-orchestrator" ]
```

{% endcode %}

Build and tag the new image:

{% code title="Terminal" %}

```bash
docker build -t mybuildimage-below:latest .
```

{% endcode %}

Notes:

* If your original image had an ENTRYPOINT, it will be replaced when using the Docker image in beLow. Call the original entrypoint explicitly in scripts defined in beLow if needed.
* If you push your build image to a Docker registry, also push the beLow build image (mybuildimage-below:latest) to the same registry so it remains available if local images are cleaned.
  {% endstep %}
  {% endstepper %}

## Declare your build image as a new platform

To use the modified Docker image, beLow must know about it. This requires a beLow runner running in Docker mode. If you manage services with beLowCTL on a local install, you already have a Docker runner. The instructions below show how to configure this using beLowCTL.

Create a YAML file (for example `platforms-docker.yaml`) containing the platform declaration:

{% code title="platforms-docker.yaml" %}

```yaml
- usage: build
  type: docker
  arch: x86_64
  system:
    - name: Linux System
      os:
        - name: "Ubuntu"
          version:
            - name: "22.04 - Custom build environment"
              imageTag: "mybuildimage-below:latest"
              imagePlatform: "linux/amd64"
      cpu:
        - name: "Any"
```

{% endcode %}

Replace the `arch`, `system.os.version.imageTag` and `system.os.version.imagePlatform` values as needed. The other fields are primarily for display (except `usage` and `type`).

Now declare this platform file in beLowCTL configuration. Open or create the beLow config file and set the `runner.docker.platform_file` path to the path of `platforms-docker.yaml`.

{% tabs %}
{% tab title="Linux" %}
Open or create:

{% code title="${HOME}/.config/wedolow/config.json" %}

```
```

{% endcode %}

```json
{
  "runner": {
    "docker": {
      "platform_file": "/path/to/platforms-docker.yaml"
    }
  }
}
```

Replace `/path/to/platforms-docker.yaml` with the correct path on your system.
{% endtab %}

{% tab title="Windows" %}
Open or create:

{% code title="C:\Users\<YourUser>\AppData\Roaming\wedolow\config.json" %}

```
```

{% endcode %}

```json
{
  "runner": {
    "docker": {
      "platform_file": "C:\\path\\to\\platforms-docker.yaml"
    }
  }
}
```

Replace `C:\\path\\to\\platforms-docker.yaml` with the correct path on your system.
{% endtab %}
{% endtabs %}

Finally, restart beLowCTL if it is running.

When using beLow, you will now see an additional platform corresponding to your Docker image. Selecting this platform causes scripts to run in containers created from that image.

Important: Do not remove the `platforms-docker.yaml` file. If it is missing, the Docker runner will error on startup and break beLow. Keep it in a safe place (for example next to the `config.json`) so it persists while beLow is installed on your system.


# Bazel

This method should also be used on Linux, in case your Bazel setup involves some server-side build cache.

Using beLow with Bazel requires an intermediate representation of the compilation, called Bazel acyclic query graph, which is a specific JSON representation of a Bazel build. beLow transforms this representation into a compilation database.

To generate the requested file, use the `aquery` Bazel subcommand.

If your usual build command is:

```bash
bazel build //...
```

Generating the JSON graph to standard output is done by running:

```bash
bazel aquery //...
```

This output must be written to a file called `bazel_action_graph.json` during project configuration for beLow to understand the context. For example:

```bash
bazel aquery //... > bazel_action_graph.json
```

Note: On Windows, the encoding of the output graph could be incompatible with beLow because the output format depends on the system language. To force the output encoding using PowerShell:

```powershell
bazel aquery //... | Out-File -Encoding ASCII -FilePath ./bazel_action_graph.json
```

{% hint style="warning" %}
If your Bazel setup uses a server-side build cache, make sure to run the `aquery` generation step as part of project configuration so beLow has the full context.
{% endhint %}

### Configuration for beLow

Configure

{% tabs %}
{% tab title="Linux" %}

* Script content:

```bash
bazel aquery //... > bazel_action_graph.json
```

* Script execution path: In the target directory
* Shell: Bash
* Direct link to tab: <https://docs.wedolow.com/below-technical-documentation/compatibility-guide/bazel#tab-linux>
  {% endtab %}

{% tab title="Windows" %}

* Script content:

```powershell
bazel aquery //... | Out-File -Encoding ASCII -FilePath ./bazel_action_graph.json
```

* Script execution path: In the target directory
* Shell: Pwsh
* Direct link to tab: <https://docs.wedolow.com/below-technical-documentation/compatibility-guide/bazel#tab-windows>
  {% endtab %}
  {% endtabs %}

Clean

{% tabs %}
{% tab title="Linux" %}

* Script content:

```bash
bazel clean //...
```

* Script execution path: In the target directory
* Shell: Bash
* Direct link to tab: <https://docs.wedolow.com/below-technical-documentation/compatibility-guide/bazel#tab-linux-1>
  {% endtab %}

{% tab title="Windows" %}

* Script content:

```powershell
bazel clean //...
```

* Script execution path: In the target directory
* Shell: Pwsh
* Direct link to tab: <https://docs.wedolow.com/below-technical-documentation/compatibility-guide/bazel#tab-windows-1>
  {% endtab %}
  {% endtabs %}

Build

{% tabs %}
{% tab title="Linux" %}

* Script content:

```bash
bazel build //...
```

* Script execution path: In the target directory
* Shell: Bash
* Direct link to tab: <https://docs.wedolow.com/below-technical-documentation/compatibility-guide/bazel#tab-linux-2>
  {% endtab %}

{% tab title="Windows" %}

* Script content:

```powershell
bazel build //...
```

* Script execution path: In the target directory
* Shell: Pwsh
* Direct link to tab: <https://docs.wedolow.com/below-technical-documentation/compatibility-guide/bazel#tab-windows-2>
  {% endtab %}
  {% endtabs %}


# Tutorials

[Manual dynamic analysis](/documentation/ressources/tutorials/manual-dynamic-analysis)

<a href="/pages/8f39d06e4c42dc9f7345ecba79bcfacdc12cdc8f" class="button primary">Open Manual dynamic analysis</a>

Last updated 3 months ago


# Manual dynamic analysis

### When is manual dynamic analysis relevant?

Though beLow allows you to run dynamic analysis automatically, this is not always possible, depending on your use case.

Automated dynamic analysis will not be possible if:

* You are running your application in an environment unable to print data to a file (usage of `fprintf` not possible)
* Running your application is not scriptable (e.g., requires clicking in some Windows software, requires human interaction, etc)

In this context, there are two possibilities:

* Running static analysis only: beLow will still be able to find some optimizations, but their impact will certainly be under or over-evaluated. An optimization in an initialization function and an optimization in a deep for-loop would have the same weight, while in runtime reality, the first one would be executed once and the second one million times.
* Running manual dynamic analysis: in this case, we provide you an instrumented code that you manually have to build, run, and retrieve data from.

Manual dynamic analysis is not suitable in fully automated environments like CI/CD, but it is recommended when you want accurate insights about what beLow can improve in your code.

### How to run a manual dynamic analysis?

When setting up a project without automated dynamic analysis, before running analysis, you get a card prompting either to run static analysis or to use manual dynamic analysis.

Before analysis

![](/files/d5263dbddf5b9424bd56b6ed45e2b0eb032e99f9)

At this point, you have 2 choices:

* Run a static analysis by clicking Run analysis, or
* Perform a manual dynamic analysis

The steps to run a manual dynamic analysis are:

{% stepper %}
{% step %}

### Download instrumented code

Click the corresponding button in the UI to download `instrumented-code.zip`. Unzip it. The archive contains:

* `main.c`: the instrumented code. Ideally do not modify this file.
* `below_vendor.i`: beLow vendor generated code (not supposed to be modified).
* `below_instr.i`: beLow customizable code which you should modify as needed.

Merge the unzipped code into your original project (or a copy). The instrumented code adds counters to measure execution frequency of code blocks and formats data for export.
{% endstep %}

{% step %}

### Merge and optionally adapt instrumented code

Merge the instrumented files into your project. You may:

* Apply the instrumented files directly to the original project (you can revert later with git), or
* Work in a copy of your project.

Default behavior implemented by the instrumented code:

* Allocates a global array of counters
* Increments counters (one index per instrumented block)
* Prints counters as text into a file named `wedolow.prof` when the program exits

Modify `below_instr.i` if your environment requires different behavior (for example, sending profile output over UART on a microcontroller).
{% endstep %}

{% step %}

### Build the instrumented code

Build the project as you normally would (example for the sample project below). Ensure build uses the instrumented files.
{% endstep %}

{% step %}

### Run your application in a prod-like environment

Execute the instrumented binary. If your application is long-running (e.g., infinite loop), use the `BELOW_DYNAMIC_ANALYSIS` preprocessor macro in your original code to limit execution for profiling purposes (see example below).
{% endstep %}

{% step %}

### Retrieve profiling data

After execution finishes, retrieve the `wedolow.prof` file (or the data produced by your custom `below_instr.i` implementation).
{% endstep %}

{% step %}

### Upload profiling data and run analysis

Upload the profiling file to beLow using the UI, then click Run analysis. beLow will take profiling information into account.
{% endstep %}
{% endstepper %}

In the next section we walk through a full example.

#### Example project

The example project is a single-file C program that sums two random integer vectors every 1 second in an endless loop.

main.c

```c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#define N 5

void vect_add(int *a, int *b, int *c, int n) {
    for (int i = 0; i < n; i++) {
        c[i] = a[i] + b[i];
    }
}

int main() {
    int *a = malloc(N * sizeof(int));
    int *b = malloc(N * sizeof(int));
    int *c = malloc(N * sizeof(int));
    if (!a || !b || !c) {
        fprintf(stderr, "Memory allocation failed\n");
        return 1;
    }

    srand(time(NULL));

    while (1) {
        for (int i = 0; i < N; i++) {
            a[i] = rand() % 100;
            b[i] = rand() % 100;
        }

        vect_add(a, b, c, N);

        printf("a: ");
        for (int i = 0; i < N; i++) printf("%d ", a[i]);
        printf("\nb: ");
        for (int i = 0; i < N; i++) printf("%d ", b[i]);
        printf("\nc: ");
        for (int i = 0; i < N; i++) printf("%d ", c[i]);
        printf("\n\n");

        sleep(1);
    }

    free(a);
    free(b);
    free(c);
    return 0;
}
```

Build command used in the example:

```bash
gcc -O2 -o exec main.cpp
```

**Download instrumented code**

![](/files/8757d59bec94731c88646462fe917b094da1b1c6)

After unzipping, merge the instrumented files into the project as described above.

The instrumented `main.c` contains calls to `BELOW_COUNT(id)` and an include of `below_instr.i`, for example:

main.c (instrumented)

```c
#include "below_instr.i"
void BELOW_COUNT(int id);
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#define N 5

void vect_add(int *a, int *b, int *c, int n) {
{BELOW_COUNT(1);}

    for (int i = 0; i < n; i++) {
    {BELOW_COUNT(2);}

        c[i] = a[i] + b[i];
    }
    {BELOW_COUNT(3);}

}

int main() {
{BELOW_COUNT(0);}

    int *a = malloc(N * sizeof(int));
    int *b = malloc(N * sizeof(int));
    int *c = malloc(N * sizeof(int));
    if (!a || !b || !c) {
    {BELOW_COUNT(4);}

        fprintf(stderr, "Memory allocation failed\n");
        return 1;
    }
    {BELOW_COUNT(5);}


    srand(time(NULL));

    while (1) {
    {BELOW_COUNT(6);}

        for (int i = 0; i < N; i++) {
        {BELOW_COUNT(8);}

            a[i] = rand() % 100;
            b[i] = rand() % 100;
        }
        {BELOW_COUNT(9);}


        vect_add(a, b, c, N);

        printf("a: ");
        for (int i = 0; i < N; i++) {

        {BELOW_COUNT(10);}
        printf("%d ", a[i]);
        }
        {BELOW_COUNT(11);}

        printf("\nb: ");
        for (int i = 0; i < N; i++) {

        {BELOW_COUNT(12);}
        printf("%d ", b[i]);
        }
        {BELOW_COUNT(13);}

        printf("\nc: ");
        for (int i = 0; i < N; i++) {

        {BELOW_COUNT(14);}
        printf("%d ", c[i]);
        }
        {BELOW_COUNT(15);}

        printf("\n\n");

        sleep(1);
    }
    {BELOW_COUNT(7);}


    free(a);
    free(b);
    free(c);
    return 0;
}
```

The file `below_instr.i` contains the custom logic for counters:

below\_instr.i

```c
#ifndef BELOW_INSTR_I
#define BELOW_INSTR_I

#include "below_vendor.i"

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>

// You may want to change the base type of the counters to smaller types
typedef long long below_counter_t;
below_counter_t* BELOW_counters = NULL;

// This will be called when the first BELOW_COUNT is called or when BELOW_finish is called if
// BELOW_COUNT is never called
void BELOW_init_custom(){
    // Initialize the counters with BELOW_N_COUNTERS (defined in below_vendor.i)
    BELOW_counters = (below_counter_t*)malloc(sizeof(below_counter_t) * BELOW_N_COUNTERS);
    memset(BELOW_counters, 0, sizeof(below_counter_t)*BELOW_N_COUNTERS);

    // BELOW_finish must be called before the program exits. It calls BELOW_finish_custom
    // If atexit is not available, you may use BELOW_DYNAMIC_ANALYSIS definition in your original
    // code to call BELOW_finish directly only in the dynamic analysis context
    atexit(BELOW_finish);
}

void BELOW_COUNT_custom(int id) {
    // Counters must be incremented here
    BELOW_counters[id]++;
}

void BELOW_finish_custom() {
    // When your run script is over, counters must be written to wedolow.prof file
    // in the run script directory
    // If you can't write files, you must find another way to print the counter and use your
    // run script to read them and write them to wedolow.prof file
    FILE* f = fopen("wedolow.prof", "w+");
    // First write the number of counters
    fprintf(f, "%d,", BELOW_N_COUNTERS);
    // Then write the counters
    for(int i=0; i<BELOW_N_COUNTERS; i++){
        fprintf(f, "%lld,", BELOW_counters[i]);
    }
    fclose(f);
    // Clean up before exit.
    // Be sure that no counter increment is done after this point
    free(BELOW_counters);
}

#endif
```

Key elements inside `below_instr.i`:

* Counters array and type:

```c
typedef long long below_counter_t;
below_counter_t* BELOW_counters = NULL;
```

Modify the type depending on your platform and expected maximum counter values.

* Initialization function called on first count (or via atexit):

```c
void BELOW_init_custom()
```

* Custom count function called on each instrumented point:

```c
void BELOW_COUNT_custom(int id)
```

* Finish function that writes `wedolow.prof` by default:

```c
void BELOW_finish_custom()
```

`below_vendor.i` (vendor code) defines, among other things, the preprocessor variable:

```c
#define BELOW_DYNAMIC_ANALYSIS
```

You may use `BELOW_DYNAMIC_ANALYSIS` in your original code to alter behavior only in dynamic analysis mode. For example, the original infinite loop can be limited to a fixed number of iterations in dynamic analysis mode to allow the instrumented run to end and produce profiling output.

Example: original main modified for dynamic analysis to stop after 10 iterations

main.c (modified)

```c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

#define N 5

void vect_add(int *a, int *b, int *c, int n) {
    for (int i = 0; i < n; i++) {
        c[i] = a[i] + b[i];
    }
}

int main() {
    int *a = malloc(N * sizeof(int));
    int *b = malloc(N * sizeof(int));
    int *c = malloc(N * sizeof(int));
    if (!a || !b || !c) {
        fprintf(stderr, "Memory allocation failed\n");
        return 1;
    }

    srand(time(NULL));

#ifdef BELOW_DYNAMIC_ANALYSIS
    int loop_counter = 0;
#endif
    while (1) {
        for (int i = 0; i < N; i++) {
            a[i] = rand() % 100;
            b[i] = rand() % 100;
        }

        vect_add(a, b, c, N);

        printf("a: ");
        for (int i = 0; i < N; i++) printf("%d ", a[i]);
        printf("\nb: ");
        for (int i = 0; i < N; i++) printf("%d ", b[i]);
        printf("\nc: ");
        for (int i = 0; i < N; i++) printf("%d ", c[i]);
        printf("\n\n");

        sleep(1);
#ifdef BELOW_DYNAMIC_ANALYSIS
        loop_counter++;
        if (loop_counter >= 10) {
            break; // Stop after 10 iterations
        }
#endif
    }

    free(a);
    free(b);
    free(c);
    return 0;
}
```

The corresponding instrumented version includes the same `BELOW_COUNT` calls; when built with the dynamic-analysis-aware original code, the instrumented run will terminate after 10 iterations.

Build and run the instrumented example:

```bash
> gcc -O2 -o exec main.cpp
> ./exec
a: 4 40 69 24 32
b: 90 40 3 42 20
c: 94 80 72 66 52

[...]

a: 2 79 63 28 87
b: 27 77 91 93 30
c: 29 156 154 121 117
```

When the instrumented execution stops, `wedolow.prof` is created. Example content:

wedolow\.prof

```
16,1,10,50,10,0,1,10,1,50,10,50,10,50,10,50,10,
```

* The first number (16) is the number of counters (BELOW\_N\_COUNTERS).
* Following numbers are the counter values recorded during the run.

Upload the `wedolow.prof` file via the beLow UI and click Run analysis. The analysis will incorporate the execution data.

### Adapting manual dynamic analysis to your usage

For any project, the instrumented package contains:

* A modified version of your project files (content depends on the project)
* `below_vendor.i` (stable vendor content)
* `below_instr.i` (customizable)

All custom logic (counters allocation, initialization, termination) is in `below_instr.i`. In most cases you only need to modify this file and keep a copy in your project so you don't rewrite changes for each manual analysis.

Ensure your instrumented execution ends at some point. Use `BELOW_DYNAMIC_ANALYSIS` in your original code if needed to limit runtime.

Examples of custom modifications (illustrative of use cases present in the original content):

* On microcontrollers, initialize UART and write profiling data to UART instead of a file, then copy-paste output into `wedolow.prof`.
* If you have debug tools accessing program memory, read the counters array directly and format the data offline.

In both cases, modifying `below_instr.i` should be sufficient.

Upload profiling data

![](/files/ab25f6d1050281d56dce56f77b7510f60f9a5ae9)

Once uploaded, click Run analysis. The analysis will use your profiling information.

Last updated 3 months ago


# Wedolow Optimization Families

<details>

<summary>Memory Management Optimizations</summary>

**What it does:** Optimizes how your code uses memory - reducing allocations, eliminating unnecessary copies, and improving data access patterns.

**Benefits**: Lower memory usage, fewer memory allocation cycles, better cache performance, better CPU performance since removing useless memory operations.

**Examples**: Pre-allocating container memory, using references instead of copying objects, eliminating unused array operations.

<mark style="color:$success;">**Optimizations**</mark><mark style="color:$success;">: Push\_back to Emplace\_back, Track Vector Reserve, Track array usages, Copy Hunter</mark>

</details>

<details>

<summary>Arithmetic &#x26; Mathematical Optimizations</summary>

**What it does**: Improves mathematical calculations by using appropriate data types, replacing expensive operations, and leveraging hardware capabilities.

**Benefits**: Faster math operations, reduced precision where not needed, better suited for embedded processors without floating-point units.

**Examples**: Converting to fixed-point arithmetic, using single precision instead of double, replacing complex math functions with approximations.

<mark style="color:$success;">**Optimizations**</mark><mark style="color:$success;">: Fixed Point Conversion, Double2Float, Libm Fcts Types, Polynomial Approximation, Divide Hunter</mark>

</details>

<details>

<summary>Loop &#x26; Vectorization Optimizations</summary>

**What it does**: Transforms loops to process multiple data elements simultaneously and removes dependencies that prevent parallel execution.

**Benefits**: Important speed improvements through SIMD instructions, better utilization of modern processor capabilities.

**Examples**: Vectorizing independent loop iterations, inlining functions to enable vectorization, optimizing loop structures.

<mark style="color:$success;">**Optimizations**</mark><mark style="color:$success;">: SIMD-Opportunities, For loop data dependency, SIMD-ExternalFunctions, SIMD-GCD, AoS/SoA</mark>

</details>

<details>

<summary>Compiler &#x26; Code Generation Optimizations</summary>

**What it does**: Enhances how the compiler generates machine code by optimizing control flow, function calls, and enabling advanced compiler features.

**Benefits**: More efficient assembly code, better processor-specific optimizations, reduced function call overhead.

**Examples**: Optimizing switch statements, enabling aggressive compiler optimizations, using processor-specific instructions.

<mark style="color:$success;">**Optimizations**</mark><mark style="color:$success;">: Const Volatile, Enum/Switch Operations, FctFactorization, OptimO3, Flags-MathOps,  Min/Max/Sat Operations</mark>

</details>

<details>

<summary>Type System &#x26; Casting Optimizations</summary>

**What it does**: Analyzes and optimizes type conversions and enables architecture-specific features for the target embedded platform.

**Benefits**: Eliminates expensive hidden type conversions, leverages target processor capabilities.

**Examples**: Tracking implicit casts to make them explicit if required, or pinpoint a useless cast that can be removed, enabling processor-specific optimizations.

<mark style="color:$success;">**Optimizations**</mark><mark style="color:$success;">: Track implicit cast, ArchiFlags</mark>

</details>

### Key Benefits for Embedded Systems

* [x] **Performance**: Faster execution through vectorization, better math operations, and optimized code generation.
* [x] **Resource Efficiency**: Lower memory usage, reduced CPU cycles, better utilization of limited embedded resources.
* [x] **Hardware Optimization**: Takes advantage of specific processor features and avoids expensive operations on resource-constrained devices.
* [x] **Systematic Approach**: Automatically categorizes optimizations by safety level (bit-exact, lossy, permissive) and whether they can be safely automated or require manual review.

<br>


# FAQ

<details>

<summary>Does beLow support MacOS?</summary>

No, beLow does not support MacOS for now.

Original source: <https://docs.wedolow.com/below-technical-documentation/faq-troubleshooting/faq#does-below-support-macos>

</details>

<details>

<summary>What is the value to use for beLow server when using the UI?</summary>

* If you are running the product in local mode, keep the default value (`http://localhost:18080/core`)
* If you are using a remote server deployed by your organization, please ask the IT team of your organization.

Original source: <https://docs.wedolow.com/below-technical-documentation/faq-troubleshooting/faq#what-is-the-value-to-use-for-below-server-when-using-the-ui>

</details>


# Troubleshooting

<details>

<summary>Why beLow CTL does not start anymore (no tray)?</summary>

There might have been a problem while releasing the lock preventing it from opening multiple times.

To release the lock, remove the tray.lock file for your platform:

${HOME}/.config/wedolow/tray.lock%USERPROFILE%\AppData\Roaming\wedolow\tray.lock

If the problem persists, please contact us at <support@wedolow.com>.

</details>

<details>

<summary>Why the user interface does not run because of missing libraries on Windows?</summary>

You may have missed installing the Visual Studio C++ Redistributable 2017 listed in the [requirements](https://docs.wedolow.com/below-technical-documentation/readme/installation-instructions/windows/requirements).

</details>

<details>

<summary>Why a CMake build may fail on Windows?</summary>

This can happen because of a possibly faulty compilation database generated by CMake on Windows when injecting preprocessor variable definitions with certain syntax, for example:

```cmake
add_definitions(-DLIB_HEADER_FILE="lib.h")
```

You may find ways to overcome this issue in the compatibility guide: <https://docs.wedolow.com/below-technical-documentation/compatibility-guide/cmake#windows-specificities>

</details>

<details>

<summary>Why jobs fail and log archives are empty?</summary>

This occurs when the time on the machine where the runners run and the machine where the server runs differ (known date/time mismatch).

* For Windows full-desktop usage: check that Windows and WSL time are synced.
* For distributed usage: check time sync for all machines. If they are not in sync, enable internet time synchronization when possible or set the time manually so all machines match the same time zone.

</details>


