diff --git a/.wordlist.txt b/.wordlist.txt index 74cfd01317..ab04032169 100644 --- a/.wordlist.txt +++ b/.wordlist.txt @@ -5656,4 +5656,105 @@ actionability customizations pyaudio sounddevice -webrtcvad \ No newline at end of file +webrtcvad +APM +DevSecOps +Jaeger +OTLP +Opentelemetry +Trivy +Zipkin +azurecompute +jaeger +jaegertracing +opentelemetry +otel +techcommunity +trivy +vms +AWSTemplateFormatVersion +AllowedValues +BlockDeviceMappings +BuildHost +BuildSecurityGroup +BuildSecurityGroupId +CidrIp +DeleteOnTermination +DeviceName +Ebs +EdgeBlox +Fastpath's +FastpathHost +FastpathSecurityGroup +FastpathSecurityGroupId +FromPort +GLDBOX +GOLDBOX +GetAtt +GitLab's +GoldBox +GroupDescription +GroupId +HasFastpathPeer +ImageId +InstanceId +InstanceType +IpProtocol +KeyName +KeyPair +KeyPairName +LTO's +LatestUbuntuAmiId +MaxValue +MicroBoost +MicroPacFiles +MinValue +PlanExec +PrivateIp +PublicIp +ResourceType +RootFS +RootVolumeSizeGiB +SDcard +SSHAllowedCidr +SUT's +SecurityGroup +SecurityGroupEgress +SecurityGroupId +SecurityGroupIds +SecurityGroupIngress +SourceSecurityGroupId +SubnetId +SutHost +SutPeerIngress +SutSecurityGroup +SutSecurityGroupId +ToPort +VNP +Validator +VolumeSize +VolumeType +VpcId +cloudformation +deepsjeng +downsampling +ebs +edgeblox +fastpath +hvm +leela +mcf +micropacfile +partitioner +practise +representativeness +runit +sda +sdb +sg +ssm +sut +swprofiles +techsupport +upscaler +walkthroughs diff --git a/assets/contributors.csv b/assets/contributors.csv index 69b9b68be3..b1ed1f8230 100644 --- a/assets/contributors.csv +++ b/assets/contributors.csv @@ -112,3 +112,4 @@ Yahya Abouelseoud,Arm,,,, Steve Suzuki,Arm,,,, Qixiang Xu,Arm,,,, Phalani Paladugu,Arm,phalani-paladugu,phalani-paladugu,, +Richard Burton,Arm,Burton2000,,, \ No newline at end of file diff --git a/assets/css/content-pages.css b/assets/css/content-pages.css index 908cd362dc..6e95ef59d9 100644 --- a/assets/css/content-pages.css +++ b/assets/css/content-pages.css @@ -63,6 +63,18 @@ html[theme='dark'] .tab-right-card > h6 { font-size:1em; } +/* Force a 2-line clamp for masthead title */ +ads-masthead #ads-masthead-title { + line-height: 1.2; + padding-bottom: 6px; + box-sizing: border-box; + max-height: calc(1.2em * 2 + 8px); /* dyncamically calculate height depending on length of title */ + overflow: hidden; + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + white-space: normal; +} /* hover effects */ @@ -268,4 +280,4 @@ html[theme='dark'] .incorrect-explain {color: #e86868} /* 27% lighter than arm's padding-bottom: 6px; padding-right: 16px; font-size: 16px; -} \ No newline at end of file +} diff --git a/assets/css/cross-page.css b/assets/css/cross-page.css index 9356ec8191..bdce13fe69 100644 --- a/assets/css/cross-page.css +++ b/assets/css/cross-page.css @@ -209,17 +209,18 @@ table tbody td { /* Fix Masthead Height */ #expanded-masthead { background-color: transparent; - height: 105px; /* You must set a specified height */ - background-position: center; /* Center the image */ - background-repeat: no-repeat; /* Do not repeat the image */ - background-size: cover; /* Resize the background image to cover the entire container */ - border-bottom: 1px solid #303133; /* bottom border across page */ -} -@media (max-width: 768px) { /* smaller screens than MD */ - #expanded-masthead { - height: 90px; /* You must set a specified height */ - } + min-height: 100px; /* Keep baseline height for short titles */ + height: auto; /* Allow 2-line titles to expand */ + background-position: center; + background-repeat: no-repeat; + background-size: cover; + border-bottom: 1px solid #303133; +} +#expanded-masthead.is-two-lines { + min-height: 160px; } + + /* remove bottom border from ads-masthead component */ ads-masthead { --ads-masthead-border-bottom-color: transparent; @@ -452,7 +453,3 @@ html[theme='light'] body { ads-masthead { --ads-masthead-horizontal-padding: 5px; } } - - - - diff --git a/content/learning-paths/automotive/tinkerblox_ultraedge/_index.md b/content/learning-paths/automotive/tinkerblox_ultraedge/_index.md deleted file mode 100644 index 91dfb36697..0000000000 --- a/content/learning-paths/automotive/tinkerblox_ultraedge/_index.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -title: UltraEdge HPC-I execution fabric for AI & mixed workloads - -draft: true -cascade: - draft: true - -minutes_to_complete: 60 - -who_is_this_for: Business teams targeting lower TCO of computing infrastructure through higher utilization of CPU and/or CPU-GPU install bases. R&D and Engineering teams looking for most efficient use of CPU/CPU-GPU infrastructure. Innovation teams looking to maximize edge resources to host new-age AI on constrained environments. Development teams looking at alternative packaging tech – run-time environments to build next generation workloads. - -learning_objectives: - - Understand the layered architecture of UltraEdge **core**, **boost**, and **prime** - - Build applications using the **UltraEdge MicroStack** - - Deploy the MicroPacs on **Linux-based compute systems** and scale to cloud or data-center environments - - Optimize performance for **edge-cloud scenarios**, enabling near real-time data flows - - -prerequisites: - - Experience using **Linux** on embedded or SBC platforms. - - Understanding of **container runtimes** (containerd) and **CNI - networking**. - - Basic knowledge of **communication protocols** (MQTT, HTTP, etc.). - - (Optional but helpful) Familiarity with **edge-cloud - architectures** and **data-flow orchestration**. - -author: Tinkerblox - -### Tags -skilllevels: Advanced -subjects: Containers and Virtualization -tools_software_languages: - - Tinkerblox - -armips: - - Neoverse - -operatingsystems: - - Linux - - other - -further_reading: - - resource: - title: Tinkerblox - link: https://tinkerblox.io - type: website - - -### FIXED, DO NOT MODIFY -# ================================================================================ -weight: 1 # _index.md always has weight of 1 to order correctly -layout: "learningpathall" # All files under learning paths have this same wrapper -learning_path_main_page: "yes" # This should be surfaced when looking for related content. Only set for _index.md of learning path content. ---- diff --git a/content/learning-paths/automotive/tinkerblox_ultraedge/background.md b/content/learning-paths/automotive/tinkerblox_ultraedge/background.md deleted file mode 100644 index c32fd13a54..0000000000 --- a/content/learning-paths/automotive/tinkerblox_ultraedge/background.md +++ /dev/null @@ -1,99 +0,0 @@ ---- -title: UltraEdge HPC-I execution fabric for AI & mixed workloads - -weight: 2 - -layout: "learningpathall" ---- - -### Introduction - -UltraEdge is an edge-native, high-performance execution fabric designed to run AI and mixed workloads without the overhead of traditional container platforms. While technologies like Docker and Kubernetes were created for general-purpose cloud environments, they introduce latency, resource bloat, and non-deterministic behavior that are poorly suited for edge deployments. - -UltraEdge takes a fundamentally different approach. It replaces heavyweight container runtimes with a lean, deterministic execution stack purpose-built for performance-oriented compute. This enables millisecond-level startup times, predictable performance, and a dramatically smaller resource footprint—allowing workloads to start faster, run closer to the hardware, and make full use of available CPU and GPU resources. - -At the core of UltraEdge are two specialized execution systems: - -· **MicroStack**, optimized for enterprise and mixed workloads - -· **NeuroStack**, purpose-built for AI inference and accelerated compute - -Together, these systems deliver up to **30× faster startup times** and **3.8× smaller package sizes** compared to conventional container-based approaches. By removing unnecessary abstraction layers, UltraEdge ensures compute cycles are spent on execution—not on managing the runtime itself. - -This learning path introduces the architecture, principles, and components that make UltraEdge a high-performance execution fabric for modern edge infrastructure. - -### Ultraedge overview - -UltraEdge was built with the vision of **orchestrating the edge-native execution fabric for high-performance compute infrastructure** - -Key design principles and capabilities include: - -· **Built-for-edge execution stack** - -A lightweight, adaptive platform for **AI and mixed workloads** optimized for low latency, high determinism, and minimal footprint. - -· **Dual workload focus** - -Native support for both traditional enterprise workloads and next-generation AI workloads, without compromising performance. - -· **Full-stack enablement** - -Delivered through the **MicroStack** and **NeuroStack** execution systems, each optimized for its workload domain. - -· **High fungibility and efficiency** - -Maximizes utilization of CPU and GPU resources while reducing operational and infrastructure overhead. - -· **Ecosystem-aligned development** - -Developed through strategic alliances with leading technology partners and curated for **AI@Edge**, including alignment with Edge AI Foundation deployment approaches. - -· **Cluster-aware orchestration** - -Integrates with Kubernetes-based stacks and Slurm for managed cluster orchestration. - -· **Built-in observability** - -Provides control-plane visibility, diagnostics, and telemetry for operational insight. - -· **Lower total cost of ownership (TCO)** - -Demonstrable reduction in CPU/GPU cluster costs through faster startup, higher utilization, and reduced runtime overhead. - -### UltraEdge high-level architecture - -UltraEdge is composed of layered systems, each responsible for a distinct aspect of execution and orchestration: - -![High-level Architecture diagram](https://raw.githubusercontent.com/Tinkerbloxsupport/arm-learning-path-support/main/static/images/High-level%20architecture%20diagram.png) - ---- - -#### UltraEdge Core Layer -*Manages the foundational execution fabric, including:* -* Compute infrastructure management -* Service orchestration and lifecycle management -* Rule-engine orchestration -* Data-flow management across workloads - -#### UltraEdge Boost Layer -*Provides performance-critical acceleration, including:* -* Low-level optimized routines -* FFI (Foreign Function Interface) integrations -* Dynamic connectors and southbound protocol adapters - -#### UltraEdge Prime Layer -*Implements workload intelligence and orchestration logic, including:* -* Business logic execution -* Trigger and activation sequences -* AI and mixed workload coordination - -#### UltraEdge Dock -*Provides workload and cluster orchestration through:* -* Kubernetes-based stacks -* Slurm-based scheduling environments - -#### UltraEdge Edge-Cloud Connect Layer -*Enables data movement and observability, including:* -* Data streaming to databases (for example, InfluxDB, SQLite) -* Diagnostics, logging, and telemetry outputs - diff --git a/content/learning-paths/automotive/tinkerblox_ultraedge/running.md b/content/learning-paths/automotive/tinkerblox_ultraedge/running.md deleted file mode 100644 index c06a7b0c23..0000000000 --- a/content/learning-paths/automotive/tinkerblox_ultraedge/running.md +++ /dev/null @@ -1,148 +0,0 @@ ---- -title: Running UltraEdge HPC-I execution fabric for AI & mixed workloads - -weight: 6 - -layout: "learningpathall" ---- - - -This section provides a hands-on walkthrough of the Tinkerblox CLI to help you explore how microservices are deployed, managed, and monitored on the UltraEdge platform. The exercises focus on inspecting system state, installing a sample microservice, and observing its runtime behavior. - -To practice the commands below, install and run a sample microservice on your device. Use below git link find a mpac file(only for practice purpose). - -https://github.com/Tinkerbloxsupport/arm-learning-path-support/blob/main/static/Sample_ms/dte_nn.mpac - -### Tinkerblox CLI usage guide - -Tinkerblox Command Line Interface for managing the Edge Agent and -microservices. - -**Usage:** - - tinkerblox-cli [OPTIONS] - -**Commands:** - -- `status` — Show connection status with the Edge Agent -- `microboost` — Microservice management commands -- `help` — Print this message or the help of the given subcommand(s) - -**Options:** - -- `-h`, `--help` — Print help -- `-V`, `--version` — Print version - -### Usage - -#### Check CLI connection status - -```bash - sudo tinkerblox-cli status -``` - -*Displays whether the CLI is connected to the Edge Agent.* - -#### Microservice management - -Manage microservices running on the Edge platform. - -**Syntax:** - - sudo tinkerblox-cli microboost [options] - -##### Available commands - -* **install** - Installs a microservice. You must provide the path to the MPAC file as an argument. - - sudo tinkerblox-cli microboost install -f /path/to/your.mpac - -* **list** - Lists all installed microservices. - - sudo tinkerblox-cli microboost list - -* **status ** - Shows statistics (CPU, memory, status, etc.) for the specified microservice. - - sudo tinkerblox-cli microboost status - -* **stop ** - Stops the microservice with the specified ID. - - sudo tinkerblox-cli microboost stop - -* **start ** - Starts the microservice with the specified ID (must be stopped). - - sudo tinkerblox-cli microboost start - -* **uninstall ** - Uninstalls the microservice with the specified ID. - - sudo tinkerblox-cli microboost uninstall - -#### Diagnostics management - -Run diagnostics on the Edge platform. - -**Syntax:** - - sudo tinkerblox-cli diagnostics - -**full** : Run complete system diagnostics and summarize results - - sudo tinkerblox-cli diagnostics full - -**system** : Check CPU, memory, and OS-level health - - sudo tinkerblox-cli diagnostics system - -**network** : Verify network connectivity and endpoint reachability - - sudo tinkerblox-cli diagnostics network - -**filesystem** : Validate database/filesystem connectivity and integrity - - sudo tinkerblox-cli diagnostics filesystem - -**engine** : Check engine microboost neuroboost - - sudo tinkerblox-cli diagnostics engine - -## Troubleshooting - - The following sections describe common errors you may encounter while running CLI commands or deploying microservices, along with guidance on how to resolve them. These are general errors and are not limited to any specific scenario; they may occur while executing commands or managing the system. - -Permission denied - -- Ensure `sudo` privileges. -- Check directory ownership and permissions. -- Verify overlay filesystem support. - -Directory creation failed - -- Check disk space. -- Verify parent directory permissions. -- Ensure the path is valid. - -Cross-architecture build issues - -Cross-architecture issues typically occur when binaries are built for a different CPU architecture than the host system. They are not related to yocto build issues. - -- Verify QEMU installation: - -```bash - qemu-aarch64-static --version -``` - -- Check binfmt registration: - -```bash - ls /proc/sys/fs/binfmt_misc/ -``` - -- Ensure the target architecture is enabled. - -- If issues persist, change the host architecture. \ No newline at end of file diff --git a/content/learning-paths/cross-platform/gitlab-managed-runners/_images/ci-cd-new.png b/content/learning-paths/cross-platform/gitlab-managed-runners/_images/ci-cd-new.png new file mode 100644 index 0000000000..107e5ea2ac Binary files /dev/null and b/content/learning-paths/cross-platform/gitlab-managed-runners/_images/ci-cd-new.png differ diff --git a/content/learning-paths/cross-platform/gitlab-managed-runners/_images/ci-cd-new.webp b/content/learning-paths/cross-platform/gitlab-managed-runners/_images/ci-cd-new.webp deleted file mode 100644 index 60103e620b..0000000000 Binary files a/content/learning-paths/cross-platform/gitlab-managed-runners/_images/ci-cd-new.webp and /dev/null differ diff --git a/content/learning-paths/cross-platform/gitlab-managed-runners/_index.md b/content/learning-paths/cross-platform/gitlab-managed-runners/_index.md index ebc3a1dd9a..b8eab1f16a 100644 --- a/content/learning-paths/cross-platform/gitlab-managed-runners/_index.md +++ b/content/learning-paths/cross-platform/gitlab-managed-runners/_index.md @@ -1,10 +1,6 @@ --- title: Build a CI/CD pipeline using GitLab-hosted Arm runners -draft: true -cascade: - draft: true - minutes_to_complete: 30 @@ -25,7 +21,8 @@ author: Mohamed Ismail ### Tags skilllevels: Introductory subjects: CI-CD -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/cross-platform/gitlab-managed-runners/info.md b/content/learning-paths/cross-platform/gitlab-managed-runners/info.md index 820fa00511..320826f91d 100644 --- a/content/learning-paths/cross-platform/gitlab-managed-runners/info.md +++ b/content/learning-paths/cross-platform/gitlab-managed-runners/info.md @@ -1,5 +1,5 @@ --- -title: GitLab runners overview +title: Build and use GitLab-hosted Arm runners for CI/CD weight: 2 ### FIXED, DO NOT MODIFY @@ -8,14 +8,16 @@ layout: learningpathall ## What is a GitLab runner? -A GitLab Runner is an agent that executes CI/CD jobs defined in your pipeline configuration. GitLab offers two types: +A GitLab Runner is an agent that executes CI/CD jobs defined in your pipeline configuration. GitLab offers two types of runners: -- **GitLab-hosted runners**: Managed by GitLab, no setup required -- **Self-managed runners**: You install and manage on your own infrastructure +- **GitLab-hosted runners**: GitLab manages these runners, so you don't need to set up or maintain infrastructure. +- **Self-managed runners**: you install and maintain these runners on your own infrastructure. -When you register a runner, you choose an executor that determines the job environment (Docker, Shell, Kubernetes, etc.). +For Arm development, GitLab-hosted runners offer a managed way to build and test applications targeting Arm platforms without maintaining your own infrastructure. You'll choose between the Docker executor (for containerized builds) or the Shell executor (for direct access to the Arm64 runner environment). -### Arm64 runner support +When you register a runner, you specify an executor that determines the job environment. For Arm development workflows, Docker and Shell executors are the most common choices, letting you build container images or compile applications directly on native Arm64 hardware. + +## Arm64 runner support GitLab-hosted runners support both x86-64 and arm64 architectures. For developers targeting Arm platforms (servers, edge devices, or embedded systems), using Arm64 runners provides: @@ -25,7 +27,7 @@ GitLab-hosted runners support both x86-64 and arm64 architectures. For developer - Faster builds when targeting Arm64 platforms {{% notice Note %}} -GitLab-hosted runner specifications are subject to change. See the [GitLab documentation](https://docs.gitlab.com/ci/runners/hosted_runners/) for current details. +GitLab-hosted runner specifications are subject to change. See the [GitLab documentation](https://docs.gitlab.com/ci/runners/hosted_runners/) for further information. {{% /notice %}} ## GitLab-hosted runners @@ -34,10 +36,13 @@ GitLab-hosted runner specifications are subject to change. See the [GitLab docum Each job runs in a newly provisioned virtual machine dedicated to that job. The VM is deleted immediately after job completion. -- Untagged jobs default to the small Linux x86-64 runner +GitLab-hosted runners provide the following execution environment: + +- Jobs run with sudo access (no password required) - Jobs time out after three hours -- The VM has sudo access without password -- Storage is shared between OS, container image, and repository clone +- Storage is shared between the operating system, container images, and your repository clone +- Untagged jobs default to the small Linux x86-64 runner (specify `saas-linux-small-arm64` or another Arm64 tag to use Arm runners) + ### Network isolation @@ -60,7 +65,7 @@ For complete specifications, see [GitLab-hosted runners](https://docs.gitlab.com Each job executes in complete isolation: -1. GitLab provisions a new VM for your job -2. The job executes in this dedicated environment -3. GitLab sends deletion command to Google Compute API immediately after completion -4. The [Google Compute Engine hypervisor](https://cloud.google.com/blog/products/gcp/7-ways-we-harden-our-kvm-hypervisor-at-google-cloud-security-in-plaintext) securely deletes the VM and data +- GitLab provisions a new VM for your job +- The job executes in this dedicated environment +- GitLab sends deletion command to Google Compute API immediately after completion +- The [Google Compute Engine hypervisor](https://cloud.google.com/blog/products/gcp/7-ways-we-harden-our-kvm-hypervisor-at-google-cloud-security-in-plaintext) securely deletes the VM and data diff --git a/content/learning-paths/cross-platform/gitlab-managed-runners/pipeline.md b/content/learning-paths/cross-platform/gitlab-managed-runners/pipeline.md index c59807a7a3..70f83e51fd 100644 --- a/content/learning-paths/cross-platform/gitlab-managed-runners/pipeline.md +++ b/content/learning-paths/cross-platform/gitlab-managed-runners/pipeline.md @@ -1,10 +1,13 @@ --- -title: Configure CI/CD pipeline for Arm64 +title: Build and configure your Arm64 CI/CD pipeline weight: 4 ### FIXED, DO NOT MODIFY layout: learningpathall --- +## Overview + +This section guides you through building an Arm64 container image and creating a pipeline configuration for GitLab-hosted runners. GitLab-hosted runners are available for any project without additional setup. To use Arm64 runners, create a `.gitlab-ci.yml` file in your project root and specify the Arm64 runner tag. @@ -63,15 +66,15 @@ Create these three files before adding the pipeline configuration. Once you comm From your project page, select **Set up CI/CD** or use the **+** button to create a new file: -![CI-CD-New #center](_images/ci-cd-new.png) +![GitLab project page with CI/CD setup option highlighted, showing the Set up CI/CD button in the center of the interface alt-txt#center](_images/ci-cd-new.png "GitLab Set up CI/CD button") Name the file `.gitlab-ci.yml`: -![New-YML #center](_images/new-yml.png) +![GitLab new YAML file creation screen for pipeline configuration alt-txt#center](_images/new-yml.png "GitLab new YAML file creation screen") Select **Edit** > **Edit in pipeline editor**: -![Editor-YML #center](_images/editor-yml.png) +![GitLab pipeline editor screen for editing .gitlab-ci.yml alt-txt#center](_images/editor-yml.webp "GitLab pipeline editor screen") Add the following pipeline configuration. This defines three stages that build, test, and publish your Arm64 container image: ```yaml @@ -136,4 +139,13 @@ The `push_latest` job runs only on the default branch (typically `main`). It tag **Authentication:** GitLab automatically provides `$CI_REGISTRY_PASSWORD` and `$CI_REGISTRY_USER` variables for authenticating to the container registry. -Commit the configuration. GitLab validates the syntax and starts the pipeline automatically. +Commit the configuration. GitLab validates the syntax and starts the pipeline automatically. + +## What you've accomplished and what's next + +In this section, you: +- Built a simple C application for Arm64 +- Created a Dockerfile and containerized your application +- Configured a GitLab pipeline to build and push Arm64 images + +Next, you'll run your pipeline, verify the results, and test your container image on Arm64 infrastructure. Continue to the next section to validate your CI/CD workflow and ensure your application is ready for deployment on Arm platforms. diff --git a/content/learning-paths/cross-platform/gitlab-managed-runners/project.md b/content/learning-paths/cross-platform/gitlab-managed-runners/project.md index 1aec891e04..35009edc57 100644 --- a/content/learning-paths/cross-platform/gitlab-managed-runners/project.md +++ b/content/learning-paths/cross-platform/gitlab-managed-runners/project.md @@ -5,6 +5,10 @@ weight: 3 ### FIXED, DO NOT MODIFY layout: learningpathall --- +## Create your GitLab project for Arm CI/CD + +This section covers how to create a new GitLab project to use with Arm64 runners. + Before you begin, log in to your [GitLab account](https://gitlab.com/) or create a new one. @@ -18,18 +22,18 @@ If you're using an existing project, skip to the next section. Navigate to **Projects** in the left sidebar and select **New Project**: -![Gitlab-Projects #center](_images/gitlab-projects.png) +![GitLab left sidebar showing Projects menu with New Project option highlighted alt-txt#center](_images/gitlab-projects.png "GitLab Projects menu in left sidebar") Choose **Create blank project** or **Create from template** (select **GitLab CI/CD components** if using a template): -![New-Project #center](_images/new-project.png) +![GitLab new project creation screen showing options for blank project and templates alt-txt#center](_images/new-project.png "GitLab new project creation screen") Provide a project name (for example, `arm-runner-demo`) and select your preferred project URL. Select **Create Project**: -![Project-Info #center](_images/project-info.png) +![GitLab project information entry screen with fields for project name and URL alt-txt#center](_images/project-info.png "GitLab project information entry screen") Your new project is ready: -![Project-Done #center](_images/project-done.png) +![GitLab project creation success screen showing project dashboard alt-txt#center](_images/project-done.png "GitLab project creation success screen") With your project created, you can now add application files and configure the CI/CD pipeline to use Arm64 runners. diff --git a/content/learning-paths/cross-platform/gitlab-managed-runners/results.md b/content/learning-paths/cross-platform/gitlab-managed-runners/results.md index 7f38b7d18a..c59af1e170 100644 --- a/content/learning-paths/cross-platform/gitlab-managed-runners/results.md +++ b/content/learning-paths/cross-platform/gitlab-managed-runners/results.md @@ -5,6 +5,9 @@ weight: 5 ### FIXED, DO NOT MODIFY layout: learningpathall --- +## Validate and test your Arm64 CI/CD pipeline + +This section explains how to run, verify, and test your pipeline and container images on Arm64 infrastructure. ## Run the pipeline @@ -14,7 +17,7 @@ Navigate to **Build** > **Pipelines** and select **Run pipeline**: Select individual jobs to view their output and status: -![pipeline-execution #center](_images/pipeline-execution.png) +![GitLab pipeline execution screen showing job output and status alt-txt#center](_images/pipeline-execution.png "GitLab pipeline execution screen") ## Verify Arm64 architecture @@ -63,6 +66,8 @@ The pipeline editor provides helpful features: - **Visualize**: View your pipeline as a graph showing stage dependencies - **Validate**: Check pipeline syntax before committing changes +![GitLab visual pipeline editor showing pipeline graph and validation tools alt-txt#center](_images/visual-pipeline.webp "GitLab visual pipeline editor with graph and validation tools") + ## What you've accomplished and what's next You have: diff --git a/content/learning-paths/cross-platform/gitlab/_index.md b/content/learning-paths/cross-platform/gitlab/_index.md index 28b27a623a..2bd46fc2a1 100644 --- a/content/learning-paths/cross-platform/gitlab/_index.md +++ b/content/learning-paths/cross-platform/gitlab/_index.md @@ -21,7 +21,8 @@ author: Pranay Bakre ### Tags skilllevels: Advanced subjects: Containers and Virtualization -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/cross-platform/sme-executorch-profiling/02-setup-and-pipeline.md b/content/learning-paths/cross-platform/sme-executorch-profiling/02-setup-and-pipeline.md index e6a07a006e..90626629de 100644 --- a/content/learning-paths/cross-platform/sme-executorch-profiling/02-setup-and-pipeline.md +++ b/content/learning-paths/cross-platform/sme-executorch-profiling/02-setup-and-pipeline.md @@ -193,13 +193,13 @@ Each experiment is defined in a JSON configuration file. These configs specify: * Logging level: Timing-only mode vs full ETDump trace mode (trace mode impacts timing, use for kernel-level insights) * Analysis comparisons: Which experiment pairs to compare (for example, SME2-on vs SME2-off) -This approach enables repeatable, systematic performance analysis across multiple configurations without modifying pipeline code. +This approach enables repeatable, systematic performance analysis across multiple configurations without modifying pipeline code. Example templates can be found in the `model_profiling/config` directory after the setup workspace has completed. ### Pipeline scripts The following scripts execute the pipeline: - [`model_profiling/scripts/android_pipeline.py`](https://github.com/ArmDeveloperEcosystem/sme-executorch-profiling/blob/main/model_profiling/scripts/android_pipeline.py) - Android performance analysis pipeline -- [`model_profiling/scripts/mac_pipeline.py`](https://github.com/ArmDeveloperEcosystem/sme-executorch-profiling/blob/main/model_profiling/scripts/mac_pipeline.py) - macOS performance analysis pipeline +- [`model_profiling/scripts/mac_pipeline.py`](https://github.com/ArmDeveloperEcosystem/sme-executorch-profiling/blob/main/model_profiling/scripts/mac_pipeline.py) - macOS performance analysis pipeline These scripts read the experiment configuration, run all defined experiments, and collect ETDump traces and logs. Analysis is performed automatically after execution using [`model_profiling/scripts/analyze_results.py`](https://github.com/ArmDeveloperEcosystem/sme-executorch-profiling/blob/main/model_profiling/scripts/analyze_results.py) diff --git a/content/learning-paths/cross-platform/tinkerblox_ultraedge/_index.md b/content/learning-paths/cross-platform/tinkerblox_ultraedge/_index.md new file mode 100644 index 0000000000..b355bd3638 --- /dev/null +++ b/content/learning-paths/cross-platform/tinkerblox_ultraedge/_index.md @@ -0,0 +1,55 @@ +--- +title: Deploy UltraEdge HPC-I for AI and mixed workloads on Arm +minutes_to_complete: 60 + +who_is_this_for: This is an advanced topic for business, R&D, and engineering teams seeking to optimize CPU and GPU infrastructure utilization while reducing total cost of ownership on edge and constrained environments. It's ideal for innovation and development teams building next-generation AI workloads using alternative runtime environments and packaging technologies. + +learning_objectives: + - Understand the layered architecture of UltraEdge core, boost, and prime + - Build applications using the UltraEdge MicroStack + - Deploy the MicroPacs on Linux-based compute systems and scale to cloud or data-center environments + - Optimize performance for edge-cloud scenarios, enabling near real-time data flows + + +prerequisites: + - Experience using Linux on embedded or SBC platforms + - Understanding of container runtimes (containerd) and CNI networking + - Basic knowledge of communication protocols (MQTT, HTTP, and others) + - Familiarity with edge-cloud architectures and data-flow orchestration + +author: Tinkerblox + +### Tags +skilllevels: Advanced +subjects: Containers and Virtualization +tools_software_languages: + - Tinkerblox + +cloud_service_providers: + - Google Cloud + +armips: + - Neoverse + +operatingsystems: + - Linux + - other + +shared_path: true +shared_between: + - servers-and-cloud-computing + - automotive + +further_reading: + - resource: + title: Tinkerblox + link: https://tinkerblox.io + type: website + + +### FIXED, DO NOT MODIFY +# ================================================================================ +weight: 1 # _index.md always has weight of 1 to order correctly +layout: "learningpathall" # All files under learning paths have this same wrapper +learning_path_main_page: "yes" # This should be surfaced when looking for related content. Only set for _index.md of learning path content. +--- diff --git a/content/learning-paths/automotive/tinkerblox_ultraedge/_next-steps.md b/content/learning-paths/cross-platform/tinkerblox_ultraedge/_next-steps.md similarity index 100% rename from content/learning-paths/automotive/tinkerblox_ultraedge/_next-steps.md rename to content/learning-paths/cross-platform/tinkerblox_ultraedge/_next-steps.md diff --git a/content/learning-paths/cross-platform/tinkerblox_ultraedge/background.md b/content/learning-paths/cross-platform/tinkerblox_ultraedge/background.md new file mode 100644 index 0000000000..184e98d27c --- /dev/null +++ b/content/learning-paths/cross-platform/tinkerblox_ultraedge/background.md @@ -0,0 +1,91 @@ +--- +title: Understand UltraEdge HPC-I architecture for edge AI and mixed workloads + +weight: 2 + +layout: "learningpathall" +--- + +## Introduction +UltraEdge is an edge-native, high-performance execution fabric designed to run AI and mixed workloads without the overhead of traditional container platforms. While technologies like Docker and Kubernetes were created for general-purpose cloud environments, they introduce latency, resource bloat, and non-deterministic behavior that are poorly suited for edge deployments. + +UltraEdge takes a fundamentally different approach. It replaces heavyweight container runtimes with a lean, deterministic execution stack purpose-built for performance-oriented compute. This enables millisecond-level startup times, predictable performance, and a dramatically smaller resource footprint - allowing workloads to start faster, run closer to the hardware, and make full use of available CPU and GPU resources. + +At the core of UltraEdge are two specialized execution systems: + +· MicroStack, optimized for enterprise and mixed workloads + +· NeuroStack, purpose-built for AI inference and accelerated compute + +Together, these systems deliver up to 30x faster startup times and 3.8x smaller package sizes compared to conventional container-based approaches. By removing unnecessary abstraction layers, UltraEdge ensures compute cycles are spent on execution - not on managing the runtime itself. + +This Learning Path introduces the architecture, principles, and components that make UltraEdge a high-performance execution fabric for modern edge infrastructure. + +## UltraEdge overview + +UltraEdge orchestrates an edge-native execution fabric for high-performance compute infrastructure. Key design principles and capabilities include: + +**Built-for-edge execution stack** + +A lightweight, adaptive platform for AI and mixed workloads optimized for low latency, high determinism, and minimal footprint. + +**Dual workload focus** + +Native support for both traditional enterprise workloads and next-generation AI workloads, without compromising performance. + +**Full-stack enablement** + +Delivered through MicroStack and NeuroStack execution systems, each optimized for its workload domain. + + + +## Understand UltraEdge architecture for edge AI and mixed workloads + +UltraEdge is an edge-native, high-performance execution fabric for AI and mixed workloads on Arm platforms. Unlike traditional container platforms such as Docker and Kubernetes, UltraEdge minimizes latency, resource overhead, and non-deterministic behavior, making it ideal for edge deployments where performance and efficiency are critical. + +## Explore UltraEdge execution fabric + +UltraEdge replaces heavyweight container runtimes with a lean, deterministic execution stack. This enables millisecond-level startup times, predictable performance, and a smaller resource footprint. You can start workloads faster, run closer to the hardware, and maximize CPU and GPU utilization. + +UltraEdge includes two specialized execution systems: +- **MicroStack**: Optimized for enterprise and mixed workloads +- **NeuroStack**: Purpose-built for AI inference and accelerated compute + +These systems deliver up to 30x faster startup times and 3.8x smaller package sizes compared to conventional container-based approaches. By removing unnecessary abstraction layers, UltraEdge ensures compute cycles are spent on execution, not on managing the runtime. + +## Review UltraEdge features and design principles + +UltraEdge orchestrates edge-native execution for high-performance compute infrastructure. Its design principles include: + +- built-for-edge execution stack: lightweight, adaptive platform for AI and mixed workloads, optimized for low latency and high determinism +- dual workload focus: native support for both enterprise and next-generation AI workloads +- full-stack enablement: delivered through MicroStack and NeuroStack, each optimized for its domain +- high efficiency: maximizes CPU and GPU utilization, reduces operational overhead +- ecosystem alignment: developed with technology partners and aligned with Edge AI Foundation deployment approaches +- cluster-aware orchestration: integrates with Kubernetes and Slurm for managed cluster orchestration +- built-in observability: provides diagnostics, telemetry, and control-plane visibility +- lower total cost of ownership (TCO): reduces CPU/GPU cluster costs through faster startup, higher utilization, and less runtime overhead + + +## UltraEdge architecture layers + +UltraEdge is composed of layered systems, each responsible for a distinct aspect of execution and orchestration: + +![UltraEdge high-level architecture diagram showing layered execution systems for edge AI and mixed workloads alt-txt#center](https://raw.githubusercontent.com/Tinkerbloxsupport/arm-learning-path-support/main/static/images/High-level%20architecture%20diagram.png "UltraEdge high-level architecture") + +UltraEdge organizes functionality into five specialized layers. Each layer is responsible for a specific aspect of workload execution and orchestration: + +- **Core layer**: manages compute infrastructure, service orchestration, rule engines, and data flow across workloads. +- **Boost layer**: accelerates workloads with optimized routines, FFI (Foreign Function Interface) integrations, and dynamic connectors. +- **Prime layer**: coordinates workload intelligence, business logic, triggers, and AI/mixed workload orchestration. +- **Dock layer**: orchestrates workloads and clusters using Kubernetes-based stacks and Slurm-based scheduling. +- **Edge-cloud connect layer**: enables data streaming to databases (such as InfluxDB, SQLite), diagnostics, logging, and telemetry outputs. + +## What you've accomplished and what's next + +In this section, you: +- Learned the motivation and architecture behind UltraEdge +- Reviewed the layered execution systems and their roles in edge AI and mixed workloads + +Next, you'll move on to hands-on installation and configuration of UltraEdge on your target Arm platform. + diff --git a/content/learning-paths/automotive/tinkerblox_ultraedge/debian_installation.md b/content/learning-paths/cross-platform/tinkerblox_ultraedge/debian_installation.md similarity index 80% rename from content/learning-paths/automotive/tinkerblox_ultraedge/debian_installation.md rename to content/learning-paths/cross-platform/tinkerblox_ultraedge/debian_installation.md index aea48c2ef1..d8c23a75c7 100644 --- a/content/learning-paths/automotive/tinkerblox_ultraedge/debian_installation.md +++ b/content/learning-paths/cross-platform/tinkerblox_ultraedge/debian_installation.md @@ -1,20 +1,20 @@ --- -title: Debian/Ubuntu installation - UltraEdge +title: Install UltraEdge on Debian and Ubuntu for Edge AI workloads weight: 5 layout: "learningpathall" --- -### Installation process for UltraEdge on Ubuntu/Debian +## Install UltraEdge on Ubuntu/Debian Follow these steps to initialize and register your device within the **Uncloud** ecosystem: -1. **Access the Platform:** +* **Access the Platform:** - Navigate to the [Uncloud Dashboard](https://dev.tinkerblox.io/) and log in with your credentials. + Navigate to the [Uncloud Dashboard](https://dev.tinkerblox.io/) and log in with your credentials. -2. **Provision a New Device:** +* **Provision a New Device:** * Go to **Device Management** > **New Device**. ![Device Management](https://raw.githubusercontent.com/Tinkerbloxsupport/arm-learning-path-support/main/static/images/Device_managment.png) @@ -25,19 +25,19 @@ Follow these steps to initialize and register your device within the **Uncloud** ![Initialize Device](https://raw.githubusercontent.com/Tinkerbloxsupport/arm-learning-path-support/main/static/images/Initialize%20.png) -3. **Install prerequisites:** +* **Install prerequisites:** Install the required prerequisites: ```bash -sudo apt update +sudo apt update sudo apt install -y curl jq ``` -4. **Retrieve installation command details:** +* **Retrieve installation command details:** - * Copy the generated device installation command or details from the **Uncloud** portal to your clipboard. + Copy the generated device installation command or details from the **Uncloud** portal to your clipboard. ![Installation Command](https://raw.githubusercontent.com/Tinkerbloxsupport/arm-learning-path-support/main/static/images/Initialize%20_command.png) @@ -49,7 +49,7 @@ sudo DEVICE_ID="5b3ff290-0c88-4cd9-8ef7-08de0bded9df" KEY="TB.ApiKey-mlBZgDFc7qy Run your specific installer command in your Ubuntu/Debian SSH shell and initialize the agent to install UltraEdge. -### Activation of the UltraEdge agent +## Activate the UltraEdge agent On the first boot, the agent will automatically generate a file named `activation_key.json` at the path: @@ -74,7 +74,7 @@ receive license key (which includes license metadata). sudo systemctl start tbx-agent.service ``` -### Manual running +### Run the UltraEdge agent manually - Binary path: `/bin/tbx-agent` @@ -87,7 +87,7 @@ receive license key (which includes license metadata). - To stop, press Ctrl + C once. -## MicroPac installation +## Install MicroPac MicroPac is the core tooling used to build and manage **MicroStack** (general microservices) and **NeuroStack** (AI-native services). @@ -97,21 +97,21 @@ MicroPac is the core tooling used to build and manage **MicroStack** (general mi * Validation: The ecosystem includes a **MicroPac Validator**, which verifies the integrity and security of the package created by the builder to ensure it is ready for edge deployment. -#### System requirements +### System requirements - Linux host (aarch64) - Sudo permissions - Overlay filesystem support - Internet connection -#### Required packages +### Required packages ```bash sudo apt-get update sudo apt-get install -y tar curl qemu-user-static binfmt-support ``` -### Cross-architecture support +## Cross-architecture support The **MicroPacFile** is the central declarative configuration used by the builder to define the environment and behavior of your service. This configuration is essential for orchestrating both **MicroStack** (general microservices) and **NeuroStack** (AI/ML) services. @@ -127,7 +127,7 @@ To build MicroPac for different architectures: sudo update-binfmts --enable qemu-armv7 ``` -### Installation +## Install the MicroPac package - The package is provided as a `.deb` file. @@ -137,9 +137,9 @@ To build MicroPac for different architectures: sudo apt install ./.deb ``` -### MicroPac file schema file creation/setup +## Create and set up the MicroPac file schema -#### File placement +### File placement For the MicroPac Builder to function correctly, the **MicroPacFile** must be placed in the root directory alongside your source code and dependency files. @@ -196,9 +196,9 @@ Place a `MicroPacFile` in your project directory as mentioned in above example. mode: host name: nginx-net ``` -### Configuration fields +## Configuration fields -#### Required fields +### Required fields - **name**: Application name (≤ 10 characters) - **version**: Application version @@ -208,7 +208,7 @@ Place a `MicroPacFile` in your project directory as mentioned in above example. - **entry**: Entry point command - **mode**: single-run -#### Optional fields +### Optional fields - **env**: Environment variable - **buildSteps**: Array of build instructions @@ -218,7 +218,7 @@ Place a `MicroPacFile` in your project directory as mentioned in above example. - **createdBy**: maintainer of the application - **description**: description of the application -### Build the MicroPac +## Build the MicroPac Navigate to your project directory and execute: @@ -228,13 +228,22 @@ Navigate to your project directory and execute: This generates a file named `.mpac`. -### Verify the Micropac setup +## Verify the MicroPac setup To confirm that the Micropac has been generated properly, follow these steps: -1. **Locate the Package:** Find the generated file with the `.mpac` extension. -2. **Extract the Contents:** Extract the `.mpac` file using a standard extraction tool (or rename it to `.zip`/`.tar.gz` if necessary to open it). -3. **Verify Contents:** The extracted folder must contain exactly three files: - * **`manifest.yaml`**: Contains the metadata and configuration for the package. - * **RootFS tarball**: The base file system layer (in `.tar` format). - * **Application layer tarball**: The specific application logic/binaries (in `.tar` format). +* Locate the package: find the generated file with the `.mpac` extension. +* Extract the contents: extract the `.mpac` file using a standard extraction tool (or rename it to `.zip`/`.tar.gz` if necessary to open it. +* Verify the contents: the extracted folder must contain exactly three files: + * `manifest.yaml`: contains the metadata and configuration for the package. + * RootFS tarball: the base file system layer (in `.tar` format). + * Application layer tarball: the specific application logic/binaries (in `.tar` format). + +## What you've accomplished and what's next + +In this section, you: +- Installed UltraEdge on Ubuntu/Debian +- Activated and managed the UltraEdge agent +- Built and installed MicroPac workloads for edge deployment + +Next, you can explore advanced MicroPac features, integrate with additional edge devices, or move on to Yocto-based installations for broader hardware support. diff --git a/content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-download-complete.png b/content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-download-complete.png similarity index 100% rename from content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-download-complete.png rename to content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-download-complete.png diff --git a/content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-download-file.png b/content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-download-file.png similarity index 100% rename from content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-download-file.png rename to content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-download-file.png diff --git a/content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-network.png b/content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-network.png similarity index 100% rename from content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-network.png rename to content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-network.png diff --git a/content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-shell.png b/content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-shell.png similarity index 100% rename from content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-shell.png rename to content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-shell.png diff --git a/content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-ssh.png b/content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-ssh.png similarity index 100% rename from content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-ssh.png rename to content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-ssh.png diff --git a/content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-ubuntu.png b/content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-ubuntu.png similarity index 100% rename from content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-ubuntu.png rename to content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-ubuntu.png diff --git a/content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-upload-complete.png b/content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-upload-complete.png similarity index 100% rename from content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-upload-complete.png rename to content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-upload-complete.png diff --git a/content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-upload-files.png b/content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-upload-files.png similarity index 100% rename from content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-upload-files.png rename to content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-upload-files.png diff --git a/content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-upload.png b/content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-upload.png similarity index 100% rename from content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-upload.png rename to content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-upload.png diff --git a/content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-vm.png b/content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-vm.png similarity index 100% rename from content/learning-paths/automotive/tinkerblox_ultraedge/images/gcp-vm.png rename to content/learning-paths/cross-platform/tinkerblox_ultraedge/images/gcp-vm.png diff --git a/content/learning-paths/automotive/tinkerblox_ultraedge/instance.md b/content/learning-paths/cross-platform/tinkerblox_ultraedge/instance.md similarity index 85% rename from content/learning-paths/automotive/tinkerblox_ultraedge/instance.md rename to content/learning-paths/cross-platform/tinkerblox_ultraedge/instance.md index f0ca563960..f2b08189d8 100644 --- a/content/learning-paths/automotive/tinkerblox_ultraedge/instance.md +++ b/content/learning-paths/cross-platform/tinkerblox_ultraedge/instance.md @@ -1,5 +1,5 @@ --- -title: Create a Google Axion C4A virtual machine on Google Cloud to build a Yocto image +title: Provision a Google Axion C4A VM for Yocto image builds on Arm weight: 3 ### FIXED, DO NOT MODIFY @@ -14,7 +14,7 @@ In this section, you provision a Google Axion C4A virtual machine on Google Clou For general guidance on setting up a Google Cloud account and project, see the Learning Path [Getting started with Google Cloud Platform](/learning-paths/servers-and-cloud-computing/csp/google/). {{% /notice %}} -## Provision a Google Axion C4A VM in the Google Cloud Console +## Provision a Google Axion C4A VM in Google Cloud Console To create a virtual machine using the C4A instance type: @@ -51,4 +51,10 @@ A new browser window opens with a terminal connected to your virtual machine. This is a rather expensive VM given its vCPU and memory usage. It is highly recommended to delete this VM once you have completed this learning path! {{% /notice %}} -Next, build the Yocto image on this VM instance. \ No newline at end of file +## What you've accomplished and what's next + +In this section, you: +- Provisioned a Google Axion C4A VM on Google Cloud Platform +- Configured the VM for Arm64-based Yocto image builds + +Next, you'll use this VM to build a Yocto image for your target hardware. Continue to the Yocto installation section to complete your edge deployment workflow. \ No newline at end of file diff --git a/content/learning-paths/cross-platform/tinkerblox_ultraedge/running.md b/content/learning-paths/cross-platform/tinkerblox_ultraedge/running.md new file mode 100644 index 0000000000..0ecd699c71 --- /dev/null +++ b/content/learning-paths/cross-platform/tinkerblox_ultraedge/running.md @@ -0,0 +1,145 @@ +--- +title: Run and manage UltraEdge HPC-I for AI and mixed workloads on Arm + +weight: 6 + +layout: "learningpathall" +--- + +## Get started with the Tinkerblox CLI + +In this section, you'll use the Tinkerblox CLI to deploy, manage, and monitor microservices on the UltraEdge platform. You'll practise inspecting system state, installing a sample microservice, and observing its runtime behavior. + +To get started, download a sample MPAC file from the [Tinkerblox support repository](https://github.com/Tinkerbloxsupport/arm-learning-path-support/blob/main/static/Sample_ms/dte_nn.mpac) and install it on your device. + +## Use the Tinkerblox CLI + +The Tinkerblox Command Line Interface (CLI) lets you manage the Edge Agent and microservices on UltraEdge devices. + +**Basic usage:** + +```bash +tinkerblox-cli [OPTIONS] +``` + +**Common commands:** + +- `status`: Show connection status with the Edge Agent +- `microboost`: Microservice management commands +- `help`: Print this message or the help for a given subcommand + +**Options:** + +- `-h`, `--help`: Print help +- `-V`, `--version`: Print version + +## Check CLI connection status + +To verify that the CLI is connected to the Edge Agent, run: + +```bash +sudo tinkerblox-cli status +``` + +The output shows whether the CLI is connected to the Edge Agent. + +## Manage microservices + +You can install, list, start, stop, and uninstall microservices using the `microboost` command. Replace `/path/to/your.mpac` with the path to your MPAC file and `` with the microservice ID. + +**Install a microservice:** +```bash +sudo tinkerblox-cli microboost install -f /path/to/your.mpac +``` + +**List installed microservices:** +```bash +sudo tinkerblox-cli microboost list +``` + +**Show microservice status:** +```bash +sudo tinkerblox-cli microboost status +``` + +**Stop a microservice:** +```bash +sudo tinkerblox-cli microboost stop +``` + +**Start a microservice:** +```bash +sudo tinkerblox-cli microboost start +``` + +**Uninstall a microservice:** +```bash +sudo tinkerblox-cli microboost uninstall +``` + +## Run diagnostics + +Use the `diagnostics` command to check system health and connectivity on your UltraEdge device. + +**Syntax:** +```bash +sudo tinkerblox-cli diagnostics +``` + +**Available diagnostics:** + +- **full**: Run complete system diagnostics and summarize results + ```bash + sudo tinkerblox-cli diagnostics full + ``` +- **system**: Check CPU, memory, and OS-level health + ```bash + sudo tinkerblox-cli diagnostics system + ``` +- **network**: Verify network connectivity and endpoint reachability + ```bash + sudo tinkerblox-cli diagnostics network + ``` +- **filesystem**: Validate database and filesystem connectivity and integrity + ```bash + sudo tinkerblox-cli diagnostics filesystem + ``` +- **engine**: Check engine, microboost, and neuroboost + ```bash + sudo tinkerblox-cli diagnostics engine + ``` + +## Troubleshoot common issues + +If you encounter errors while running CLI commands or deploying microservices, use the following guidance to resolve them: + +**Permission denied** +- Ensure you have `sudo` privileges. +- Check directory ownership and permissions. +- Verify overlay filesystem support is enabled. + +**Directory creation failed** +- Check available disk space. +- Verify parent directory permissions. +- Ensure the path is valid. + +**Cross-architecture build issues** +Cross-architecture issues usually occur when binaries are built for a different CPU architecture than your host system. These are not related to Yocto build issues. +- Verify QEMU installation: + ```bash + qemu-aarch64-static --version + ``` +- Check binfmt registration: + ```bash + ls /proc/sys/fs/binfmt_misc/ + ``` +- Ensure the target architecture is enabled. +- If issues persist, try changing the host architecture. + +## What you've accomplished and what's next + +In this section, you: +- Used the Tinkerblox CLI to manage microservices and system diagnostics +- Practiced installing, starting, stopping, and monitoring microservices on UltraEdge + +Next, explore more advanced CLI features, automate deployments, or integrate with additional monitoring and orchestration tools for your edge environment. \ No newline at end of file diff --git a/content/learning-paths/automotive/tinkerblox_ultraedge/yocto_installation.md b/content/learning-paths/cross-platform/tinkerblox_ultraedge/yocto_installation.md similarity index 67% rename from content/learning-paths/automotive/tinkerblox_ultraedge/yocto_installation.md rename to content/learning-paths/cross-platform/tinkerblox_ultraedge/yocto_installation.md index c092a49c70..fa3c6b5cf6 100644 --- a/content/learning-paths/automotive/tinkerblox_ultraedge/yocto_installation.md +++ b/content/learning-paths/cross-platform/tinkerblox_ultraedge/yocto_installation.md @@ -1,5 +1,5 @@ --- -title: Yocto image build and install/configure for NXP S32G-VNP-GLDBOX3 - UltraEdge +title: Build and install Yocto images for NXP S32G-VNP-GLDBOX3 with UltraEdge weight: 4 @@ -9,7 +9,7 @@ layout: "learningpathall" ## System requirements {{% notice Note %}} -The requirements below are given as additional information only. The GCP C4A VM instance, running Ubuntu 22.04 with 100GB disk space, will work fine for this learning path. +The requirements below are given as additional information only. The GCP C4A VM instance, running Ubuntu 22.04 with 100GB disk space, will work fine for this Learning Path. {{% /notice %}} - Linux host system (64-bit recommended) @@ -22,7 +22,7 @@ The requirements below are given as additional information only. The GCP C4A VM - Ubuntu 22.04 LTS (AArch64) {{% notice Note %}} -As of this learning path's publication, Ubuntu 24.04 LTS is NOT a supported Yocto build host OS. This may change in the future. +As of this Learning Path's publication, Ubuntu 24.04 LTS is NOT a supported Yocto build host OS. This may change in the future. {{% /notice %}} - Minimum hardware requirements: @@ -42,29 +42,28 @@ As of this learning path's publication, Ubuntu 24.04 LTS is NOT a supported Yoct Yocto builds are **very** resource-intensive and may take several hours depending on hardware and memory capacities {{% /notice %}} -## Yocto build instructions for NXP S32G-VNP-GLDBOX3 -This section uses the **NXP S32G-VNP-GLDBOX3** hardware platform with the **BSP 38.0** release from NXP's `auto_yocto_bsp` repository to run EdgeBlox Agent. The following steps demonstrate how to build a Yocto-based Linux image for this board and prepare it for EdgeBlox deployment. +## Build a Yocto image for your NXP board -- **NXP Auto Linux BSP Repository (BSP 38.0):** - https://github.com/nxp-auto-linux/auto_yocto_bsp/tree/release/bsp38.0 +You'll use the **NXP S32G-VNP-GLDBOX3** hardware platform with the **BSP 38.0** release from NXP's `auto_yocto_bsp` repository to run EdgeBlox Agent. Follow these steps to build a Yocto-based Linux image and prepare it for deployment. -- **NXP GoldBox 3 Design Page:** +- **NXP Auto Linux BSP Repository (BSP 38.0):** + https://github.com/nxp-auto-linux/auto_yocto_bsp/tree/release/bsp38.0 +- **NXP GoldBox 3 Design Page:** https://www.nxp.com/design/design-center/development-boards-and-designs/GOLDBOX-3 -#### Acquire the replacement "meta-edgeblox" layer from Tinkerblox +### Get the replacement meta-edgeblox layer -Please reach out to the Tinkerblox support team to request access to the meta-edgeblox zip file that contains the replacement layer for your Yocto image: **techsupport@tinkerblox.io** +Contact the Tinkerblox support team at **techsupport@tinkerblox.io** to request the meta-edgeblox zip file for your Yocto image. The file you receive will be called "meta-edgeblox.zip" and will be used in the next steps and in the build script below. -For this example, the file received will be called "meta-edgeblox.zip" and will be used in the next section and in the build script below. -### Build the Yocto image for NXP S32G-VNP-GLDBOX3 +## Build the Yocto image {{% notice Note %}} -In default installs of Ubuntu for your YOCTO build environment, you will get an error from the above command stating that the `/etc/sudoers` file needs to be updated. Please follow those instructions as the script needs the additional permissions to fully setup properly. Otherwise, the subsequent `bitbake` commands below will fail. +If you see an error about updating the `/etc/sudoers` file, follow the instructions provided. The script needs these permissions to set up properly. If you skip this, the `bitbake` commands below will fail. {{% /notice %}} -First, copy this entire config file and save it as "kernel.cfg": +First, copy the following config file and save it as "kernel.cfg": ```bash CONFIG_NAMESPACES=y @@ -95,7 +94,7 @@ CONFIG_IP6_NF_IPTABLES=y CONFIG_IP6_NF_FILTER=y ``` -Next copy this entire build script and save it as "build.sh": +Next, copy the following build script and save it as "build.sh": ```bash #!/bin/bash @@ -193,7 +192,8 @@ fi exit 0 ``` -Next, using the VM SSH window, select "upload" to upload "kernel.cfg", "meta-edgeblox.zip" and "build.sh" to the VM instance: + +In your VM SSH window, select "upload" to upload "kernel.cfg", "meta-edgeblox.zip", and "build.sh" to the VM instance. Invoking SSH file upload: ![Invoking file upload from the SSH shell#center](images/gcp-upload.png "Invoking file upload from the SSH shell") @@ -204,7 +204,8 @@ Selecting files to upload through SSH: Upload completed: ![Upload completed#center](images/gcp-upload-complete.png "Upload completed") -Next, within your VM SSH window, type these commands to invoke the build: + +In your VM SSH window, run the following commands to start the build: ```bash chmod 755 ./build.sh @@ -214,25 +215,22 @@ cd ./tinkerblox ./build.sh ``` -{{% notice Building Notes %}} -1). The build will take around 20-40 minutes to fully complete. - -2). During the build, you will be prompted a few times to "restart" some services on the VM. Just press the "tab" key to select "OK" and then "enter" to continue. -3). Also during the build, you will be prompted to accept the NXP BSP license. Please type "q" followed by "y" to accept and begin the build. +{{% notice Building notes %}} +- The build takes about 20-40 minutes to complete. +- During the build, you might be prompted to restart some services. Press the "tab" key to select "OK" and then "enter" to continue. +- You will be prompted to accept the NXP BSP license. Type "q" followed by "y" to accept and begin the build. {{% /notice %}} -The build will take around 20-40 minutes to fully complete. -### Download the built Yocto image for NXP S32G-VNP-GLDBOX3 +## Download the built Yocto image -Once completed, the built image is archived and then downloaded using the SSH "download" option: +After the build completes, archive the image and download it to your local machine. Make sure your local machine has access to the **NXP S32G-VNP-GLDBOX3** and its SD card for the next steps. -The archived image should be downloaded to a local machine with access to the **NXP S32G-VNP-GLDBOX3** and its SD card for the next steps. -### Flash the SD card +## Flash the SD card -#### Download the build Yocto image from the VM instance +### Download the built Yocto image from the VM instance In the VM SSH shell, perform the following commands: ```bash @@ -259,41 +257,42 @@ cd s32g399ardb3 ls -al fsl-image-base-s32g399ardb3.sdcard ``` -We are now ready to flash the image to the SD card. Insert the SD card (your localhost may expose the SD card as /dev/sdb for example if linux/ubuntu based). +Insert the SD card. Your system may expose it as /dev/sdb (Linux/Ubuntu example). {{% notice Note %}} -Replace "/dev/sdb" with your specific local host's device file for the SD card connected to your local device: +Replace "/dev/sdb" with your system's device file for the SD card. {{% /notice %}} +Write the image to the SD card: + ```bash ls -al fsl-image-base-s32g399ardb3.sdcard sudo dd if=fsl-image-base-s32g399ardb3.sdcard of=/dev/sdb bs=1M && sync ``` -## Activate the agent on the NXP S32G-VNP-GLDBOX3 -On the first boot, the agent will automatically generate a file named -`activation_key.json` at the path: +## Activate the agent on your NXP device + +On first boot, the agent automatically generates a file named `activation_key.json` at: - /opt/tinkerblox/activation_key.json + /opt/tinkerblox/activation_key.json -Log into your **NXP S32G-VNP-GLDBOX3** device using SSH after determining its IP address (for example, 1.2.3.4 - replace with the IP address of your NXP device): +Log in to your **NXP S32G-VNP-GLDBOX3** device using SSH. Replace `1.2.3.4` with your device's IP address: ```bash ssh root@1.2.3.4 ``` -Within the SSH login shell: +In the SSH shell, check for the activation key: ```bash cd /opt/tinkerblox/ ls -al activation_key.json ``` -Share this `activation_key.json` file with the TinkerBlox team at **techsupport@tinkerblox.io** to -receive license key (which includes license metadata) that will enable device activation. You will receive a new `activation_key.json` that you'll use in the following steps. +Send this `activation_key.json` file to the Tinkerblox team at **techsupport@tinkerblox.io** to receive your license key. You will get a new `activation_key.json` to use in the next steps. -Back on the NXP device in the SSH shell, once your device activation json file is received from TinkerBlox support: +Once you receive the licensed file: 1. Stop the agent using the following command: @@ -311,33 +310,31 @@ For example, using "1.2.3.4" as the NXP device's IP address, on your local machi sudo systemctl start tbx-agent.service -#### Manual running - -- Binary path: `/bin/tbx-agent` - -- To start: - - cd /bin - ./tbx-agent +### Run the agent manually -- To stop, press Ctrl + - C once. +- Binary path: `/bin/tbx-agent` +- To start: + ```bash + cd /bin + ./tbx-agent + ``` +- To stop, press **Ctrl+C** once. + ## Install and run workloads -This section demonstrates how to deploy and manage a MicroPac-based -workload on an UltraEdge-enabled device. +You can deploy and manage MicroPac-based workloads on your UltraEdge-enabled device using the MicroBoost CLI. Use the following steps to install, start, stop, and monitor workloads. This workflow uses the MicroBoost CLI to install, start, stop, and monitor MicroPac-based workloads running on UltraEdge. ### Build the workload using mpac builder -This section demonstrates how to build the .mpac file from a cross-architecture setup using **Micropac Builder**. +To build the .mpac file from a cross-architecture setup using **Micropac Builder**: - Verify QEMU installation: @@ -359,56 +356,75 @@ After the build completes, the workload file your_service.mpac will be generated Copy the your_service.mpac file to any root filesystem path of your NXP target to deploy it. -### Install the workloads in the device using below command +systemctl start runit-supervise +tinkerblox-cli microboost install -f /path/to/your_service.mpac +tinkerblox-cli microboost list +tinkerblox-cli microboost start +tinkerblox-cli microboost stop +tinkerblox-cli microboost status +tinkerblox-cli microboost uninstall + +### Install the workloads on the device -``` +Start the runit supervisor: +```bash systemctl start runit-supervise ``` -``` +Install the workload: +```bash tinkerblox-cli microboost install -f /path/to/your_service.mpac ``` -Now use the microboost List command to find the id of the service. - -``` +List installed services: +```bash tinkerblox-cli microboost list ``` -Copy the id and use the commands below to start, stop, and check the status of the service. +Copy the service ID and use the following commands to manage the service: -``` +Start the service: +```bash tinkerblox-cli microboost start ``` -``` +Stop the service: +```bash tinkerblox-cli microboost stop ``` -``` +Check the service status: +```bash tinkerblox-cli microboost status ``` -To uninstall the workload with the specified ID: - -``` +Uninstall the workload: +```bash tinkerblox-cli microboost uninstall ``` -## Additional information for reference -Below are two additional videos as additional reference information. +## Watch video walkthroughs -Microservice Setup/Install: +Watch these videos for additional guidance: +**Microservice setup and install:** -Yocto Setup/Build/Install: - +**Yocto setup, build, and install:** \ No newline at end of file + + +## What you've accomplished and what's next + +In this section, you: +- Built a Yocto image for the NXP S32G-VNP-GLDBOX3 platform +- Activated and managed the UltraEdge agent on your target device +- Built, installed, and managed MicroPac workloads using the mpac builder and CLI + +Next, you can further customize your Yocto builds, automate deployment pipelines, or explore integration with other edge and cloud platforms. \ No newline at end of file diff --git a/content/learning-paths/cross-platform/woa_azure/_index.md b/content/learning-paths/cross-platform/woa_azure/_index.md index ffb7f3bc46..e0dc378d8e 100644 --- a/content/learning-paths/cross-platform/woa_azure/_index.md +++ b/content/learning-paths/cross-platform/woa_azure/_index.md @@ -18,7 +18,8 @@ author: Pareena Verma ### Tags skilllevels: Introductory subjects: Containers and Virtualization -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse diff --git a/content/learning-paths/embedded-and-microcontrollers/edge_impulse_greengrass/_index.md b/content/learning-paths/embedded-and-microcontrollers/edge_impulse_greengrass/_index.md index 78e20ee0af..37424a5e64 100644 --- a/content/learning-paths/embedded-and-microcontrollers/edge_impulse_greengrass/_index.md +++ b/content/learning-paths/embedded-and-microcontrollers/edge_impulse_greengrass/_index.md @@ -23,7 +23,8 @@ author: Doug Anson ### Tags skilllevels: Introductory -cloud_service_providers: AWS +cloud_service_providers: + - AWS subjects: ML armips: - Cortex-M diff --git a/content/learning-paths/mobile-graphics-and-gaming/model-training-gym/_index.md b/content/learning-paths/mobile-graphics-and-gaming/model-training-gym/_index.md index bef6e52f58..decc748a4c 100644 --- a/content/learning-paths/mobile-graphics-and-gaming/model-training-gym/_index.md +++ b/content/learning-paths/mobile-graphics-and-gaming/model-training-gym/_index.md @@ -48,7 +48,7 @@ further_reading: link: https://huggingface.co/Arm/neural-super-sampling type: website - resource: - title: Vulkan ML Sample Learning Path + title: Vulkan Samples Learning Path link: /learning-paths/mobile-graphics-and-gaming/vulkan-ml-sample/ type: learningpath diff --git a/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/_index.md b/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/_index.md index c07b067c4e..522e88ea8a 100644 --- a/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/_index.md +++ b/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/_index.md @@ -1,5 +1,5 @@ --- -title: Unleashing leading On-Device AI performance with llama.cpp, SME2 and KleidiAI +title: Profile SME2 with llama.cpp and KleidiAI on Android draft: true cascade: @@ -16,7 +16,9 @@ learning_objectives: prerequisites: - Knowledge of KleidiAI and SME2 - - An Linux or Android device with Arm SME2 support + - A Linux host machine (x86_64 or aarch64) for building llama.cpp with the Arm GNU Toolchain used in this Learning Path + - Git, CMake and Android Debug Bridge (ADB) installed on the host machine + - An Android device with Arm SME2 support for running and profiling the built executable author: Zenon Zhilong Xiu @@ -24,8 +26,8 @@ author: Zenon Zhilong Xiu skilllevels: Advanced subjects: ML armips: - - Arm C1 CPU - - Arm SME2 unit + - Arm C1 core + - SME2 tools_software_languages: - C++ - llama.cpp diff --git a/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/build_llama_cpp.md b/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/build_llama_cpp.md index cfae409b93..3762837042 100644 --- a/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/build_llama_cpp.md +++ b/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/build_llama_cpp.md @@ -6,25 +6,70 @@ weight: 4 layout: learningpathall --- -## Build llama.cpp with KleidiAI and SME2 enabled -For convenience, llama.cpp is statically linked. We use aarch64 GCC cross compile toolchain, *aarch64-none-linux-gnu-* to build the project. To support SME2, GCC compiler version 14.2 and onwards is required. The toolchain can be downloaded [here](https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads) . +In this section, you set up a GCC cross-compile toolchain and build a statically linked `llama-cli` binary with KleidiAI and SME2 enabled. -The llama.cpp with Tag b7611 is used in this tutorial, newer versions should also work but they are not tested. +For convenience, llama.cpp is statically linked. You use the aarch64 GCC cross compile toolchain, *aarch64-none-linux-gnu-*, to build the project. To support SME2, GCC compiler version 14.2 and onwards is required. -After downloading the llama.cpp source code [here](https://github.com/ggml-org/llama.cpp/releases/tag/b7610), create a new directory *build* under the llama.cpp root directory and change to the new directory, +The build uses the Linux-hosted Arm GNU Toolchain. If you are working on macOS or Windows, run these commands in a Linux environment (for example, a Linux VM, container, or a Linux development machine). + +## Install the toolchain + +Start by downloading and unpacking the Arm GNU Toolchain (GCC 14.2) for your host architecture: + +```bash +TOOLCHAIN_VER="14.2.rel1" +mkdir -p "$HOME/toolchains" && cd "$HOME/toolchains" + +HOST_ARCH="$(uname -m)" +if [ "$HOST_ARCH" = "x86_64" ]; then + TOOLCHAIN_TAR="arm-gnu-toolchain-${TOOLCHAIN_VER}-x86_64-aarch64-none-linux-gnu.tar.xz" +elif [ "$HOST_ARCH" = "aarch64" ]; then + TOOLCHAIN_TAR="arm-gnu-toolchain-${TOOLCHAIN_VER}-aarch64-aarch64-none-linux-gnu.tar.xz" +else + echo "Unsupported host architecture: $HOST_ARCH" >&2 + exit 1 +fi + +curl -L -O "https://developer.arm.com/-/media/Files/downloads/gnu/${TOOLCHAIN_VER}/binrel/${TOOLCHAIN_TAR}" +tar -xf "${TOOLCHAIN_TAR}" + +export PATH="$PWD/${TOOLCHAIN_TAR%.tar.xz}/bin:$PATH" +``` + +Verify the installation was successful by printing the toolchain version: + +```bash +aarch64-none-linux-gnu-gcc --version +``` + +## Clone the llama.cpp repository + +The llama.cpp with tag b7610 is used in this tutorial. Newer versions should also work, but they are not tested. + +Next, download the llama.cpp source code and check out the tag used in this tutorial: ```bash -cd ~/llama.cpp +cd $HOME +git clone --depth 1 --branch b7610 https://github.com/ggml-org/llama.cpp.git +``` + +Create a new directory *build* under the llama.cpp root directory and change to the new directory: + +```bash +cd $HOME/llama.cpp mkdir build && cd build ``` -Next, configure the project, + +## Compile the binary + +Next, configure the project using the following command: ```bash cmake .. \ -DCMAKE_SYSTEM_NAME=Linux \ -DCMAKE_SYSTEM_PROCESSOR=arm \ - -DCMAKE_C_COMPILER=aarch64-linux-gnu-gcc \ - -DCMAKE_CXX_COMPILER=aarch64-linux-gnu-g++ \ + -DCMAKE_C_COMPILER=aarch64-none-linux-gnu-gcc \ + -DCMAKE_CXX_COMPILER=aarch64-none-linux-gnu-g++ \ -DLLAMA_NATIVE=OFF \ -DLLAMA_F16C=OFF \ -DLLAMA_GEMM_ARM=ON \ @@ -38,20 +83,24 @@ cmake .. \ -DLLAMA_CURL=OFF \ -DGGML_CPU_KLEIDIAI=ON ``` -Set CMAKE_C_COMPILER and CMAKE_CXX_COMPILER to your cross compiler path. Make sure that *-march* in CMAKE_C_FLAGS and CMAKE_CXX_FLAGS includes "+sme2". -The *-static* and *-g* options are specified to produce a statically linked executable, in oder to run on different Arm64 Linux/Android environments and include debug information. +{{% notice Note %}} +Set `CMAKE_C_COMPILER` and `CMAKE_CXX_COMPILER` to your cross compiler path if it is not already in your `PATH`. Make sure that `-march` in `CMAKE_C_FLAGS` and `CMAKE_CXX_FLAGS` includes `+sme2`. +{{% /notice %}} + + +The `-static` and `-g` options are specified to produce a statically linked executable, in order to run on different Arm64 Linux/Android environments and include debug information. Next, build the project, ```bash -cd ~/llama.cpp/build +cd $HOME/llama.cpp/build cmake --build ./ --config Release -j $(nproc) ``` -After the building process completes, you can find the application,*llama-cli*,in the ~/llama.cpp/build/bin/ directory. - -To enable SME2 microkernels, you must set following environment variable before running the application. +After the building process completes, verify that *llama-cli* exists in the binary directory: ```bash -GGML_KLEIDIAI_SME="1" -``` \ No newline at end of file +ls -la $HOME/llama.cpp/build/bin | grep llama-cli +``` + +Now that you have a `llama-cli` build with KleidiAI enabled, move on to the next section to run the model on your SME2 device and observe the performance impact when you enable the microkernels. \ No newline at end of file diff --git a/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/introduction.md b/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/introduction.md index d5d69b7ddf..31b669083e 100644 --- a/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/introduction.md +++ b/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/introduction.md @@ -3,10 +3,11 @@ title: Overview weight: 2 ### FIXED, DO NOT MODIFY -layout: Overview +layout: learningpathall --- ## Introduction +In this section, you get a quick mental model of SME2, KleidiAI, and what llama.cpp is doing when it runs LLM inference on an Arm CPU. Arm’s latest Client CPU processors such as Arm C1 include Scalable Matrix Extension 2 (SME2). SME2 accelerates the matrix-heavy AI operations behind large language models (LLMs), media processing, speech recognition, computer vision, real-time apps and multimodal apps. llama.cpp provides extensive support for many LLMs, including Phi, Llama, DeepSeek, Gemma and Qwen. Llama.cpp is designed for efficient CPU-based inference. It enables on-device LLM execution, reducing latency and enhancing privacy. @@ -17,3 +18,4 @@ In this learning path, llama.cpp and Llama-3.2-3B-Instruct-Q4_0.gguf model with + diff --git a/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/kleidiai_integration.md b/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/kleidiai_integration.md index e02d307be0..f857748b52 100644 --- a/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/kleidiai_integration.md +++ b/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/kleidiai_integration.md @@ -7,16 +7,23 @@ layout: learningpathall --- ## Integration of SME2 optimized KleidiAI microkernels in llama.cpp -KleidiAI library provides optimized matrix multiplication (matmul) kernels tailored for hardware features such as SME, I8MM, and Dot Product(DotProd) acceleration. The feature can be enabled with the build option GGML_CPU_KLEIDIAI. +In this section, you look at how SME2 connects into the Arm software ecosystem by following the path from llama.cpp, through its ggml CPU backend, down to Arm KleidiAI microkernels that take advantage of SME2 when the hardware supports it. + +### Where does KleidiAI fit in the llama.cpp CPU backend? + +The KleidiAI library provides optimized matrix multiplication (matmul) kernels tailored for hardware features such as SME, I8MM, and Dot Product (DotProd) acceleration. In llama.cpp this feature is enabled with the build option `GGML_CPU_KLEIDIAI`. ![Figure showing components of llama.cpp alt-text#center](images/llama_components.jpg "Components of llama.cpp") -The KleidiAI is integrated as a trait of ggml-cpu in llama.cpp CPU backend. -The integration source code locates in following directory of llama.cpp. +KleidiAI is integrated as a trait of `ggml-cpu` in the llama.cpp CPU backend. +The integration source code is located in the following directory of llama.cpp: ```text ./ggml/src/ggml-cpu/kleidiai ``` -KleidiAI matmul microkernels can be used for some types of GGML_OP_MUL_MAT operators. The table below lists some matmul operators with specific input and output data type that can be accelerated by KleidiAI microkernels. + +### Which matmul operators can use KleidiAI microkernels? + +KleidiAI matmul microkernels can be used for some types of `GGML_OP_MUL_MAT` operators. The table below lists some matmul operators with specific input and output data type that can be accelerated by KleidiAI microkernels. | LHS data type | RHS data type | Output data type | |---------|----------------|----------------| @@ -24,24 +31,35 @@ KleidiAI matmul microkernels can be used for some types of GGML_OP_MUL_MAT opera | GGML_TYPE_F32 | GGML_TYPE_Q8_0 | GGML_TYPE_F32 | | GGML_TYPE_F32 | GGML_TYPE_F16 | GGML_TYPE_F32 | -Note: -LHS is short for Left Hand Source(or Left Hand Input Matrix). -RHS is short for Right Hand Source(or Right Hand Input Matrix). + +{{% notice Note %}} +In this table, LHS is short for left-hand source (left-hand input matrix) and RHS is short for right-hand source (right-hand input matrix). +{{% /notice %}} + More operators and data types are being supported by KleidiAI microkernels. -The figure below shows how KleidiAI microkernels are used for matmul with GGML_TYPE_Q4_0 or GGML_TYPE_Q8_0 RHS(weight). +### How does the KleidiAI path work? + +The figure below shows how KleidiAI microkernels are used for `matmul` with `GGML_TYPE_Q4_0` or `GGML_TYPE_Q8_0` RHS(weight). ![Figure showing how kleidiai microkernel is used for quantization, packing and matrix multiply llama.cpp alt-text#center](images/kai_matmul_kernel.jpg "Quantization, packing and matrix multiply microkernels") -The packing of GGML_TYPE_Q4_0 or GGML_TYPE_Q8_0 weight (RHS) only needs to be performed one-time when llama.cpp loads the model and weight tensor data, since the weight never changes during the inference. For performance, it repacks the original GGUF weights into a layout optimized for cache-friendly access and DotProd, I8MM, and SME2 operations with the KleidiAI microkernels. -Generally, if multiple choice of KleidiAI matmul microkernels (implemented with DotProd, I8MM or SME2) can be used for acceleration, the KleidAI trait selects one of implementation in following order, +The packing of `GGML_TYPE_Q4_0` or `GGML_TYPE_Q8_0` weight (RHS) only needs to be performed one time when llama.cpp loads the model and weight tensor data, because the weight never changes during inference. For performance, it repacks the original GGUF weights into a layout optimized for cache-friendly access and DotProd, I8MM, and SME2 operations with the KleidiAI microkernels. - ```text - SME2, I8MM, DotProd +Generally, if multiple KleidiAI matmul microkernels (implemented with DotProd, I8MM, or SME2) can be used for acceleration, the KleidiAI trait selects an implementation in the following order: + +```output +SME2 -> I8MM -> DotProd ``` Once the matmul microkernel is decided, its corresponding RHS packing and LHS quantizing & packing micro-kernel will be used. +## Call stacks + +The call stacks below are included as a way to make this integration concrete. Read each stack from top to bottom: the top frames show the high-level llama.cpp operation you triggered (loading the model or decoding tokens), the middle frames show where execution enters the `ggml-cpu` backend, and the bottom frame is the specific KleidiAI microkernel that runs. The first stack shows a one-time weight repack during model load, which happens because the model weights are constant during inference. The later stacks show what happens during inference: activations change from token to token, so the LHS is quantized and packed each time, and then the selected SME2 GEMM or GEMV microkernel executes the matmul. + +### During model load + In case of using the Llama-3.2-3B-Instruct-Q4_0.gguf model and SME2 microkernels, RHS packing is done by the *kai_run_rhs_pack_nxk_qsi4c32ps1s0scalef16_qsu4c32s16s0_neon* microkernel when loading the model. It is shown in following function call stack, ```text @@ -53,6 +71,9 @@ llama_model_load ggml::cpu::kleidiai::tensor_traits::repack kai_run_rhs_pack_nxk_qsi4c32ps1s0scalef16_qsu4c32s16s0_neon ``` + +### During inference + The F32 activation input matrix (LHS) is dynamically quantized and packed by the *kai_run_lhs_quant_pack_qsi8d32p_f32_neon* microkernel every time, since the activation input keeps changing during the model run. It is done by following function call stack, ```text @@ -71,7 +92,9 @@ llama_context::decode ``` Once the LHS and RHS is ready, KleidiAI matmul microkernel can be executed. -In this example, we use Llama-3.2-3B-Instruct-Q4_0.gguf model and 512-bit SME2 streaming vector length. At the Prefill stage, the KleidiAI GEMM microkernel optimized with SME2, *kai_matmul_clamp_f32_qsi8d32p1vlx4_qsi4c32p4vlx4_1vlx4vl_sme2_mopa*, is selected by the KleidiAI trait, it produces a dequantized F32 output matrix. It is done right after LHS quantizing & packing by function call stack shown below. +### During prefill + +`Llama-3.2-3B-Instruct-Q4_0.gguf` model and 512-bit SME2 streaming vector length are used as an example. At the Prefill stage, the KleidiAI GEMM microkernel optimized with SME2, *kai_matmul_clamp_f32_qsi8d32p1vlx4_qsi4c32p4vlx4_1vlx4vl_sme2_mopa*, is selected by the KleidiAI trait, it produces a dequantized F32 output matrix. It is done right after LHS quantizing and packing by function call stack shown below. ```text llama_context::decode llama_context::process_ubatch @@ -87,6 +110,9 @@ llama_context::decode kai_run_lhs_quant_pack_qsi8d32p_f32_neon kai_matmul_clamp_f32_qsi8d32p1vlx4_qsi4c32p4vlx4_1vlx4vl_sme2_mopa ``` + +### During token decode + At the LLM decode stage, KleidiAI GEMV micro-kernel optimized with SME2, *kai_run_matmul_clamp_f32_qsi8d32p1x4_qsi4c32p4vlx4_1x4vl_sme2_sdot*, is selected by the KleidiAI trait in llama.cpp, it produces a dequantized F32 output vector. It is done right after LHS quantizing & packing by function call stack shown below, ```text @@ -104,3 +130,5 @@ llama_context::decode kai_run_lhs_quant_pack_qsi8d32p_f32_neon kai_run_matmul_clamp_f32_qsi8d32p1x4_qsi4c32p4vlx4_1x4vl_sme2_sdot ``` + +Now that you know where the KleidiAI SME2 path lives in llama.cpp and what it accelerates, move on to the next section to build the binary for inference. diff --git a/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/run_llm.md b/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/run_llm.md index dd494f2e25..8cfb1f5a53 100755 --- a/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/run_llm.md +++ b/content/learning-paths/mobile-graphics-and-gaming/performance_llama_cpp_sme2/run_llm.md @@ -7,38 +7,83 @@ layout: learningpathall --- ## Run the Llama-3.2-3B-Instruct-Q4_0.gguf model with llama-cli -Put the built llama-cli executable and Llama-3.2-3B-Instruct-Q4_0.gguf model file to your aarch64 Linux/Android target that supports SME2. -The model can be downloaded [here](https://huggingface.co/unsloth/Llama-3.2-3B-Instruct-GGUF). + +In this section, you run the model on an SME2-capable Android device. You will compare performance with SME2 enabled and disabled. + +Put the built `llama-cli` executable and the `Llama-3.2-3B-Instruct-Q4_0.gguf` model file on your Android target that supports SME2. Using Android Debug Bridge (ADB) is usually the easiest way to transfer files and open a shell on the device. + +The model is hosted on [Hugging Face](https://huggingface.co/unsloth/Llama-3.2-3B-Instruct-GGUF). Download to your host machine using `curl`: + +```bash +curl -L -o Llama-3.2-3B-Instruct-Q4_0.gguf \ + https://huggingface.co/unsloth/Llama-3.2-3B-Instruct-GGUF/resolve/main/Llama-3.2-3B-Instruct-Q4_0.gguf +``` + +## Transfer the files using ADB +This subsection shows a repeatable way to copy your `llama-cli` binary and GGUF model from your host machine to an Android target device, and then run the same commands from an interactive shell on the device. + +Enable **Developer options** and **USB debugging** on the Android device, connect it over USB (or over the network if your setup supports it), and verify that your host can see the device: + +```bash +adb devices +``` + +Create a working directory on the device and push the binary and model into it. Run these commands on your host machine from the directory that contains `llama-cli` and `Llama-3.2-3B-Instruct-Q4_0.gguf`: + +```bash +adb shell "mkdir -p /data/local/tmp/llama_sme2" +adb push ./llama-cli /data/local/tmp/llama_sme2/ +adb push ./Llama-3.2-3B-Instruct-Q4_0.gguf /data/local/tmp/llama_sme2/ +adb shell "chmod +x /data/local/tmp/llama_sme2/llama-cli" +``` + +Now open an interactive shell and switch to that directory. From here onward, you are running on the Android target device: + +```bash +adb shell +cd /data/local/tmp/llama_sme2 +``` The figure below shows the architecture of Llama-3.2-3B model, ![Figure showing Llama-3.2-3B architecture alt-text#center](images/llama-3.2-3b_architecture.jpg "Architecture of Llama-3.2-3B") -For performance evaluation, we run the model by binding it to a single Arm C1-Pro core with CPU affinity. -To run the model with SME2 microkernels enabled, set the environment variable first. +## Inference with SME2 enabled + +You run the model by binding it to a single Arm C1-Pro core with CPU affinity. To enable SME2 microkernels, you must set the `GGML_KLEIDIAI_SME` environment variable before running the application. + +Run an inference on your target device: ```bash -env GGML_KLEIDIAI_SME="1" taskset 2 ./llama-cli -m ./ Llama-3.2-3B-Instruct-Q4_0.gguf -st -C 0x2 -Cb 0x2 -t 1 -p "input your prompt" +env GGML_KLEIDIAI_SME="1" taskset 2 ./llama-cli -m ./Llama-3.2-3B-Instruct-Q4_0.gguf -st -C 0x2 -Cb 0x2 -t 1 -p "input your prompt" ``` -Where -- *env GGML_KLEIDIAI_SME="1"* sets the environment variable -- *taskset 2* sets the task affinity and binds the execution of llama-cli to CPU core 2 (the Arm C1-Pro core in our case) -- *-C 0x2 -Cb 0x2* sets the CPU affinity of the execution of operators -- *-t 1* sets the number of threads to 1 -For performance comparison, we also run the model with SME2 microkernels disabled by the setting the environment variable, +Here `env GGML_KLEIDIAI_SME="1"` enables SME2 microkernels, `taskset 2` binds the `llama-cli` process to CPU core 2 (the Arm C1-Pro core in our case), `-C 0x2 -Cb 0x2` sets the CPU affinity for operator execution, and `-t 1` sets the number of threads to one. If `taskset` is not available on your target device, run the same command without it. -```bash -GGML_KLEIDIAI_SME="0" +With the SME2 kernels enabled, you'll notice the following performance output: + +```output +[ Prompt: 12.3 t/s | Generation: 9.1 t/s ] ``` -so that I8MM and Dotprod microkernels are used instead. + +## Inference without SME2 enabled + +For a performance comparison, you can run the model with SME2 microkernels disabled. In this scenario, I8MM and Dotprod microkernels are used instead. ```bash -env GGML_KLEIDIAI_SME="0" taskset 2 ./llama-cli -m ./ Llama-3.2-3B-Instruct-Q4_0.gguf -st -C 0x2 -Cb 0x2 -t 1 -p "input your prompt" +env GGML_KLEIDIAI_SME="0" taskset 2 ./llama-cli -m ./Llama-3.2-3B-Instruct-Q4_0.gguf -st -C 0x2 -Cb 0x2 -t 1 -p "input your prompt" +``` + +With the resulting performance: + +```output +[ Prompt: 7.9 t/s | Generation: 5.9 t/s ] ``` -We can profile the model execution with the approach introduced in [Profile llama.cpp performance with Arm Streamline and KleidiAI LLM kernels](https://learn.arm.com/learning-paths/servers-and-cloud-computing/llama_cpp_streamline/). +## Optional: Use Streamline to profile -The Streamline Timeline view and Annotate Markers in the figure below show that the token generation speeds up significantly at both Prefill and Decode stage. The PMU event counters show that many SME2 instructions, especially SME2 Integer Outer Product Accumulate instructions at the Prefill stage and SME2 Integer Outer Product instructions at the Decode stage, are used for acceleration. +You can profile the model execution with the approach introduced in [Profile llama.cpp performance with Arm Streamline and KleidiAI LLM kernels](https://learn.arm.com/learning-paths/servers-and-cloud-computing/llama_cpp_streamline/). + +The Streamline Timeline view and Annotate Markers in the figure below show that the token generation speeds up significantly at both Prefill and Decode stage. The PMU event counters show that many SME2 instructions, especially SME2 Integer Outer Product Accumulate instructions at the Prefill stage and SME2 Integer Outer Product instructions at the Decode stage, are used for acceleration. ![Figure showing Streamline Timeline view alt-text#center](images/streamline_timeline_combined.jpg "Combined Streamline Timeline view with and without SME2") @@ -46,9 +91,11 @@ The Streamline Call Paths view below indicates similar speedup, it also shows th ![Figure showing Streamline Call Paths view alt-text#center](images/streamline_call_paths_combined.jpg "Combined Streamline Call Paths view with and without SME2") -To investigate which operators in the model graph are delegated to KleidiAI microkernels, we can add some codes as below to *./ggml/src/ggml-cpu/kleidiai/kleidiai.cpp* to print out the name of operators that make use of kleidiAI microkernels. This is only for debugging purpose. +## Optional: Print the kernel names at runtime + +To investigate which operators in the model graph are delegated to KleidiAI microkernels, you can add some code as below to *./ggml/src/ggml-cpu/kleidiai/kleidiai.cpp* and recompile the binary. When you run the inference, the names of operators that make use of KleidiAI microkernels will be printed. This is only for debugging purposes. -```c++ +```cpp bool compute_forward(struct ggml_compute_params * params, struct ggml_tensor * dst) override { if (dst->op == GGML_OP_MUL_MAT) { @@ -66,8 +113,9 @@ To investigate which operators in the model graph are delegated to KleidiAI micr return compute_forward_fp16(params, dst); } ``` -When running the model, some log will be printed as below, -```text +When running the model, some log will be printed as below: + +```output kai matmul Q4_0 Qcur-27 kai matmul Q4_0 Vcur-27 kai matmul Q4_0 Kcur-27 @@ -76,11 +124,11 @@ kai matmul Q4_0 ffn_gate-27 kai matmul Q4_0 ffn_up-27 kai matmul Q4_0 ffn_out-27 ``` -Take one attention block of Llama-3.2-3B-Instruct-Q4_0 model for example, the operators that are accelerated by KleidiAI SME2-optimized microkernels are highlighted manually by the blue boxs in the figure of graph of the attention block. How to get the graph is beyond the scope of this learning path. Please refer to external resources. -![Figure highlighting operators acclerated by KleidiAI SME2-optimized microkernels alt-text#center](images/one_attention_block.jpg "Operators acclerated by KleidiAI SME2-optimized microkernels in one attention block") +## Summary KleidiAI support in llama.cpp is still evolving, more operators will be accelerated by KleidiAI microkernels, unleashing greater potential of SME2. -## Summary -With out-of-box KleidiAI and SME2 support in llama.cpp, we can get significant performance uplift at both Prefill and Decode stage, which enhances the experience of running LLM locally on device. +With out-of-box KleidiAI and SME2 support in llama.cpp, you can get significant performance uplift at both Prefill and Decode stage, which enhances the experience of running LLM locally on device. + +Now that you have validated the runtime behavior with SME2 on your target device, move on to the Next Steps section to explore profiling and related Arm on-device AI performance resources. diff --git a/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/1-introduction.md b/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/1-introduction.md new file mode 100644 index 0000000000..b7df6cfdd5 --- /dev/null +++ b/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/1-introduction.md @@ -0,0 +1,55 @@ +--- +title: Explore PTQ and QAT for ExecuTorch INT8 deployment +weight: 2 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Quantization with ExecuTorch and the Arm backend + +PTQ and QAT both aim to run your model with quantized operators (typically INT8). The difference is where you pay the cost: PTQ optimizes for speed of iteration, while QAT optimizes for quality and robustness. + +In this Learning Path, you use quantization as part of the ExecuTorch Arm backend. The goal is to export a quantized model that can run on Arm hardware with dedicated neural accelerators (NX). + +To keep the workflow concrete, you start with a complete, runnable CIFAR-10-based example that exports `.vgf` artifacts end to end. After you have a known-good baseline, you can apply the same steps to your own neural network and training code. + +The Arm backend in ExecuTorch provides an open, standardized, minimal operator set for neural network operations to be lowered to, and is used by Arm platforms and accelerators. + +The ExecuTorch Arm backend uses three key components to optimize your model for Arm hardware: + +- TOSA (Tensor Operator Set Architecture) provides a standardized operator set for acceleration on Arm platforms. +- ExecuTorch Arm backend lowers your PyTorch model to TOSA using ahead-of-time (AOT) compilation. +- VGF backend produces portable `.vgf` artifacts that work with downstream tools and Vulkan-based pipelines. + +### Post-training quantization (PTQ) + +PTQ keeps training simple. You train your FP32 model as usual, then run a calibration pass using representative inputs to determine quantization parameters (for example, scales). After calibration, you convert the model and export a quantized graph. + +PTQ is a good default when you need a fast iteration loop and you have a calibration set that looks like the actual inference data. For neural networks, PTQ can be good enough for early bring-up, especially when your goal is to validate the export and integration path. Depending on the model and use case, PTQ can provide good quality results equal to the original floating-point graph. + +### Quantization-aware training (QAT) + +QAT simulates quantization effects during training. You prepare the model for QAT, fine-tune with fake-quantization enabled, then convert and export. + +QAT introduces visible drop in model accuracy. For example, this is common for image-to-image tasks because small numeric changes can show up as banding, ringing, or loss of fine detail. + +## ExecuTorch quantization workflow for Arm + +For Arm-based platforms, the workflow stays consistent across models: + +- Train and evaluate the neural network in PyTorch. +- Quantize (PTQ or QAT) to reduce runtime cost. +- Export with ExecuTorch (via TOSA) to generate a `.vgf` artifact. +- Run the `.vgf` model in your Vulkan-based pipeline. + +In later sections, you generate the `.vgf` file using the ExecuTorch Arm backend VGF partitioner. + +## What you've accomplished and what's next + +In this section: +- You covered the difference between PTQ and QAT, and when to use each +- You saw how the ExecuTorch Arm backend uses TOSA as an intermediate representation +- You traced the end-to-end export workflow that produces `.vgf` artifacts + +In the next section, you create a Python environment with all the tools needed to run the examples. diff --git a/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/2-set-up-your-environment.md b/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/2-set-up-your-environment.md new file mode 100644 index 0000000000..7dbeef8c03 --- /dev/null +++ b/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/2-set-up-your-environment.md @@ -0,0 +1,92 @@ +--- +title: Set up your environment for ExecuTorch quantization +weight: 3 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Install and configure PyTorch, TorchAO, and ExecuTorch for quantization + +In this section, you create a Python environment with PyTorch, TorchAO, and ExecuTorch components needed for quantization and `.vgf` export. + +{{% notice Note %}} +If you already use [Neural Graphics Model Gym](/learning-paths/mobile-graphics-and-gaming/model-training-gym), keep that environment and reuse it here. +{{% /notice %}} + +## Create a virtual environment + +Create and activate a virtual environment: + +```bash +python3 -m venv venv +source venv/bin/activate +python -m pip install --upgrade pip +``` + +## Clone the ExecuTorch repository + +In your virtual environment, clone the ExecuTorch repository and run the installation script: + +```bash +git clone https://github.com/pytorch/executorch.git +cd executorch +./install_executorch.sh +``` + +## Run the Arm backend setup script + +From the root of the cloned `executorch` repository, run the Arm backend setup script: + +```bash +./examples/arm/setup.sh \ + --i-agree-to-the-contained-eula \ + --disable-ethos-u-deps \ + --enable-mlsdk-deps +``` + +In the same terminal session, source the generated setup script so the Arm backend tools (including the model converter) are available on your `PATH`: + +```bash +source ./examples/arm/arm-scratch/setup_path.sh +``` + +Verify the model converter is available: + +```bash +command -v model-converter || command -v model_converter +``` + +Verify your imports: + +```python +import torch +import torchvision +import torchao + +import executorch +import executorch.backends.arm +from executorch.backends.arm.vgf.partitioner import VgfPartitioner + +print("torch:", torch.__version__) +print("torchvision:", torchvision.__version__) +print("torchao:", torchao.__version__) +``` + +{{% notice Tip %}} +If `executorch.backends.arm` is missing, you installed an ExecuTorch build without the Arm backend. Use an ExecuTorch build that includes `executorch.backends.arm` and the VGF partitioner. + +If you checked out a specific ExecuTorch branch (for example, `release/1.0`) and you run into version mismatches, check out the main branch of ExecuTorch from the cloned repository and install from source: + +```bash +pip install -e . +``` +{{% /notice %}} + +## What you've accomplished and what's next + +In this section, you: +- Created a Python virtual environment with PyTorch, TorchAO, and ExecuTorch +- Ran the Arm backend setup script and verified the model converter is available on your `PATH` + +In the next section, you apply PTQ to a sample model and generate a `.vgf` artifact. diff --git a/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/3-run-ptq-and-export-vgf.md b/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/3-run-ptq-and-export-vgf.md new file mode 100644 index 0000000000..47878d2d6c --- /dev/null +++ b/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/3-run-ptq-and-export-vgf.md @@ -0,0 +1,306 @@ +--- +title: Apply PTQ and export a quantized VGF model +weight: 4 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Apply post-training quantization and export to VGF + + +In this section, you apply post-training quantization (PTQ) to an image-to-image model and export a `.vgf` artifact. + +The default workflow in this Learning Path is end to end: you run a complete CIFAR-10-based example, generate a `.vgf` artifact, and validate that the Arm backend export path works on your machine. + +After that, you take the same PTQ export logic and apply it to your own model and calibration data. + +## Run the end-to-end PTQ example + +Create a file called `quantize_and_export_vgf.py` and add the following code. + +This example uses CIFAR-10 as a convenient image source. It constructs a low-resolution input by downsampling an image, then trains the model to reconstruct the original image. This is a practical proxy for a real neural upscaler. + +```python +import torch +from torch.utils.data import DataLoader +from torch import nn +from torchvision import datasets, transforms + +import torch.nn.functional as F + +from executorch.backends.arm.tosa.specification import TosaSpecification +from executorch.backends.arm.vgf.compile_spec import VgfCompileSpec +from executorch.backends.arm.vgf.partitioner import VgfPartitioner +from executorch.backends.arm.quantizer.arm_quantizer import ( + get_symmetric_quantization_config, + TOSAQuantizer, +) +from executorch.exir import to_edge_transform_and_lower + +from torchao.quantization.pt2e.quantize_pt2e import ( + convert_pt2e, + prepare_pt2e, +) + + +class SmallUpscalerModel(nn.Module): + """Small image-to-image model for upscaling workflows.""" + + def __init__(self): + super().__init__() + self.net = nn.Sequential( + nn.Conv2d(3, 32, kernel_size=3, padding=1), + nn.ReLU(), + nn.Conv2d(32, 32, kernel_size=3, padding=1), + nn.ReLU(), + nn.Conv2d(32, 3, kernel_size=3, padding=1), + ) + + def forward(self, x_lowres): + # Upscale input first, then refine. + x = F.interpolate(x_lowres, scale_factor=2.0, mode="bilinear", align_corners=False) + x = self.net(x) + return x + + +def get_data_loaders(root="./data", batch_size=64): + tfm = transforms.Compose([ + transforms.ToTensor(), + ]) + train_ds = datasets.CIFAR10(root=root, train=True, download=True, transform=tfm) + test_ds = datasets.CIFAR10(root=root, train=False, download=True, transform=tfm) + train_loader = DataLoader(train_ds, batch_size=batch_size, shuffle=True, drop_last=True) + test_loader = DataLoader(test_ds, batch_size=batch_size, shuffle=False) + return train_loader, test_loader + + +def make_lowres_input(x_hr: torch.Tensor): + # Simulate a game render at lower resolution. + return F.interpolate(x_hr, scale_factor=0.5, mode="bilinear", align_corners=False) + + +@torch.no_grad() +def evaluate_psnr(model, loader, device="cpu", max_batches=50): + psnr_sum = 0.0 + count = 0 + + for i, (x_hr, _y) in enumerate(loader): + if max_batches is not None and i >= max_batches: + break + + x_hr = x_hr.to(device) + x_lr = make_lowres_input(x_hr) + pred = model(x_lr) + + mse = F.mse_loss(pred, x_hr) + psnr = 10.0 * torch.log10(1.0 / mse.clamp_min(1e-12)) + + psnr_sum += psnr.item() + count += 1 + + return psnr_sum / max(1, count) + + +def train_model( + model: nn.Module, + train_loader: DataLoader, + test_loader: DataLoader | None = None, + device: str = "cpu", + epochs: int = 1, + lr: float = 1e-3, + log_every: int = 50, +): + model.to(device) + optimizer = torch.optim.AdamW(model.parameters(), lr=lr) + + for epoch in range(epochs): + model.train() + + for step, (x_hr, _y) in enumerate(train_loader): + x_hr = x_hr.to(device) + x_lr = make_lowres_input(x_hr) + + optimizer.zero_grad() + pred = model(x_lr) + loss = F.mse_loss(pred, x_hr) + loss.backward() + optimizer.step() + + if log_every and (step % log_every == 0): + print(f"epoch={epoch+1} step={step} loss={loss.item():.6f}") + + if test_loader is not None: + model.eval() + psnr = evaluate_psnr(model, test_loader, device=device, max_batches=50) + print(f"epoch={epoch+1} end psnr={psnr:.2f} dB") + model.train() + + return model + + +def make_example_input_from_loader(loader, batch_size=1): + x_hr, _y = next(iter(loader)) + + # Use channels_last to reduce transpose noise in the exported graph. + x_hr = x_hr[:batch_size].to("cpu").to(memory_format=torch.channels_last) + x_lr = make_lowres_input(x_hr) + + return (x_lr,) + + +def make_calibration_batches(loader: DataLoader, num_batches: int): + cal = [] + for i, (x_hr, _y) in enumerate(loader): + if i >= num_batches: + break + x_lr = make_lowres_input(x_hr.to("cpu")) + cal.append(x_lr) + + if len(cal) == 0: + raise RuntimeError("Calibration set is empty; check loader/num_batches.") + + return cal + + +def ptq_example(device="cpu"): + """PTQ example: calibrate, convert, then export to VGF.""" + + # 1) Train (or load) a baseline model. + model = SmallUpscalerModel() + train_loader, test_loader = get_data_loaders() + + # Keep training short for the tutorial. + model = train_model(model, train_loader, test_loader, device=device, epochs=1) + + model = model.to("cpu") + model.eval() + + # 2) Export the FP32 model. + example_input = make_example_input_from_loader(train_loader, batch_size=1) + exported_model = torch.export.export(model, example_input, strict=True).module(check_guards=False) + + # 3) Configure the Arm backend quantizer. + tosa_spec = "TOSA-1.00+INT" + quantizer = TOSAQuantizer(TosaSpecification.create_from_string(tosa_spec)) + quantizer.set_global(get_symmetric_quantization_config(is_qat=False)) + + # 4) Prepare for PTQ. + quantized_export_model = prepare_pt2e(exported_model, quantizer) + + # 5) Calibrate with representative inputs. + calibration_loader, _ = get_data_loaders(batch_size=1) + calibration_data = make_calibration_batches(calibration_loader, num_batches=500) + + with torch.no_grad(): + for x_lr in calibration_data: + quantized_export_model(x_lr) + + # 6) Convert to an INT8 model. + quantized_export_model = convert_pt2e(quantized_export_model) + + # 7) Export again so the quantized graph is captured. + aten_dialect = torch.export.export( + quantized_export_model, + args=example_input, + strict=True, + ) + + # 8) Partition and dump a `.vgf` artifact. + compile_spec = VgfCompileSpec(TosaSpecification.create_from_string(tosa_spec)) + vgf_partitioner = VgfPartitioner( + compile_spec.dump_intermediate_artifacts_to("./output/") + ) + + to_edge_transform_and_lower(aten_dialect, partitioner=[vgf_partitioner]) + + +if __name__ == "__main__": + ptq_example(device="cpu") +``` + +### Run the script + +Run the script: + +```bash +python quantize_and_export_vgf.py +``` + +The output is similar to: + +```output +epoch=1 step=0 loss=0.208134 +epoch=1 step=50 loss=0.053812 +epoch=1 end psnr=19.42 dB +``` + +Check the `./output/` directory for exported files. The exact filenames depend on your ExecuTorch version and backend configuration, but the directory should include an exported `.vgf` artifact. + +{{% notice Tip %}} +If export fails because of `bilinear` resize, switch the interpolation modes in `make_lowres_input()` and `forward()` to `mode="nearest"`. This keeps the tutorial flow intact while you investigate backend operator support. +{{% /notice %}} + +## Advanced: export PTQ to VGF in your own project + +Once the end-to-end example works, apply the same flow to your own model. + +{{% notice Note %}} +If you don't have a workflow or model, you can skip this section and proceed to the next page. +{{% /notice %}} + + +If you already have a trained model, this is the minimal PTQ-to-`.vgf` flow. Start from your FP32 PyTorch module (`model_fp32`) and an `example_input` tuple that matches your real inference inputs. You also need a list of representative `calibration_batches`, typically 100–500 samples. + +```python +import torch + +from executorch.backends.arm.tosa.specification import TosaSpecification +from executorch.backends.arm.vgf.compile_spec import VgfCompileSpec +from executorch.backends.arm.vgf.partitioner import VgfPartitioner +from executorch.backends.arm.quantizer.arm_quantizer import ( + get_symmetric_quantization_config, + TOSAQuantizer, +) +from executorch.exir import to_edge_transform_and_lower + +from torchao.quantization.pt2e.quantize_pt2e import convert_pt2e, prepare_pt2e + + +def export_vgf_int8_ptq( + model_fp32: torch.nn.Module, + example_input: tuple[torch.Tensor, ...], + calibration_batches: list[torch.Tensor], + output_dir: str, + tosa_spec: str = "TOSA-1.00+INT", +): + model_fp32 = model_fp32.to("cpu") + model_fp32.eval() + + exported = torch.export.export(model_fp32, example_input, strict=True).module(check_guards=False) + + quantizer = TOSAQuantizer(TosaSpecification.create_from_string(tosa_spec)) + quantizer.set_global(get_symmetric_quantization_config(is_qat=False)) + q = prepare_pt2e(exported, quantizer) + + with torch.no_grad(): + for x in calibration_batches: + q(x) + + q = convert_pt2e(q) + aten_dialect = torch.export.export(q, args=example_input, strict=True) + + compile_spec = VgfCompileSpec(TosaSpecification.create_from_string(tosa_spec)) + vgf_partitioner = VgfPartitioner(compile_spec.dump_intermediate_artifacts_to(output_dir)) + to_edge_transform_and_lower(aten_dialect, partitioner=[vgf_partitioner]) +``` + +When you use your own model, the most important input is the calibration set. Treat it like a contract: if it doesn't look like your actual inference data, PTQ quality can degrade. + +## What you've accomplished and what's next + +In this section, you: +- Applied PTQ to an image-to-image model using TorchAO PT2E quantization APIs +- Exported a quantized INT8 graph as a `.vgf` artifact using the ExecuTorch Arm backend + +In the next section, you repeat the workflow using QAT, which gives the model a chance to adapt to quantization during fine-tuning. diff --git a/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/4-run-qat-and-export-vgf.md b/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/4-run-qat-and-export-vgf.md new file mode 100644 index 0000000000..8d3c7203d2 --- /dev/null +++ b/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/4-run-qat-and-export-vgf.md @@ -0,0 +1,197 @@ +--- +title: Apply QAT and export a quantized VGF model +weight: 5 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Configure QAT fine-tuning and export to VGF + +In this section, you run quantization-aware training (QAT) so the model learns to be robust to quantization effects. + +The default workflow is to extend the runnable CIFAR-10 based example from the PTQ step so you can compare PTQ and QAT outputs using the same model and data. + +## Extend the sample model with QAT + +In `quantize_and_export_vgf.py`, update your TorchAO imports to include the QAT helpers: + +```python +from torchao.quantization.pt2e.quantize_pt2e import ( + convert_pt2e, + prepare_qat_pt2e, +) +from torchao.quantization.pt2e import ( + move_exported_model_to_eval, + move_exported_model_to_train, +) +``` + +Then add the QAT training function and example entry point. This code prepares the exported model for QAT, fine-tunes for a small number of epochs, converts to INT8, and exports to `.vgf`. + +```python +def train_model_qat( + model: nn.Module, + train_loader: DataLoader, + test_loader: DataLoader | None = None, + device: str = "cpu", + epochs: int = 1, + lr: float = 1e-4, + log_every: int = 50, +): + model.to(device) + optimizer = torch.optim.AdamW(model.parameters(), lr=lr) + + for epoch in range(epochs): + move_exported_model_to_train(model) + + for step, (x_hr, _y) in enumerate(train_loader): + x_hr = x_hr.to(device) + x_lr = make_lowres_input(x_hr) + + optimizer.zero_grad() + pred = model(x_lr) + loss = F.mse_loss(pred, x_hr) + loss.backward() + optimizer.step() + + if log_every and (step % log_every == 0): + print(f"qat epoch={epoch+1} step={step} loss={loss.item():.6f}") + + if test_loader is not None: + move_exported_model_to_eval(model) + psnr = evaluate_psnr(model, test_loader, device=device, max_batches=50) + print(f"qat epoch={epoch+1} end psnr={psnr:.2f} dB") + + return model + + +def qat_example(device="cpu"): + """QAT example: prepare for QAT, fine-tune, convert, then export to VGF.""" + + # 1) Train (or load) a baseline FP32 model. + model = SmallUpscalerModel() + train_loader, test_loader = get_data_loaders() + model = train_model(model, train_loader, test_loader, device=device, epochs=1) + + # 2) Export the FP32 model. + example_input = make_example_input_from_loader(train_loader, batch_size=1) + exported_model = torch.export.export(model, example_input, strict=True).module(check_guards=False) + + # 3) Configure the Arm backend quantizer. + tosa_spec = "TOSA-1.00+INT" + quantizer = TOSAQuantizer(TosaSpecification.create_from_string(tosa_spec)) + quantizer.set_global(get_symmetric_quantization_config(is_qat=True)) + + # 4) Prepare for QAT. + qat_ready_model = prepare_qat_pt2e(exported_model, quantizer) + + # 5) Fine-tune with fake-quant enabled. + qat_ready_model = train_model_qat( + qat_ready_model, + train_loader, + test_loader, + device=device, + epochs=1, + lr=1e-4, + ) + + # 6) Convert to an INT8 model. + qat_ready_model = qat_ready_model.to("cpu") + move_exported_model_to_eval(qat_ready_model) + qat_int8_model = convert_pt2e(qat_ready_model) + + # 7) Export again so the quantized graph is captured. + aten_dialect = torch.export.export( + qat_int8_model, + args=example_input, + strict=True, + ) + + # 8) Partition and dump a `.vgf` artifact. + compile_spec = VgfCompileSpec(TosaSpecification.create_from_string(tosa_spec)) + vgf_partitioner = VgfPartitioner( + compile_spec.dump_intermediate_artifacts_to("./output_qat/") + ) + + to_edge_transform_and_lower(aten_dialect, partitioner=[vgf_partitioner]) +``` + +## Run the QAT example + +Update `__main__` to call `qat_example()` and run the script: + +```bash +python quantize_and_export_vgf.py +``` + +{{% notice Tip %}} +If export fails with a missing model converter error, you likely forgot to source the Arm backend `setup_path.sh` in your current terminal session. +{{% /notice %}} + +As the script runs, you should see QAT training logs (prefixed with `qat`). When export completes, you should see `.vgf` output under `./output_qat/`. + +## Advanced: drop-in QAT export to VGF for your own project + +If PTQ degrades model accuracy too much, QAT is the next step. The workflow is the same as PTQ, but you insert a short fine-tuning phase after you prepare the model for QAT. + +In practice, you already have a training loop for your upscaler. The simplest way to use QAT is to reuse that loop and point it at the QAT-prepared exported model. + +Use the following minimal structure as a starting point for your own project. You supply: + +- `model_fp32`: your baseline FP32 model +- `example_input`: a tuple of input tensors +- `fine_tune_qat`: a function that runs your fine-tuning loop (one or more epochs) + +```python +import torch + +from executorch.backends.arm.tosa.specification import TosaSpecification +from executorch.backends.arm.vgf.compile_spec import VgfCompileSpec +from executorch.backends.arm.vgf.partitioner import VgfPartitioner +from executorch.backends.arm.quantizer.arm_quantizer import ( + get_symmetric_quantization_config, + TOSAQuantizer, +) +from executorch.exir import to_edge_transform_and_lower + +from torchao.quantization.pt2e.quantize_pt2e import convert_pt2e, prepare_qat_pt2e +from torchao.quantization.pt2e import move_exported_model_to_eval + + +def export_vgf_int8_qat( + model_fp32: torch.nn.Module, + example_input: tuple[torch.Tensor, ...], + fine_tune_qat, + output_dir: str, + tosa_spec: str = "TOSA-1.00+INT", +): + model_fp32 = model_fp32.to("cpu") + model_fp32.eval() + + exported = torch.export.export(model_fp32, example_input, strict=True).module(check_guards=False) + + quantizer = TOSAQuantizer(TosaSpecification.create_from_string(tosa_spec)) + quantizer.set_global(get_symmetric_quantization_config(is_qat=True)) + qat_ready = prepare_qat_pt2e(exported, quantizer) + + # Run your fine-tuning loop here. This is where QAT earns its keep. + fine_tune_qat(qat_ready) + + qat_ready = qat_ready.to("cpu") + move_exported_model_to_eval(qat_ready) + q = convert_pt2e(qat_ready) + aten_dialect = torch.export.export(q, args=example_input, strict=True) + + compile_spec = VgfCompileSpec(TosaSpecification.create_from_string(tosa_spec)) + vgf_partitioner = VgfPartitioner(compile_spec.dump_intermediate_artifacts_to(output_dir)) + to_edge_transform_and_lower(aten_dialect, partitioner=[vgf_partitioner]) +``` + +## What you've accomplished and what's next + +In this section, you: +- Extended the CIFAR-10 example to run QAT with fake-quantization enabled during fine-tuning +- Exported the QAT-trained model as a `.vgf` artifact using the ExecuTorch Arm backend + +In the next section, you inspect both exported graphs in Model Explorer to validate the output before runtime integration. diff --git a/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/5-validate-and-choose-a-quantization-strategy.md b/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/5-validate-and-choose-a-quantization-strategy.md new file mode 100644 index 0000000000..afb774c2f8 --- /dev/null +++ b/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/5-validate-and-choose-a-quantization-strategy.md @@ -0,0 +1,40 @@ +--- +title: Inspect the graph with Model Explorer +weight: 6 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Install the Model Explorer + +{{% notice %}}If you use `.vgf` as an intermediate artifact, it helps to inspect the exported graph before you integrate it into your runtime.{{% /notice %}} + +Install and launch Model Explorer with the VGF adapter: + +```bash +pip install vgf-adapter-model-explorer +pip install torch ai-edge-model-explorer +model-explorer --extensions=vgf_adapter_model_explorer +``` + +Open the `.vgf` file from `./output/` and `./output_qat/`. + +When you review the graph, look for unexpected layout conversions (for example, extra transpose operations), operators that you did not intend to run on your GPU path, and model I/O shapes that do not match your integration. + +## Advanced: connect the model to an ML Extensions for Vulkan workflow + +The fastest way to understand the integration constraints is to start from a known-good sample and then replace the model. + +Use the Learning Path [Get started with neural graphics using ML Extensions for Vulkan](/learning-paths/mobile-graphics-and-gaming/vulkan-ml-sample/) and focus on how the sample loads and executes `.vgf` artifacts. This is where you validate assumptions about input and output tensor formats and where any required color-space or layout conversions happen. + +## Choose your quantization strategy + +You now have a complete reference workflow for quantizing an image-to-image model with TorchAO and exporting INT8 `.vgf` artifacts using the ExecuTorch Arm backend. You also have a practical baseline you can use to debug export issues before you switch to your production model and data. + +When you move from the CIFAR-10 proxy model to your own model, keep these constraints in mind: + +- Treat calibration data as part of your model contract. If PTQ quality drops, start by fixing the representativeness of calibration inputs. +- Use QAT when PTQ introduces visible artifacts or regressions that matter to your visual quality bar. +- Validate early by inspecting the exported graph so you can catch unexpected layouts, operators, or tensor shapes before runtime integration. + diff --git a/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/_index.md b/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/_index.md new file mode 100644 index 0000000000..53de7584b2 --- /dev/null +++ b/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/_index.md @@ -0,0 +1,61 @@ +--- +title: Quantize neural upscaling models with ExecuTorch + +minutes_to_complete: 60 + +who_is_this_for: This is an advanced topic for ML developers who want to reduce latency and memory bandwidth by exporting INT8 models to the `.vgf` file format using the ExecuTorch Arm backend. + +learning_objectives: + - Explain when to use post-training quantization (PTQ) vs quantization-aware training (QAT) + - Prepare and quantize a PyTorch model using TorchAO PT2E quantization APIs + - Export the quantized model to TOSA and generate a model artifact with the ExecuTorch Arm backend + - Validate the exported graph by visualizing it using Google's Model Explorer + +prerequisites: + - Basic PyTorch model training and evaluation experience + - A development machine with Python 3.10+ and PyTorch installed that runs ExecuTorch + +author: +- Richard Burton +- Annie Tallund + +### Tags +skilllevels: Advanced +subjects: ML +armips: + - Mali +tools_software_languages: + - ExecuTorch + - TorchAO + - Vulkan + - TOSA + - NX +operatingsystems: + - Linux + - macOS + - Windows + +further_reading: + - resource: + title: Get started with neural graphics using ML Extensions for Vulkan + link: /learning-paths/mobile-graphics-and-gaming/vulkan-ml-sample/ + type: learningpath + - resource: + title: Fine-tuning neural graphics models with Model Gym + link: /learning-paths/mobile-graphics-and-gaming/model-training-gym/ + type: learningpath + - resource: + title: Neural Graphics Development Kit + link: https://developer.arm.com/mobile-graphics-and-gaming/neural-graphics + type: website + - resource: + title: Arm neural technology in ExecuTorch 1.0 + link: https://developer.arm.com/community/arm-community-blogs/b/ai-blog/posts/arm-neural-technology-in-executorch-1-0 + type: website + +### FIXED, DO NOT MODIFY +# ================================================================================ +weight: 1 # _index.md always has weight of 1 to order correctly +layout: "learningpathall" # All files under learning paths have this same wrapper +learning_path_main_page: "yes" # This should be surfaced when looking for related content. Only set for _index.md of learning path content. +--- diff --git a/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/_next-steps.md b/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/_next-steps.md new file mode 100644 index 0000000000..c3db0de5a2 --- /dev/null +++ b/content/learning-paths/mobile-graphics-and-gaming/quantize-neural-upscaling-models/_next-steps.md @@ -0,0 +1,8 @@ +--- +# ================================================================================ +# FIXED, DO NOT MODIFY THIS FILE +# ================================================================================ +weight: 21 # Set to always be larger than the content in this path to be at the end of the navigation. +title: "Next Steps" # Always the same, html page title. +layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing. +--- diff --git a/content/learning-paths/servers-and-cloud-computing/_index.md b/content/learning-paths/servers-and-cloud-computing/_index.md index e034565c5f..b97d2da0d8 100644 --- a/content/learning-paths/servers-and-cloud-computing/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/_index.md @@ -254,7 +254,7 @@ tools_software_languages_filter: weight: 1 cloud_service_providers_filter: - AWS: 19 -- Google Cloud: 36 +- Google Cloud: 38 - Microsoft Azure: 19 - Oracle: 2 --- diff --git a/content/learning-paths/servers-and-cloud-computing/aks/_index.md b/content/learning-paths/servers-and-cloud-computing/aks/_index.md index dee8e374e5..1ca5be2c94 100644 --- a/content/learning-paths/servers-and-cloud-computing/aks/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/aks/_index.md @@ -18,7 +18,8 @@ author: Jason Andrews ### Tags skilllevels: Advanced subjects: Containers and Virtualization -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/arcee-foundation-model-on-aws/_index.md b/content/learning-paths/servers-and-cloud-computing/arcee-foundation-model-on-aws/_index.md index c488c35b9e..e450de9c74 100644 --- a/content/learning-paths/servers-and-cloud-computing/arcee-foundation-model-on-aws/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/arcee-foundation-model-on-aws/_index.md @@ -22,7 +22,7 @@ author: Julien Simon # Tagging metadata, see the Learning Path guide for the allowed values skilllevels: Introductory subjects: ML -arm_ips: +armips: - Neoverse tools_software_languages: - AWS diff --git a/content/learning-paths/servers-and-cloud-computing/arcee-foundation-model-on-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/arcee-foundation-model-on-gcp/_index.md index 29871105d6..a7421ff49e 100644 --- a/content/learning-paths/servers-and-cloud-computing/arcee-foundation-model-on-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/arcee-foundation-model-on-gcp/_index.md @@ -22,9 +22,10 @@ author: Julien Simon # Tagging metadata, see the Learning Path guide for the allowed values skilllevels: Introductory subjects: ML -arm_ips: +armips: - Neoverse -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud tools_software_languages: - Google Cloud - Hugging Face diff --git a/content/learning-paths/servers-and-cloud-computing/argo-cd-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/argo-cd-gcp/_index.md index f9086aff59..f56e8b386b 100644 --- a/content/learning-paths/servers-and-cloud-computing/argo-cd-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/argo-cd-gcp/_index.md @@ -25,7 +25,8 @@ author: Pareena Verma ##### Tags skilllevels: Introductory subjects: Containers and Virtualization -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/_index.md b/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/_index.md new file mode 100644 index 0000000000..0c06559bc0 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/_index.md @@ -0,0 +1,66 @@ +--- +title: Migrate applications between Arm platforms with AI assistance + +draft: true +cascade: + draft: true + +minutes_to_complete: 60 + +who_is_this_for: This learning path is for developers migrating applications between Arm platforms using using AI-assisted tooling with Kiro's ARM SoC Migration Power. You will learn a practical, repeatable migration workflow through an example that moves an application from the cloud to the edge — from AWS Graviton (Neoverse-based) to Raspberry Pi 5 (Cortex-A based). + +learning_objectives: + - Install and configure Kiro's ARM SoC Migration Power + - Understand a structured migration workflow applicable across Arm platforms + - Use AI-guided migration to identify platform-specific and hardware-dependent code + - Create Hardware Abstraction Layers with power assistance + - Validate and verify migrations with automated analysis + +prerequisites: + - Access to a source and target Arm platforms (the example uses AWS Graviton3 and Raspberry Pi 5) + - Basic understanding of C programming + - Familiarity with embedded systems, Linux environments, or cloud computing concepts + +author: Daniel Schleicher + +### Tags +skilllevels: Advanced +subjects: Performance and Architecture +armips: + - Neoverse + - Cortex-A +operatingsystems: + - Linux +tools_software_languages: + - Kiro + - AWS EC2 + - GCC + - C + - CMake + +further_reading: + - resource: + title: Kiro ARM SoC Migration Power Documentation + link: https://kiro.dev/powers/arm-soc-migration + type: documentation + - resource: + title: AWS Graviton Technical Guide + link: https://aws.amazon.com/ec2/graviton/ + type: documentation + - resource: + title: Raspberry Pi 5 Documentation + link: https://www.raspberrypi.com/documentation/ + type: documentation + - resource: + title: Arm Architecture Reference + link: https://developer.arm.com/documentation + type: documentation + - resource: + title: BCM2712 Peripherals Datasheet + link: https://datasheets.raspberrypi.com/bcm2712/bcm2712-peripherals.pdf + type: documentation + +### FIXED, DO NOT MODIFY +weight: 1 +layout: learningpathall +--- diff --git a/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/_next-steps.md b/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/_next-steps.md new file mode 100644 index 0000000000..c3db0de5a2 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/_next-steps.md @@ -0,0 +1,8 @@ +--- +# ================================================================================ +# FIXED, DO NOT MODIFY THIS FILE +# ================================================================================ +weight: 21 # Set to always be larger than the content in this path to be at the end of the navigation. +title: "Next Steps" # Always the same, html page title. +layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing. +--- diff --git a/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/graviton-development.md b/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/graviton-development.md new file mode 100644 index 0000000000..507e669274 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/graviton-development.md @@ -0,0 +1,92 @@ +--- +title: Develop on source platform +weight: 3 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Develop application on the source Arm platform +In this section, you will build and validate the application on the source Arm platform before performing any migration steps. + +This example uses AWS Graviton3 as the source platform, however the same principles apply to any Arm-Arm migration scenario (e.g., from Raspberry Pi 4 to Pi 5, from i.MX8 to Jetson, etc.). + +Your development environment (Kiro IDE) remains local. The Graviton instance acts as the remote Arm test platform. This mirrors real-world workflows where development occurs locally and deployment targets remote Arm systems. + +### Download the Application (Local Machine) + +Download the `sensor-monitor` application to your local machine (where Kiro IDE is installed). + +```bash +wget https://github.com/ArmDeveloperEcosystem/arm-learning-paths/raw/main/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/projects/sensor-monitor.tar.gz +tar -xzf sensor-monitor.tar.gz +cd sensor-monitor +``` + +The package includes the complete source code, a Makefile, and platform-specific implementations. You will analyze and migrate this code using the ARM SoC Migration Power. + +### Upload to the Graviton Instance for Testing + +Before migrating, verify that the application builds and runs correctly on the source Arm platform. + +Upload the archive to the Graviton instance: + +```bash +scp -i graviton-migration-key.pem sensor-monitor.tar.gz ec2-user@$(aws ec2 describe-instances --filters "Name=tag:Name,Values=graviton-migration-source" "Name=instance-state-name,Values=running" --query 'Reservations[0].Instances[0].PublicIpAddress' --output text):~ +``` + +### Build and Test on Graviton + +Connect to the instance: + +```bash +ssh -i graviton-migration-key.pem ec2-user@$(aws ec2 describe-instances --filters "Name=tag:Name,Values=graviton-migration-source" "Name=instance-state-name,Values=running" --query 'Reservations[0].Instances[0].PublicIpAddress' --output text) +``` + +Build the application on the Graviton instance: + +```bash +tar -xzf sensor-monitor.tar.gz +cd sensor-monitor +make +./sensor_monitor +``` +If successful, the application will compile with GCC (AArch64 target) and display simulated sensor readings. + +This confirms: + * The toolchain is functional + * The application builds cleanly on Arm64 Linux + +This state becomes your baseline reference for migration validation. + +### Application Overview + +The `sensor-monitor` application demonstrates a common embedded/edge design pattern: business logic separated from platform-specific hardware interaction. + +**Project Structure:** +``` +sensor-monitor/ +├── src/main.c # Main application logic +├── include/sensor.h # Sensor interface +├── platform/graviton/sensor_graviton.c # Graviton implementation +├── platform/rpi5/ # Target platform (created during migration) +├── Makefile # Build configuration +└── README.md # Documentation +``` + +**Key Components:** + +`src/main.c` - Main application that reads sensor data in a loop +`include/sensor.h` - Hardware abstraction interface +`platform/graviton/sensor_graviton.c` - Simulated sensor for cloud development + +## Expected Outcome + +At this stage, you should have: + - A working application running on the source Arm platform + - Simulated sensor output from the Graviton instance + - A validated baseline for functional comparison + +You are now ready to analyze the code using the ARM SoC Migration Power and begin adapting it for the target platform (Raspberry Pi 5). + +This establishes your baseline application before migration to the target platform. diff --git a/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/migration.md b/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/migration.md new file mode 100644 index 0000000000..f7a9dd6ed7 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/migration.md @@ -0,0 +1,196 @@ +--- +title: Migrate using ARM SoC Migration Power +weight: 4 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Use ARM SoC Migration Power for AI-guided migration + +In this section you will learn how to use the ARM SoC Migration Power to migrate your application between Arm-based platforms. The example demonstrates migration from: + +- **Source:** AWS Graviton3 (Neoverse-V1, Arm64 Linux, cloud deployment) +- **Target:** Raspberry Pi 5 (BCM2712, Cortex-A76, edge deployment) + +However, the workflow applies to any Arm-to-Arm migration. + +### Initiate Migration + +Open Kiro and and describe your migration clearly using the ARM SoC Migration Power. + +Example prompt: +``` +I want to use the ARM SoC Migration Power to migrate my sensor monitoring +application from AWS Graviton3 to Raspberry Pi 5 (BCM2712). The application +currently uses simulated sensors on Graviton and needs to work with real +GPIO and SPI hardware on the Pi 5. +``` + +The general pattern to use for other Arm-based platform migrations: +``` +I want to migrate my [application type] from [source ARM SoC] to [target ARM SoC]. +The application uses [source-specific features] and needs [target-specific features]. +``` +Being explicit improves the quality of the Power’s architectural reasoning. + +### Discovery Phase + +The power will prompt you for information about your platforms: + +**Example for Graviton → Raspberry Pi 5:** +``` +Source Platform: AWS Graviton3 (Neoverse-V1, cloud development) +Target Platform: Raspberry Pi 5 (BCM2712, Cortex-A76, edge deployment) +Hardware Requirements: GPIO for LEDs, SPI for temperature sensor +``` +Next, instruct the Power to analyze your codebase for platform dependencies: + +Example Prompt: +``` +Scan my codebase for Graviton-specific code that needs migration to BCM2712. +Focus on sensor interfaces and any cloud-specific assumptions. +``` + +The general pattern to use for other Arm-based platform migrations: +``` +Scan my codebase for [source platform]-specific code that needs migration to [target platform]. +Focus on [platform-specific features]. +``` +This step ensures migration is systematic rather than ad hoc. + + +### Architecture Analysis + +Now compare the architectural characteristics of the platforms. + +Example Prompt: +``` +Compare Graviton3 and BCM2712 architecture capabilities. What are the key +differences I need to handle for cloud-to-edge migration? +``` + +**Example output for Graviton → Pi 5:** +- CPU differences (Neoverse-V1 vs Cortex-A76) +- Memory constraints (cloud 64GB+ vs edge 4-8GB) +- SIMD capabilities (SVE vs NEON) +- Peripheral requirements (none vs GPIO/SPI/I2C) + +The power analyzes architecture differences for any Arm SoC pair and identifies migration challenges. + +### Design the Hardware Abstraction Layer (HAL) + +Now formalize a platform-independent interface. Ask the power to design a Hardware Abstraction Layer for your platforms: + +Example Prompt: +``` +Help me design a HAL layer that supports both Graviton (cloud mocks) and +BCM2712 (real hardware). I need GPIO and SPI abstraction. +``` + + +The general pattern to use for other Arm-based platform migrations: + +``` +Help me design a HAL layer that supports both [source platform] and [target platform]. +I need [feature] abstraction. +``` +The Power may propose a structured abstraction such as the example shown `hal/sensor.h`: + +```c +typedef struct { + int (*init)(void); + float (*read_temperature)(void); + void (*cleanup)(void); +} sensor_hal_t; + +extern const sensor_hal_t *sensor_hal; +``` + +### Implement Target Platform Support + +Now generate or refactor platform-specific code using the Power: + +Example Prompt: +``` +Help me refactor my sensor code for BCM2712 compatibility. Show me how to +implement real SPI sensor communication for the Pi 5. +``` + +The general pattern to use for other Arm-based platform migrations: +``` +Help me implement [feature] for [target platform]. Show me how to [specific requirement]. +``` + +The power will provide target platform-specific code. Example for `platform/bcm2712/sensor_bcm2712.c`: + +```c +#include "hal/spi.h" + +int sensor_init(void) { + return spi_init(0, 1000000); // SPI bus 0, 1MHz +} + +float sensor_read_temperature(void) { + uint8_t data[2]; + spi_read(data, 2); + // Convert raw SPI data to temperature + int16_t raw = (data[0] << 8) | data[1]; + return raw * 0.0625; // Typical temp sensor conversion +} + +void sensor_cleanup(void) { + spi_cleanup(); +} +``` + +### Update the Build System + +Ask the power to update your build system for multi-platform support: + +Example Prompt: +``` +Update my build system for dual Graviton/BCM2712 support with proper +platform selection and cross-compilation. +``` + +The general pattern to use for other Arm-based platform migrations: +``` +Update my build system for [source platform]/[target platform] support with proper +platform selection and cross-compilation. +``` + +The power will generate a platform-aware build configuration. Example `CMakeLists.txt`: + +```cmake +cmake_minimum_required(VERSION 3.16) +project(sensor_monitor) + +set(TARGET_PLATFORM "GRAVITON" CACHE STRING "Target Platform") +set_property(CACHE TARGET_PLATFORM PROPERTY STRINGS "GRAVITON" "BCM2712") + +# Common sources +set(COMMON_SOURCES src/main.c) + +# Platform-specific sources +if(TARGET_PLATFORM STREQUAL "GRAVITON") + set(PLATFORM_SOURCES platform/graviton/sensor_graviton.c) +elseif(TARGET_PLATFORM STREQUAL "BCM2712") + set(CMAKE_C_COMPILER aarch64-linux-gnu-gcc) + set(PLATFORM_SOURCES + platform/bcm2712/sensor_bcm2712.c + platform/bcm2712/spi_bcm2712.c) +endif() + +add_executable(sensor_monitor ${COMMON_SOURCES} ${PLATFORM_SOURCES}) +``` + +## Expected Outcome + +After completing this section, you should have used the Kiro Power to: +- Analyze architecture differences between your source and target platforms +- Design HAL interfaces that abstract platform differences +- Generate platform-specific code for both platforms +- Configure the build system for your target platform + +This workflow applies to any ARM SoC migration, not just Graviton to Raspberry Pi 5. diff --git a/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/projects/README.md b/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/projects/README.md new file mode 100644 index 0000000000..6767d0db3b --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/projects/README.md @@ -0,0 +1,32 @@ +# ARM SoC Migration Learning Path - Project Files + +This directory contains downloadable project files for the ARM SoC Migration Learning Path. + +## sensor-monitor.tar.gz + +Complete sensor monitoring application for the migration tutorial. + +**Contents:** +- Source code for sensor monitoring application +- Platform-specific implementations (Graviton and Raspberry Pi 5) +- Makefile for easy building +- Complete project structure + +**Usage on Graviton EC2:** +```bash +wget https://github.com/ArmDeveloperEcosystem/arm-learning-paths/raw/main/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/projects/sensor-monitor.tar.gz +tar -xzf sensor-monitor.tar.gz +cd sensor-monitor +make +./sensor_monitor +``` + +**What's included:** +- `src/main.c` - Main application logic +- `include/sensor.h` - Sensor hardware abstraction interface +- `platform/graviton/sensor_graviton.c` - Graviton-specific implementation +- `platform/rpi5/` - Directory for Raspberry Pi 5 target (populated during migration) +- `Makefile` - Build configuration +- `README.md` - Detailed documentation + +This pre-built package eliminates manual file creation and lets users focus on the migration workflow. diff --git a/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/projects/sensor-monitor.tar.gz b/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/projects/sensor-monitor.tar.gz new file mode 100644 index 0000000000..315a25c667 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/projects/sensor-monitor.tar.gz differ diff --git a/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/setup.md b/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/setup.md new file mode 100644 index 0000000000..8d2f76a7e6 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/setup.md @@ -0,0 +1,132 @@ +--- +title: Install ARM SoC Migration Power +weight: 2 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Install and configure Kiro's ARM SoC Migration Power + +In this section, you will install Kiro IDE, enable the Kiro ARM SoC Migration Power, and prepare the required development environment. + +Kiro runs locally on your development machine. The Migration Power uses the Arm MCP server deployed as a containerized backend (via Docker) to provide Arm-specific guidance. You will also provision an AWS Graviton3 instance to act as the source platform for the migration example. + +### Install Kiro IDE + +Kiro IDE provides AI-powered development assistance and hosts the ARM SoC Migration Power that will guide you through the migration process. + +Download and install Kiro IDE for your platform: + +**macOS:** +```bash +brew install --cask kiro +``` + +**Windows and Linux:** +Download the installer from [https://kiro.dev](https://kiro.dev) + +Launch Kiro IDE after installation completes. + +### Install the Power in Kiro + +The ARM SoC Migration Power extends Kiro with specialized knowledge and tools for migrating applications between Arm platforms. + +1. Open Kiro IDE +2. Navigate to Powers panel. Press Cmd + Shift + P (Mac) or Ctrl + Shift + P (Windows) +3. Click on the ARM SoC Migration Power in the Recommended section +4. Click Install + +### Verify Installation +After installation, test the Power by entering: "I just installed the arm-soc-migration power and want to use it." + +The Power should respond and guide you through any additional setup steps. + +It supports migrations across a wide range of Arm-based platforms, including: + * AWS Graviton (Neoverse-based servers) + * Raspberry Pi (Cortex-A) + * NVIDIA Jetson + * NXP i.MX + * Other Linux-based Arm SoCs +### Install Prerequisites + +The ARM SoC Migration Power uses the Arm MCP (Model Context Protocol) server to provide specialized Arm migration capabilities. The Arm MCP server runs via Docker. + +Install Docker on your local development machine (required for ARM MCP server): + +**macOS:** +```bash +brew install --cask docker +``` + +**Linux:** +```bash +# Ubuntu/Debian +sudo apt-get update +sudo apt-get install -y docker.io + +# Or use Docker's official installation script +curl -fsSL https://get.docker.com -o get-docker.sh +sudo sh get-docker.sh +``` + +**Windows:** +Download Docker Desktop from [https://www.docker.com/products/docker-desktop](https://www.docker.com/products/docker-desktop) + +Verify installation: +```bash +docker --version +``` + +{{% notice Note %}} +Ensure Docker is running before using the ARM SoC Migration Power. The power will automatically pull and run the ARM MCP server container when needed. +{{% /notice %}} + +### Launch AWS Graviton Instance (Source Platform) + +You will use an AWS Graviton instance as the source platform in this migration scenario. + +{{% notice Note %}} +Before proceeding, ensure you are authenticated with AWS CLI. You must have valid AWS credentials configured to create and manage EC2 instances. + +Verify your AWS CLI authentication: +```bash +aws sts get-caller-identity +``` +If you see an error or need to configure AWS CLI, follow the [AWS CLI Configuration Guide](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html) to set up your credentials. +{{% /notice %}} + +Create an SSH key, security group, and launch a `c7g.medium` Graviton3 instance: + +```bash +aws ec2 create-key-pair --key-name graviton-migration-key --query 'KeyMaterial' --output text > graviton-migration-key.pem && chmod 400 graviton-migration-key.pem && SG_ID=$(aws ec2 create-security-group --group-name graviton-migration-sg --description "Security group for ARM SoC migration" --query 'GroupId' --output text) && aws ec2 authorize-security-group-ingress --group-id $SG_ID --protocol tcp --port 22 --cidr 0.0.0.0/0 && aws ec2 run-instances --image-id $(aws ec2 describe-images --owners amazon --filters "Name=name,Values=al2023-ami-2023*-arm64" "Name=state,Values=available" --query 'reverse(sort_by(Images, &CreationDate))[0].ImageId' --output text) --instance-type c7g.medium --key-name graviton-migration-key --security-group-ids $SG_ID --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=graviton-migration-source}]' --query 'Instances[0].InstanceId' --output text +``` +Wait approximately 30 seconds for the instance to enter the running state. Retrieve the SSH command: + +```bash +echo "ssh -i graviton-migration-key.pem ec2-user@$(aws ec2 describe-instances --filters "Name=tag:Name,Values=graviton-migration-source" "Name=instance-state-name,Values=running" --query 'Reservations[0].Instances[0].PublicIpAddress' --output text)" +``` + +Copy and execute the output command to connect to your instance. + +### Install Development Tools on Graviton Instance + +The Graviton instance needs some development tools (gcc, make) to compile the sensor-monitor example application. You will also install wget and tar for downloading and extracting files. + +Once connected to your Graviton instance, install the required tools: + +```bash +sudo dnf install -y gcc make wget tar +``` + +## Expected Outcome + +After completing this section, you should have: +- Kiro IDE installed locally +- ARM SoC Migration Power installed and verified +- AWS Graviton c7g.medium instance running Amazon Linux 2023 (arm64) +- Build tools installed on the source platform +- SSH key saved locally for secure access + +You are now ready to build and test the application on the source platform before migrating it to the target edge device (Raspberry Pi 5). + diff --git a/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/validation.md b/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/validation.md new file mode 100644 index 0000000000..d9c5f230e5 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/arm-soc-migration-learning-path/validation.md @@ -0,0 +1,132 @@ +--- +title: Validate migration with testing +weight: 5 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Validate migration using the Power's testing recommendations +Migration is not complete until the application is validated on both source and target platforms. + +In this section, you will use the Arm SoC Migration Power's testing recommendations to: + +- Verify functional correctness +- Confirm platform compatibility +- Validate hardware interaction +- Compare performance characteristics + +The example shows Graviton to Raspberry Pi 5, but the validation approach applies to any Arm platform migration. + +### Source Platform Build Verification + +After introducing abstraction layers and multi-platform build support, first confirm that the original platform still behaves correctly: + +Example Prompt: +``` +Help me verify my Graviton build still works after adding BCM2712 support. +``` +The general pattern to use with other Arm-based platforms: +``` +Help me verify my [source platform] build still works after adding [target platform] support. +``` + +Follow the power's guidance. Example for Graviton: + +```bash +cmake -DTARGET_PLATFORM=GRAVITON -B build-graviton +cmake --build build-graviton +./build-graviton/sensor_monitor +``` + +### Cross-Compile for the Target Platform + +Ask the Power for cross-compilation guidance: + +Example Prompt: +``` +Guide me through cross-compiling for BCM2712 and deploying to Raspberry Pi 5. +``` + +The general pattern to use for other Arm-based platforms: +``` +Guide me through cross-compiling for [target platform] and deploying to [target device]. +``` + +Follow the Power's commands. Example for Raspberry Pi 5: + +```bash +cmake -DTARGET_PLATFORM=BCM2712 -B build-bcm2712 +cmake --build build-bcm2712 +``` +Deploy to target device: +```bash +scp build-bcm2712/sensor_monitor pi@raspberrypi5:~/ +``` + +### Target Platform Functional Testing + +Now validate behavior on the actual hardware: + +Example Prompt: +``` +What tests should I run on the Raspberry Pi 5 to validate the migration? +``` + +The general pattern to use for other Arm-based platforms: +``` +What tests should I run on [target platform] to validate the migration from [source platform]? +``` + +The power will recommend platform-appropriate tests. Example for Raspberry Pi 5: +- GPIO functionality tests +- SPI communication validation +- Real sensor reading verification +- Timing consistency checks + +Run the application on your target platform. Example: + +```bash +ssh pi@raspberrypi5 +./sensor_monitor +``` + +### Performance Comparison + +Ask the power to compare platform performance: + +Example Prompt: +``` +Compare performance between Graviton development and BCM2712 deployment. +``` + +The general pattern to use for other Arm-based platforms: +``` +Compare performance between [source platform] and [target platform] for my application. +``` + +The power will analyze platform-specific characteristics. Example analysis: +- CPU performance differences +- Memory usage comparison +- I/O timing characteristics +- Power consumption differences + +## Expected Outcome + +After completing validation, you should have: +- Validated source platform build +- Cross-compiled target platform binary +- Power-verified platform-specific tests passing +- Performance comparison report + +## Key Takeaways + +1. **AI-Assisted Migration is Powerful** - The ARM SoC Migration Power provides expert guidance for any Arm-to-Arm platform migration, with automated architecture analysis and code generation following best practices. + +2. **Abstraction Preserves Portability** - HAL layers enable development on one platform while maintaining compatibility with others. The same business logic runs across different Arm SoCs. + +3. **The Power Enforces Safety** - It preserves functional behavior during migration, validates architecture compatibility, and recommends proper testing strategies for your specific platforms. + +4. **Workflow is Universal** - Discovery → Analysis → Planning → Implementation → Validation applies to any Arm SoC migration, whether cloud-to-edge, edge-to-edge, or cloud-to-cloud. + +5. **Example is Adaptable** - While this learning path uses Graviton to Raspberry Pi 5 as an example, the same workflow applies to migrations like i.MX8 to Jetson, Raspberry Pi 4 to Pi 5, or any other ARM platform combination. diff --git a/content/learning-paths/servers-and-cloud-computing/aws-copilot/_index.md b/content/learning-paths/servers-and-cloud-computing/aws-copilot/_index.md index d4ff4814fd..c21f838581 100644 --- a/content/learning-paths/servers-and-cloud-computing/aws-copilot/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/aws-copilot/_index.md @@ -19,7 +19,8 @@ author: Jason Andrews ### Tags skilllevels: Introductory subjects: Containers and Virtualization -cloud_service_providers: AWS +cloud_service_providers: + - AWS armips: - Neoverse operatingsystems: diff --git a/content/learning-paths/servers-and-cloud-computing/aws-terraform/_index.md b/content/learning-paths/servers-and-cloud-computing/aws-terraform/_index.md index 5a8daa967b..8442eca94f 100644 --- a/content/learning-paths/servers-and-cloud-computing/aws-terraform/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/aws-terraform/_index.md @@ -19,7 +19,8 @@ author: Jason Andrews ### Tags skilllevels: Advanced subjects: Containers and Virtualization -cloud_service_providers: AWS +cloud_service_providers: + - AWS armips: - Neoverse operatingsystems: diff --git a/content/learning-paths/servers-and-cloud-computing/azure-cobalt-cicd-aks/_index.md b/content/learning-paths/servers-and-cloud-computing/azure-cobalt-cicd-aks/_index.md index 84a6b933d6..e13ff8b4bd 100644 --- a/content/learning-paths/servers-and-cloud-computing/azure-cobalt-cicd-aks/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/azure-cobalt-cicd-aks/_index.md @@ -20,7 +20,8 @@ author: Pranay Bakre ### Tags skilllevels: Advanced subjects: Containers and Virtualization -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/azure-terraform/_index.md b/content/learning-paths/servers-and-cloud-computing/azure-terraform/_index.md index f359214358..ce5f0f11fa 100644 --- a/content/learning-paths/servers-and-cloud-computing/azure-terraform/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/azure-terraform/_index.md @@ -21,7 +21,8 @@ author: Jason Andrews ### Tags skilllevels: Advanced subjects: Containers and Virtualization -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/azure-vm/_index.md b/content/learning-paths/servers-and-cloud-computing/azure-vm/_index.md index 3ee259c09d..44e168bb28 100644 --- a/content/learning-paths/servers-and-cloud-computing/azure-vm/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/azure-vm/_index.md @@ -23,7 +23,8 @@ author: Jason Andrews ### Tags skilllevels: Advanced subjects: Containers and Virtualization -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/buildkite-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/buildkite-gcp/_index.md index 4151bde30d..fcd49d593d 100644 --- a/content/learning-paths/servers-and-cloud-computing/buildkite-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/buildkite-gcp/_index.md @@ -23,7 +23,8 @@ author: Jason Andrews ##### Tags skilllevels: Introductory subjects: CI-CD -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/cassandra-on-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/cassandra-on-gcp/_index.md index d1076daa1c..bb0cbdb82f 100644 --- a/content/learning-paths/servers-and-cloud-computing/cassandra-on-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/cassandra-on-gcp/_index.md @@ -21,7 +21,8 @@ author: Pareena Verma ##### Tags skilllevels: Introductory subjects: Databases -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/circleci-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/circleci-gcp/_index.md index 0e15ee9c2f..4e40020ed4 100644 --- a/content/learning-paths/servers-and-cloud-computing/circleci-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/circleci-gcp/_index.md @@ -27,7 +27,8 @@ author: Pareena Verma ##### Tags skilllevels: Introductory subjects: CI-CD -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/circleci-on-aws/_index.md b/content/learning-paths/servers-and-cloud-computing/circleci-on-aws/_index.md index 43baf3f84d..21bfc8ca7f 100644 --- a/content/learning-paths/servers-and-cloud-computing/circleci-on-aws/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/circleci-on-aws/_index.md @@ -20,7 +20,8 @@ author: Annie Tallund ##### Tags skilllevels: Introductory subjects: CI-CD -cloud_service_providers: AWS +cloud_service_providers: + - AWS armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/clickhouse-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/clickhouse-gcp/_index.md index 18a5aa32f3..0d5cedc4ff 100644 --- a/content/learning-paths/servers-and-cloud-computing/clickhouse-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/clickhouse-gcp/_index.md @@ -25,7 +25,8 @@ author: Pareena Verma ##### Tags skilllevels: Introductory subjects: Databases -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/cobalt/_index.md b/content/learning-paths/servers-and-cloud-computing/cobalt/_index.md index 4cb83a8d31..0204ea2665 100644 --- a/content/learning-paths/servers-and-cloud-computing/cobalt/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/cobalt/_index.md @@ -21,7 +21,7 @@ author: Joe Stech # Tagging metadata, see the Learning Path guide for the allowed values skilllevels: Introductory subjects: Containers and Virtualization -arm_ips: +armips: - Neoverse tools_software_languages: - Azure Portal diff --git a/content/learning-paths/servers-and-cloud-computing/codebuild/_index.md b/content/learning-paths/servers-and-cloud-computing/codebuild/_index.md index b93162f958..60fae2cfde 100644 --- a/content/learning-paths/servers-and-cloud-computing/codebuild/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/codebuild/_index.md @@ -18,7 +18,8 @@ author: Jason Andrews ### Tags skilllevels: Advanced subjects: CI-CD -cloud_service_providers: AWS +cloud_service_providers: + - AWS armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/couchbase-on-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/couchbase-on-gcp/_index.md index d7d0f7c104..2ab5bc978e 100644 --- a/content/learning-paths/servers-and-cloud-computing/couchbase-on-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/couchbase-on-gcp/_index.md @@ -21,7 +21,8 @@ author: Pareena Verma ##### Tags skilllevels: Introductory subjects: Databases -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/django-on-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/django-on-gcp/_index.md index ff204a761a..d403165e11 100644 --- a/content/learning-paths/servers-and-cloud-computing/django-on-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/django-on-gcp/_index.md @@ -26,7 +26,8 @@ author: Pareena Verma ##### Tags skilllevels: Introductory subjects: Web -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/dlrm/_index.md b/content/learning-paths/servers-and-cloud-computing/dlrm/_index.md index 2dcdc1bec4..830e0d148b 100644 --- a/content/learning-paths/servers-and-cloud-computing/dlrm/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/dlrm/_index.md @@ -29,7 +29,8 @@ tools_software_languages: - Google Cloud operatingsystems: - Linux -cloud_service_providers: AWS +cloud_service_providers: + - AWS further_reading: - resource: diff --git a/content/learning-paths/servers-and-cloud-computing/ecs/_index.md b/content/learning-paths/servers-and-cloud-computing/ecs/_index.md index b284775ca1..d31cca8d5d 100644 --- a/content/learning-paths/servers-and-cloud-computing/ecs/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/ecs/_index.md @@ -19,7 +19,8 @@ author: Jason Andrews ##### Tags skilllevels: Introductory subjects: Containers and Virtualization -cloud_service_providers: AWS +cloud_service_providers: + - AWS armips: - Neoverse operatingsystems: diff --git a/content/learning-paths/servers-and-cloud-computing/eks-multi-arch/_index.md b/content/learning-paths/servers-and-cloud-computing/eks-multi-arch/_index.md index cefbe78204..5c88fc1474 100644 --- a/content/learning-paths/servers-and-cloud-computing/eks-multi-arch/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/eks-multi-arch/_index.md @@ -20,7 +20,8 @@ author: Pranay Bakre ### Tags skilllevels: Advanced subjects: Containers and Virtualization -cloud_service_providers: AWS +cloud_service_providers: + - AWS armips: - Neoverse tools_software_languages: diff --git a/content/learning-paths/servers-and-cloud-computing/eks/_index.md b/content/learning-paths/servers-and-cloud-computing/eks/_index.md index 4f67a04172..f5abc8c31e 100644 --- a/content/learning-paths/servers-and-cloud-computing/eks/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/eks/_index.md @@ -17,7 +17,8 @@ author: Jason Andrews ### Tags skilllevels: Introductory subjects: Containers and Virtualization -cloud_service_providers: AWS +cloud_service_providers: + - AWS armips: - Neoverse operatingsystems: diff --git a/content/learning-paths/servers-and-cloud-computing/envoy-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/envoy-gcp/_index.md index 84a5e1acc6..50015b3be6 100644 --- a/content/learning-paths/servers-and-cloud-computing/envoy-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/envoy-gcp/_index.md @@ -21,7 +21,8 @@ author: Pareena Verma ##### Tags skilllevels: Introductory subjects: Web -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/fastpath/_index.md b/content/learning-paths/servers-and-cloud-computing/fastpath/_index.md index 8df7e0b92e..a258475132 100644 --- a/content/learning-paths/servers-and-cloud-computing/fastpath/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/fastpath/_index.md @@ -1,11 +1,7 @@ --- -title: Benchmark on Arm servers with different Linux kernels using Fastpath +title: Benchmark Linux kernel performance on Arm servers with Fastpath -draft: true -cascade: - draft: true - -minutes_to_complete: 45 +minutes_to_complete: 90 who_is_this_for: This is an advanced topic for software developers and performance engineers who want to benchmark and compare different Linux kernel versions on Arm servers. @@ -24,6 +20,8 @@ author: Geremy Cohen ### Tags skilllevels: Advanced subjects: Performance and Architecture +cloud_service_providers: + - AWS armips: - Neoverse operatingsystems: diff --git a/content/learning-paths/servers-and-cloud-computing/fastpath/analyze_benchmark_results.md b/content/learning-paths/servers-and-cloud-computing/fastpath/analyze_benchmark_results.md index e08eaa4016..80d4d1d19d 100644 --- a/content/learning-paths/servers-and-cloud-computing/fastpath/analyze_benchmark_results.md +++ b/content/learning-paths/servers-and-cloud-computing/fastpath/analyze_benchmark_results.md @@ -107,8 +107,44 @@ The output is similar to: | speedometer/v2.1 | score (runs/min) | 221.00 | 3.39% | +------------------+--------------------+-----------------------+---------------------+ ``` -We see 6.18.1 is performing slightly better than 6.19-rc1 in this benchmark. +The results show that 6.18.1 performs slightly better than 6.19-rc1 in this benchmark, with a 3.39% improvement. More examples of analyzing results can be found in the [Fastpath Results User Guide](https://fastpath.docs.arm.com/en/latest/user-guide/resultshow.html). -When you're done testing, remember to terminate your EC2 instances and clean up any other AWS resources you created to avoid unnecessary charges. +## Clean up resources + +When you're done testing, clean up your AWS resources to avoid unnecessary charges. + +### Terminate EC2 instances + +You can terminate instances from the AWS Console or using the AWS CLI: + +```console +aws ec2 terminate-instances --instance-ids +``` + +Replace `` with the IDs of your build host, Fastpath host, and SUT instances. + +### Delete CloudFormation stacks (if used) + +If you used CloudFormation templates, delete the stacks: + +```console +aws cloudformation delete-stack --stack-name fastpath-build +aws cloudformation delete-stack --stack-name fastpath-host +aws cloudformation delete-stack --stack-name fastpath-sut +``` + +### Remove security groups and other resources + +After the instances are terminated, remove any custom security groups, key pairs, or other resources you created specifically for this Learning Path. + +## What you've accomplished and what's next + +In this section, you: +- Analyzed benchmark results using Fastpath's result commands +- Compared kernel performance metrics between multiple versions +- Identified performance differences between v6.18.1 and v6.19-rc1 kernels +- Cleaned up AWS resources to avoid unnecessary charges + +You now have a complete workflow for building custom kernels, deploying them to test systems, and comparing their performance using Fastpath. You can use this approach to test kernel patches, configuration changes, or different kernel versions for your specific workloads. To continue exploring, consider testing different benchmarks from the Fastpath library, experimenting with kernel configuration options, or comparing performance across different instance types. diff --git a/content/learning-paths/servers-and-cloud-computing/fastpath/build_setup.md b/content/learning-paths/servers-and-cloud-computing/fastpath/build_setup.md index 6b2a92ef2e..25aa7824a0 100644 --- a/content/learning-paths/servers-and-cloud-computing/fastpath/build_setup.md +++ b/content/learning-paths/servers-and-cloud-computing/fastpath/build_setup.md @@ -8,7 +8,7 @@ layout: "learningpathall" ## Provision the kernel build host -CPU-optimized instances compile kernels quickly, so in our example, an AWS Graviton `m6g.12xlarge` instance is used. It will be referred to as the kernel build host throughout the rest of the guide. +CPU-optimized instances compile kernels quickly. In this example, a Graviton `m6g.12xlarge` instance is used. It will be referred to as the kernel build host throughout the rest of the guide. {{% notice Note %}} The following steps involve launching an EC2 instance. You can perform all EC2 instance creation steps using the AWS Management Console or AWS CLI. For step-by-step instructions to bring up an EC2 instance using the console, see [Get started with Arm-based cloud instances](/learning-paths/servers-and-cloud-computing/csp/) or the AWS tutorial [Get started with Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_GetStarted.html). @@ -16,16 +16,16 @@ The following steps involve launching an EC2 instance. You can perform all EC2 i Create the kernel build host with the following specifications: -1. **Name** — fastpath-build -2. **Operating system** — Ubuntu -3. **AMI** — Ubuntu 24.04 LTS (Arm) -4. **Architecture** — 64-bit Arm -5. **Instance type** — `m6g.12xlarge` -6. **Key pair** — Select or create a key for SSH -7. **Security group** — Allow SSH inbound from your IP and cluster peers -8. **Storage** — 200 GB gp3 +- **Name** - fastpath-build +- **Operating system** - Ubuntu +- **AMI** - Ubuntu 24.04 LTS (Arm) +- **Architecture** - 64-bit Arm +- **Instance type** - `m6g.12xlarge` +- **Key pair** - select or create a key for SSH +- **Security group** - allow SSH inbound from your IP and cluster peers +- **Storage** - 200 GB gp3 -There are many different ways to create this instance, and a few different methods are demonstrated below. Choose the method that suits you best. +Choose the method that suits you best to create this instance: {{< tabpane >}} {{< tab header="AWS Console" img_src="/learning-paths/servers-and-cloud-computing/fastpath/images/ec2_setup.png">}} @@ -162,13 +162,13 @@ EOF When the instance reports a `running` state, note the public and private IP addresses as BUILD_PUBLIC_IP and BUILD_PRIVATE_IP. You'll need these values later. -## Clone the Kernel Build repository on the build host +## Clone the kernel build repository on the build host The kernel build repository contains build scripts and configuration files to compile kernels. To clone the repository, first, SSH into the `m6g.12xlarge` host using the configured key pair. -For more background, refer to the [Install required dependencies](/learning-paths/servers-and-cloud-computing/kernel-build/how-to-1/#install-required-dependencies) of the kernel build Learning Path. +For more information, see the section [Install required dependencies](/learning-paths/servers-and-cloud-computing/kernel-build/how-to-1/#install-required-dependencies) in this Learning Path. Run the commands from that section on the build host. @@ -180,7 +180,7 @@ cd ~/arm_kernel_install_guide chmod +x scripts/*.sh ``` -## Building with the kernel build utility script +## Build with the kernel build utility script With the repository cloned, you can now produce kernels with Fastpath support. @@ -218,7 +218,7 @@ On the build host, navigate to the `arm_kernel_install_guide` folder you just cl cd ~/arm_kernel_install_guide ``` -Open the [Custom tags with Fastpath enabled](/learning-paths/servers-and-cloud-computing/kernel-build/how-to-3/#build-custom-tags-with-fastpath-enabled) section from the Learning Path, and follow the instructions to run the build script. +Open the [Custom tags with Fastpath enabled](/learning-paths/servers-and-cloud-computing/kernel-build/how-to-3/#build-custom-tags-with-fastpath-enabled) section from this Learning Path, and follow the instructions to run the build script. ```console ./scripts/kernel_build_and_install.sh --tags v6.18.1,v6.19-rc1 --fastpath true @@ -251,3 +251,12 @@ The script builds two kernel images. This process may take some time. On a `m6g. Monitor the console output for the `BUILD COMPLETE` message. Once finished, you're ready to move on to the next step, where you prepare the Fastpath host. + +## What you've accomplished and what's next + +In this section, you: +- Provisioned a high-performance Graviton build host +- Installed kernel build dependencies and utility scripts +- Compiled two Fastpath-enabled kernels (v6.18.1 and v6.19-rc1) using tuxmake + +Next, you'll set up the Fastpath host to orchestrate the benchmarking workflow and copy the compiled kernels for testing. diff --git a/content/learning-paths/servers-and-cloud-computing/fastpath/fastpath_setup.md b/content/learning-paths/servers-and-cloud-computing/fastpath/fastpath_setup.md index 2a0de92955..c43a5febf2 100644 --- a/content/learning-paths/servers-and-cloud-computing/fastpath/fastpath_setup.md +++ b/content/learning-paths/servers-and-cloud-computing/fastpath/fastpath_setup.md @@ -241,3 +241,12 @@ source ~/venv/bin/activate ``` With the Fastpath host configured, you're now ready to provision the system under test (SUT) and verify connectivity between them. + +## What you've accomplished and what's next + +In this section, you: +- Provisioned the Fastpath host instance +- Copied compiled kernel artifacts from the build host +- Installed and configured the Fastpath software and Python virtual environment + +Next, you'll provision and configure the System Under Test (SUT) where the benchmark workloads will run. diff --git a/content/learning-paths/servers-and-cloud-computing/fastpath/generate_and_execute_plan.md b/content/learning-paths/servers-and-cloud-computing/fastpath/generate_and_execute_plan.md index 6f7b168e6b..795852f381 100644 --- a/content/learning-paths/servers-and-cloud-computing/fastpath/generate_and_execute_plan.md +++ b/content/learning-paths/servers-and-cloud-computing/fastpath/generate_and_execute_plan.md @@ -5,7 +5,9 @@ weight: 11 layout: "learningpathall" --- -With all required components in place, it's time to generate a Fastpath benchmark plan, execute it, and analyze the results. +## Generate and execute your Fastpath benchmark plan + +With all required components in place, you're ready to generate a Fastpath benchmark plan, execute it, and analyze the results to compare kernel performance. ## Generate the Fastpath plan @@ -121,3 +123,12 @@ The solution is to use the `--append` parameter at the end of the `fastpath plan When the execution completes 100%, Fastpath will have run the Speedometer benchmark against both kernels on the SUT and stored the results in the specified output directory. In the next section, you'll learn how to analyze and compare the results. + +## What you've accomplished and what's next + +In this section, you: +- Generated a Fastpath benchmark plan with two kernel profiles +- Reviewed the plan structure and configuration options +- Executed the Fastpath plan to run Speedometer benchmarks on both kernels + +Next, you'll analyze the benchmark results to compare kernel performance. diff --git a/content/learning-paths/servers-and-cloud-computing/fastpath/intro.md b/content/learning-paths/servers-and-cloud-computing/fastpath/intro.md index 32a4b3d521..15e325a242 100644 --- a/content/learning-paths/servers-and-cloud-computing/fastpath/intro.md +++ b/content/learning-paths/servers-and-cloud-computing/fastpath/intro.md @@ -1,14 +1,14 @@ --- -title: "Overview of the Fastpath benchmarking workflow" +title: "Understand the Fastpath kernel benchmarking workflow" weight: 2 layout: "learningpathall" --- -## Overview +## The kernel testing challenge -Building custom Linux kernels lets you experiment with new features, patches, or flags without waiting for official Linux distro update availability. Building the kernel is only half the battle. You also need to deploy, run, and compare results across kernels and benchmarks to understand how the code impacts your workloads. +Building custom Linux kernels gives you the flexibility to experiment with new features, patches, or performance flags without waiting for official Linux distribution updates. However, building the kernel is only the first step. You also need to deploy, run, and compare results across multiple kernels and benchmarks to understand how your code changes impact real workloads on Arm systems. This Learning Path shows you how to implement this end-to-end workflow for building, configuring, and running benchmarks using [Fastpath](https://fastpath.docs.arm.com/en/latest/index.html) on Arm Linux systems. @@ -20,7 +20,7 @@ If you want to learn more about building Linux kernels for Arm systems, see the The following diagram shows how the three machines you'll create work together: -![Sequence diagram showing the interaction between the Build Host, Fastpath Host, and System Under Test (SUT) during the kernel benchmarking workflow. The Build Host compiles kernels, the Fastpath Host orchestrates the process, and the SUT runs the benchmarks.#center](images/sequence_diagram_fastpath_dark.png) +![Sequence diagram showing the interaction between the Build Host, Fastpath Host, and System Under Test (SUT) during the kernel benchmarking workflow. The Build Host compiles kernels using tuxmake, the Fastpath Host orchestrates benchmarking tasks and aggregates results, and the SUT runs benchmark workloads. Arrows indicate kernel artifacts flowing from Build Host to Fastpath Host, and benchmark commands flowing from Fastpath Host to SUT, with results returning to Fastpath Host.alt-txt#center](images/sequence_diagram_fastpath_dark.png "Fastpath benchmarking workflow: three-machine architecture diagram") ### Kernel build host diff --git a/content/learning-paths/servers-and-cloud-computing/fastpath/sut_setup.md b/content/learning-paths/servers-and-cloud-computing/fastpath/sut_setup.md index 53c3736ff2..18a5665e78 100644 --- a/content/learning-paths/servers-and-cloud-computing/fastpath/sut_setup.md +++ b/content/learning-paths/servers-and-cloud-computing/fastpath/sut_setup.md @@ -5,7 +5,16 @@ weight: 10 layout: "learningpathall" --- -Now that kernels are built and the Fastpath host is ready, it's time to set up the system under test (SUT). + +## System Under Test prerequisites and instance requirements + + +Now that kernels are built and the Fastpath host is ready, you'll set up the System Under Test (SUT)—the machine where benchmarks run on each kernel. + +The SUT is a Graviton instance running Ubuntu 24.04 LTS. Fastpath installs your kernels on this machine one at a time, runs benchmarks, and then compares results. An `m6g.12xlarge` instance provides a good balance of CPU and memory for realistic test workloads. + +In this section, you'll provision the SUT, configure it with the Fastpath software and user account, and validate connectivity from the Fastpath host. + ## Provision the SUT @@ -178,10 +187,7 @@ When the instance reports a `running` state, note the public and private IP addr ## Configure the SUT from the Fastpath host Run a script that remotely installs the Fastpath software and the required `fpuser` system account. It also sets up SSH access for the new `fpuser` account by copying over ubuntu@SUT's `~/.ssh/authorized_keys` file. - -{{% notice Note %}} -When communicating from the Fastpath host to the SUT, use the SUT's private IP address. This allows for much faster communication and file transfer. -{{% /notice %}} +{{% notice Note %}}When communicating from the Fastpath host to the SUT, use the SUT's private IP address. This ensures faster communication and file transfer between the two instances.{{% /notice %}} SSH into the Fastpath host if you aren't already there. Use agent forwarding with the `-A` flag and replace the private key `.pem` file with your key. @@ -240,3 +246,12 @@ SW: A successful run prints hardware details for the SUT. If the command fails, verify security group rules and rerun the configuration script. If you can SSH into the SUT as `fpuser`, but the fingerprint command still fails, ensure that `docker.io` is installed on the SUT. With the SUT now configured, you're ready to move on to the next step: setting up and running a Fastpath benchmark! Remember to stop (but not terminate) the build host so that kernel artifacts remain available, and stop any Fastpath/SUT instances when you're finished testing to avoid unnecessary spend. + +## What you've accomplished and what's next + +In this section, you: +- Provisioned the System Under Test (SUT) instance +- Configured the SUT with Docker and the Fastpath user account +- Validated connectivity between the Fastpath host and the SUT + +Next, you'll generate a benchmark plan and execute Fastpath to test the kernels you built earlier. diff --git a/content/learning-paths/servers-and-cloud-computing/flink-on-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/flink-on-gcp/_index.md index 4c59b0226e..8c6024c877 100644 --- a/content/learning-paths/servers-and-cloud-computing/flink-on-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/flink-on-gcp/_index.md @@ -20,7 +20,8 @@ author: Pareena Verma ##### Tags skilllevels: Introductory subjects: Performance and Architecture -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/flink/_index.md b/content/learning-paths/servers-and-cloud-computing/flink/_index.md index c872e5ab76..60fb075c45 100644 --- a/content/learning-paths/servers-and-cloud-computing/flink/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/flink/_index.md @@ -18,7 +18,8 @@ author: Ying Yu ### Tags skilllevels: Introductory subjects: Databases -cloud_service_providers: AWS +cloud_service_providers: + - AWS armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/from-iot-to-the-cloud-part1/_index.md b/content/learning-paths/servers-and-cloud-computing/from-iot-to-the-cloud-part1/_index.md index 8c0541c90a..93e472082e 100644 --- a/content/learning-paths/servers-and-cloud-computing/from-iot-to-the-cloud-part1/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/from-iot-to-the-cloud-part1/_index.md @@ -25,7 +25,8 @@ author: Dawid Borycki ### Tags skilllevels: Introductory subjects: Containers and Virtualization -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/from-iot-to-the-cloud-part2/_index.md b/content/learning-paths/servers-and-cloud-computing/from-iot-to-the-cloud-part2/_index.md index d2cc8ef761..9da6242607 100644 --- a/content/learning-paths/servers-and-cloud-computing/from-iot-to-the-cloud-part2/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/from-iot-to-the-cloud-part2/_index.md @@ -19,7 +19,8 @@ author: Dawid Borycki ### Tags skilllevels: Introductory subjects: Containers and Virtualization -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/from-iot-to-the-cloud-part3/_index.md b/content/learning-paths/servers-and-cloud-computing/from-iot-to-the-cloud-part3/_index.md index 3de3200faf..49394ccef1 100644 --- a/content/learning-paths/servers-and-cloud-computing/from-iot-to-the-cloud-part3/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/from-iot-to-the-cloud-part3/_index.md @@ -18,7 +18,8 @@ author: Dawid Borycki ### Tags skilllevels: Introductory subjects: Containers and Virtualization -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/from-iot-to-the-cloud-part4/_index.md b/content/learning-paths/servers-and-cloud-computing/from-iot-to-the-cloud-part4/_index.md index 6b0fafffa2..f7889a50fa 100644 --- a/content/learning-paths/servers-and-cloud-computing/from-iot-to-the-cloud-part4/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/from-iot-to-the-cloud-part4/_index.md @@ -22,7 +22,8 @@ author: Dawid Borycki ### Tags skilllevels: Introductory subjects: Containers and Virtualization -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/gardener-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/gardener-gcp/_index.md index 3bf3aa1254..046c675fd8 100644 --- a/content/learning-paths/servers-and-cloud-computing/gardener-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/gardener-gcp/_index.md @@ -22,7 +22,8 @@ author: Pareena Verma ##### Tags skilllevels: Introductory subjects: Containers and Virtualization -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/gcc-lto/_index.md b/content/learning-paths/servers-and-cloud-computing/gcc-lto/_index.md index 09c550c5c1..af0dc511b4 100644 --- a/content/learning-paths/servers-and-cloud-computing/gcc-lto/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/gcc-lto/_index.md @@ -1,21 +1,19 @@ --- title: Optimize performance using Link-Time Optimization with GCC -draft: true -cascade: - draft: true minutes_to_complete: 15 who_is_this_for: This is an introductory topic for developers who want to improve application performance using link-time optimization (LTO) with the GCC toolchain. learning_objectives: - - Learn how link-time optimization works and when to use it + - Understand how link-time optimization (LTO) works and when to apply it - Enable and configure LTO with GCC compiler flags - - Understand the performance and code size trade-offs of LTO + - Evaluate the performance and code size trade-offs of LTO prerequisites: - - A recent version of the GCC toolchain + - An Arm Linux system (cloud instance, on-premises hardware, or a virtual machine) + - A recent version of the [GCC toolchain](/install-guides/gcc/) author: Victor Do Nascimento diff --git a/content/learning-paths/servers-and-cloud-computing/gcc-lto/background.md b/content/learning-paths/servers-and-cloud-computing/gcc-lto/background.md index c57f3f6dde..2f43937e74 100644 --- a/content/learning-paths/servers-and-cloud-computing/gcc-lto/background.md +++ b/content/learning-paths/servers-and-cloud-computing/gcc-lto/background.md @@ -20,6 +20,7 @@ Functions that aren't visible outside the translation unit where they're defined Between these two extremes are functions that are used across multiple translation units within a program, but whose complete usage becomes known only when the final executable is produced. These cases are where link-time optimization (LTO) is most effective, as it allows the compiler to analyze the whole program as a single unit and apply optimizations that would otherwise be unavailable. ### Link-Time Optimization and Intermediate Code Representation + Under normal compilation, once a translation unit has been processed, GCC emits an object file (.o). This object file contains machine code for the translation unit, along with relocation information, symbol metadata, and data required for linking. At this stage, the compiler has already committed to specific instruction sequences and discarded most of its internal analysis state. By committing early to machine code, the compiler significantly limits its ability to perform optimizations that depend on cross-file visibility when the linker combines object files into a final executable. @@ -27,3 +28,9 @@ By committing early to machine code, the compiler significantly limits its abili When link-time optimization (LTO) is enabled, GCC changes this behavior. Instead of discarding its internal representation after compilation, GCC preserves an intermediate representation of the program. Specifically, GCC serializes its GIMPLE intermediate representation—a language-independent tree-based representation used internally by GCC—into a bytecode format and embeds it into special sections of the object file. At link time, the compiler is invoked again, this time acting as an LTO-aware front end that reads the GIMPLE bytecode from all participating object files. With visibility into the entire program, GCC can perform whole-program optimizations, such as aggressive function inlining and interprocedural constant propagation, before generating the final machine code. + +## What you've accomplished and what's next + +You now understand how compiler optimizations differ in scope and why traditional compilation limits cross-file optimization opportunities. You also learned how LTO preserves intermediate representations at compile time to enable whole-program analysis at link time. + +Next, you'll learn the practical steps to enable LTO in your builds. diff --git a/content/learning-paths/servers-and-cloud-computing/gcc-lto/performance-uplift.md b/content/learning-paths/servers-and-cloud-computing/gcc-lto/performance-uplift.md index ebcc417c3d..13ed360f6f 100644 --- a/content/learning-paths/servers-and-cloud-computing/gcc-lto/performance-uplift.md +++ b/content/learning-paths/servers-and-cloud-computing/gcc-lto/performance-uplift.md @@ -6,49 +6,58 @@ weight: 4 layout: learningpathall --- -## Comparing Performance +## Compare performance -The potential benefits of link-time optimization can be illustrated through a performance comparison using the [SPEC CPU®2017](https://www.spec.org/cpu2017/) integer rate (SPECint2017 rate) benchmark suite. SPEC CPU is an industry-standard benchmark widely used by CPU vendors and compiler teams to evaluate and compare performance. While these benchmarks don't necessarily reflect the characteristics of every real-world application, they provide a standardized way to measure optimization impact across different configurations. +Link-time optimization delivers measurable improvements across a range of workloads. The [SPEC CPU®2017](https://www.spec.org/cpu2017/) integer rate (SPECint2017 rate) benchmark suite provides a standardized way to measure these gains. SPEC CPU is an industry-standard benchmark widely used by CPU vendors and compiler teams to evaluate and compare performance. While these benchmarks don't necessarily reflect the characteristics of every real-world application, they illustrate LTO's potential impact across different optimization patterns. -In this example, benchmarks were compiled with GCC 15.1, with and without LTO, and executed on an Arm Neoverse V2 CPU running Ubuntu 20.04 LTS. +In this example, we compiled the benchmarks with GCC 15.1, with and without LTO, and executed them on an Arm Neoverse V2 CPU running Ubuntu 20.04 LTS. Common optimization flags between runs were as follows: -```c +```bash -mcpu=native -Ofast -fomit-frame-pointer --param ipa-cp-eval-threshold=1 --param ipa-cp-unit-growth=80 ``` Across the benchmark suite, enabling LTO resulted in an improvement in the geometric mean score of approximately 3.4%. Some workloads benefited more noticeably: - * `mcf` (+11%) - * `deepsjeng` (+9.9%) - * `leela` (+6.6%) + +- `mcf` (+11%) +- `deepsjeng` (+9.9%) +- `leela` (+6.6%) These results highlight how workloads with significant cross-module interaction—particularly those with many function calls across translation units—benefit from the additional whole-program visibility provided by LTO. -![SPECint LTO performance gains#center](specint_lto_improv.png "Figure 1. Performance uplift to Specint2017") +![Bar chart showing percentage performance improvements across SPEC CPU 2017 integer benchmarks with LTO enabled, displaying improvements ranging from near zero to 11 percent, with mcf showing the highest gain at 11 percent, deepsjeng at 9.9 percent, and leela at 6.6 percent alt-txt#center](specint_lto_improv.png "Performance uplift to Specint2017") -### Code Size Considerations +### Code size considerations While performance improvements are often the primary motivation for enabling LTO, its impact isn't limited to execution speed. Link-time optimization can also significantly affect the final code size of an executable, with results varying depending on the application's structure. -As shown in Figure 2, LTO can have considerable impact on the final code size of the resulting executable, with some benchmarks showing reductions and others showing increases. +As shown in the chart above, LTO's impact on code size varies across different benchmarks. Some applications experience modest reductions (up to 10%), while others see increases of 15% or more. The variation reflects the balance between dead code elimination and aggressive optimizations like inlining and loop unrolling. + -![SPECint LTO code size reduction#center](specint_lto_size.png "Figure 2. Code size reduction to Specint2017") +![Bar chart displaying code size changes as percentages across SPEC CPU 2017 integer benchmarks with LTO enabled, showing both positive increases and negative reductions in binary size, with most benchmarks exhibiting modest changes between minus 10 and plus 15 percent alt-txt#center](specint_lto_size.png "Code size reduction to Specint2017") -#### Potential Code Size Reduction +#### Potential code size reduction One common source of code size reduction with LTO is cross-translation-unit dead code elimination. With whole-program visibility, the compiler determines whether non-`static` functions or global variables are ever referenced anywhere in the final executable. -Without LTO, such symbols must be retained conservatively because they may be referenced by other translation units during linking. With LTO enabled, the compiler makes a definitive decision and eliminates unused functions and variables, reducing the size of the resulting binary. This is particularly effective for libraries where only a subset of the exported functions are actually used by the application. +Without LTO, such symbols must be retained conservatively because they may be referenced by other translation units during linking. With LTO enabled, the compiler makes a definitive decision and eliminates unused functions and variables, reducing the size of the resulting binary. This approach is particularly effective for libraries where only a subset of the exported functions are actually used by the application. -#### Potential Code Size Increase +#### Potential code size increase While global visibility often enables code size reductions, some LTO-driven optimizations lead to larger binaries when they're deemed profitable for performance. Examples include: - * Aggressive loop unrolling when iteration counts are known in specific call paths - * Increased function inlining when call relationships are well understood + +- Aggressive loop unrolling when iteration counts are known in specific call paths +- Increased function inlining when call relationships are well understood LTO also enables function cloning (also called function specialization). When a function exhibits multiple common usage patterns, the compiler may generate specialized versions optimized for frequent cases, while retaining a generic version for less common ones. Although this approach preserves correctness and improves performance for hot paths, it introduces code duplication and increases overall binary size. -These trade-offs reflect the compiler's cost model, which balances performance gains against code size growth. The net effect depends heavily on the application's structure. For performance-critical applications, the speed improvements typically outweigh the code size increase. +These trade-offs reflect the compiler's cost model, which balances performance gains against code size growth. The net effect depends heavily on the application's structure. For performance-critical applications, the speed improvements typically outweigh the code size increase. + +## What you've accomplished and what's next + +You've examined concrete performance data showing LTO's impact on SPEC CPU 2017 benchmarks, with gains ranging from modest improvements to double-digit percentage increases for workloads with significant cross-module interaction. You've also learned how LTO affects binary size through dead code elimination, aggressive inlining, and function specialization. + +You're now ready to apply LTO to your own applications. Start with `-flto -O2` on a test build, measure the results, and adjust configuration options based on your specific performance and binary size requirements. diff --git a/content/learning-paths/servers-and-cloud-computing/gcc-lto/request-lto.md b/content/learning-paths/servers-and-cloud-computing/gcc-lto/request-lto.md index 4025bc5c76..65dd5760af 100644 --- a/content/learning-paths/servers-and-cloud-computing/gcc-lto/request-lto.md +++ b/content/learning-paths/servers-and-cloud-computing/gcc-lto/request-lto.md @@ -6,10 +6,11 @@ weight: 3 layout: learningpathall --- -## Deploying LTO +## Deploy LTO -### A Simple Use Case -You can enable link-time optimization with GCC by passing the `-flto` flag during both compilation and linking. +### A simple use case + +Enable link-time optimization with GCC by passing the `-flto` flag during both compilation and linking. For a traditional, stepwise build of an executable, compile each translation unit with LTO enabled: ```bash @@ -25,18 +26,22 @@ gcc -o myprog -flto -O2 component-1.c component-2.c ``` Both approaches produce an executable that benefits from link-time optimization across all translation units. The `-O2` optimization level is recommended as a baseline, though you can also use `-O3` for more aggressive optimizations. -### Modifying LTO behaviour +### Modify LTO behavior + #### Flexible object files When compiling with `-flto`, GCC normally emits **slim LTO objects**. These object files contain only GCC's internal intermediate representation (GIMPLE bytecode) and no conventional machine code. As a result, they can only be linked by an LTO-capable linker invocation. For libraries intended for broader reuse—or when you need compatibility with non-LTO builds—you can retain conventional object code alongside the LTO data using the `-ffat-lto-objects` flag: + ```bash gcc -c -O2 -flto -ffat-lto-objects component-1.c ``` + With this option enabled, GCC emits both: - * The intermediate representation used for LTO - * The non-LTO object code that would normally be produced + +- The intermediate representation used for LTO +- The non-LTO object code that would normally be produced Fat LTO objects provide greater compatibility at the cost of increased object file size (typically 1.5-2x larger). Use this option when building static or shared libraries that might be linked without LTO. @@ -45,8 +50,8 @@ Link-time optimization can be computationally expensive, especially for larger p Control this behavior through the `-flto` flag: - * `-flto=auto` enables automatic parallelization based on available system resources - * `-flto=` explicitly specifies the number of parallel LTO jobs to run +- `-flto=auto` enables automatic parallelization based on available system resources +- `-flto=` explicitly specifies the number of parallel LTO jobs to run For example: ```bash @@ -58,7 +63,15 @@ When parallelization is enabled, GCC partitions the program into multiple units During iterative development, repeatedly recompiling with LTO can increase build times. GCC provides support for caching intermediate LTO results to speed up incremental builds by reusing previously computed optimization information. Enable this using the `-flto-incremental=` option: + ```bash gcc -O2 -flto -flto-incremental=lto-cache -c component-1.c ``` + When enabled, GCC stores intermediate optimization results in the specified directory. Subsequent builds reuse previous work where possible, significantly reducing edit–compile cycle times. The cache directory grows over time, so you may need to clean it periodically during development. + +## What you've accomplished and what's next + +You've learned how to enable LTO with the `-flto` flag for both simple and complex build scenarios. You can now configure LTO behavior using fat objects for compatibility, parallelize LTO jobs to speed up builds, and cache intermediate results during development. + +Next, you'll see concrete performance and code size results from enabling LTO on industry-standard benchmarks. diff --git a/content/learning-paths/servers-and-cloud-computing/gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/gcp/_index.md index 47ad8446ac..b748e62cf9 100644 --- a/content/learning-paths/servers-and-cloud-computing/gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/gcp/_index.md @@ -20,7 +20,8 @@ author: Jason Andrews ##### Tags skilllevels: Introductory subjects: Containers and Virtualization -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/github-actions-runner/_index.md b/content/learning-paths/servers-and-cloud-computing/github-actions-runner/_index.md index 5cff9c2d36..aac1936324 100644 --- a/content/learning-paths/servers-and-cloud-computing/github-actions-runner/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/github-actions-runner/_index.md @@ -18,7 +18,8 @@ author: Cyril Rohr ##### Tags skilllevels: Introductory subjects: CI-CD -cloud_service_providers: AWS +cloud_service_providers: + - AWS armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/github-on-arm/_index.md b/content/learning-paths/servers-and-cloud-computing/github-on-arm/_index.md index b2208286d1..53779ec455 100644 --- a/content/learning-paths/servers-and-cloud-computing/github-on-arm/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/github-on-arm/_index.md @@ -19,7 +19,8 @@ author: Annie Tallund ##### Tags skilllevels: Introductory subjects: CI-CD -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/gke-multi-arch/_index.md b/content/learning-paths/servers-and-cloud-computing/gke-multi-arch/_index.md index 40d04d4d5b..34f6d6c6bc 100644 --- a/content/learning-paths/servers-and-cloud-computing/gke-multi-arch/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/gke-multi-arch/_index.md @@ -21,7 +21,8 @@ author: Pranay Bakre ### Tags skilllevels: Advanced subjects: Containers and Virtualization -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/gke/_index.md b/content/learning-paths/servers-and-cloud-computing/gke/_index.md index 27999c198a..e06f9caee4 100644 --- a/content/learning-paths/servers-and-cloud-computing/gke/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/gke/_index.md @@ -17,7 +17,8 @@ author: Jason Andrews ##### Tags skilllevels: Advanced subjects: Containers and Virtualization -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/go-benchmarking-with-sweet/_index.md b/content/learning-paths/servers-and-cloud-computing/go-benchmarking-with-sweet/_index.md index 4d708ab03c..7ee9536e84 100644 --- a/content/learning-paths/servers-and-cloud-computing/go-benchmarking-with-sweet/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/go-benchmarking-with-sweet/_index.md @@ -21,7 +21,8 @@ skilllevels: Introductory subjects: Performance and Architecture armips: - Neoverse -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud tools_software_languages: - Go operatingsystems: diff --git a/content/learning-paths/servers-and-cloud-computing/golang-on-azure/_index.md b/content/learning-paths/servers-and-cloud-computing/golang-on-azure/_index.md index 4138b2819c..a549894369 100644 --- a/content/learning-paths/servers-and-cloud-computing/golang-on-azure/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/golang-on-azure/_index.md @@ -20,7 +20,8 @@ author: Pareena Verma ### Tags skilllevels: Introductory subjects: Performance and Architecture -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/helm-on-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/helm-on-gcp/_index.md index 0e02269ff4..a741b3046a 100644 --- a/content/learning-paths/servers-and-cloud-computing/helm-on-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/helm-on-gcp/_index.md @@ -26,7 +26,8 @@ author: Pareena Verma ##### Tags skilllevels: Introductory subjects: Containers and Virtualization -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/java-on-axion/_index.md b/content/learning-paths/servers-and-cloud-computing/java-on-axion/_index.md index 7cce91f9a0..098cf6fc3a 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-on-axion/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/java-on-axion/_index.md @@ -18,7 +18,8 @@ author: Joe Stech ### Tags skilllevels: Introductory -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud subjects: Performance and Architecture armips: - Neoverse V2 diff --git a/content/learning-paths/servers-and-cloud-computing/java-on-azure/_index.md b/content/learning-paths/servers-and-cloud-computing/java-on-azure/_index.md index 245237dd5f..c8ef2e759e 100644 --- a/content/learning-paths/servers-and-cloud-computing/java-on-azure/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/java-on-azure/_index.md @@ -19,7 +19,8 @@ author: Pareena Verma ### Tags skilllevels: Introductory subjects: Performance and Architecture -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/kafka-azure/_index.md b/content/learning-paths/servers-and-cloud-computing/kafka-azure/_index.md index 0952b8dda0..13e0c707d7 100644 --- a/content/learning-paths/servers-and-cloud-computing/kafka-azure/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/kafka-azure/_index.md @@ -20,7 +20,8 @@ author: Pareena Verma ### Tags skilllevels: Advanced subjects: Storage -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/lambda_functions/_index.md b/content/learning-paths/servers-and-cloud-computing/lambda_functions/_index.md index a5c8b07ca1..32858fbe58 100644 --- a/content/learning-paths/servers-and-cloud-computing/lambda_functions/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/lambda_functions/_index.md @@ -16,7 +16,8 @@ author: Jason Andrews ### Tags skilllevels: Introductory subjects: Containers and Virtualization -cloud_service_providers: AWS +cloud_service_providers: + - AWS armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/memory_consistency/_index.md b/content/learning-paths/servers-and-cloud-computing/memory_consistency/_index.md index 4c0b566773..91038165b8 100644 --- a/content/learning-paths/servers-and-cloud-computing/memory_consistency/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/memory_consistency/_index.md @@ -21,7 +21,6 @@ author: Julio Suarez skilllevels: Advanced subjects: Performance and Architecture -cloud_service_providers: armips: - Neoverse operatingsystems: diff --git a/content/learning-paths/servers-and-cloud-computing/mongodb-on-azure/_index.md b/content/learning-paths/servers-and-cloud-computing/mongodb-on-azure/_index.md index 9692fc1176..a41bc324cb 100644 --- a/content/learning-paths/servers-and-cloud-computing/mongodb-on-azure/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/mongodb-on-azure/_index.md @@ -19,7 +19,8 @@ author: Pareena Verma ### Tags skilllevels: Introductory subjects: Databases -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/mongodb-on-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/mongodb-on-gcp/_index.md index 27a3011c93..89d75fcd77 100644 --- a/content/learning-paths/servers-and-cloud-computing/mongodb-on-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/mongodb-on-gcp/_index.md @@ -18,7 +18,8 @@ author: Annie Tallund ##### Tags skilllevels: Introductory subjects: Databases -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/multiarch_nginx_on_aks/_index.md b/content/learning-paths/servers-and-cloud-computing/multiarch_nginx_on_aks/_index.md index 1c3c475dd8..48c602c4db 100644 --- a/content/learning-paths/servers-and-cloud-computing/multiarch_nginx_on_aks/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/multiarch_nginx_on_aks/_index.md @@ -24,7 +24,8 @@ author: skilllevels: Introductory subjects: Containers and Virtualization -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/multiarch_ollama_on_gke/_index.md b/content/learning-paths/servers-and-cloud-computing/multiarch_ollama_on_gke/_index.md index a7d21651b6..7865526d64 100644 --- a/content/learning-paths/servers-and-cloud-computing/multiarch_ollama_on_gke/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/multiarch_ollama_on_gke/_index.md @@ -24,7 +24,8 @@ author: skilllevels: Introductory subjects: Containers and Virtualization -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/mysql-azure/_index.md b/content/learning-paths/servers-and-cloud-computing/mysql-azure/_index.md index 74bcfe5563..f6e8b14479 100644 --- a/content/learning-paths/servers-and-cloud-computing/mysql-azure/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/mysql-azure/_index.md @@ -20,7 +20,8 @@ author: Pareena Verma ### Tags skilllevels: Introductory subjects: Databases -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/mysql/_index.md b/content/learning-paths/servers-and-cloud-computing/mysql/_index.md index 77cff145d5..e09a969610 100644 --- a/content/learning-paths/servers-and-cloud-computing/mysql/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/mysql/_index.md @@ -17,7 +17,8 @@ author: Jason Andrews ### Tags skilllevels: Introductory subjects: Databases -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse operatingsystems: diff --git a/content/learning-paths/servers-and-cloud-computing/mysql_tune/_index.md b/content/learning-paths/servers-and-cloud-computing/mysql_tune/_index.md index 9c594140e1..08b04026d5 100644 --- a/content/learning-paths/servers-and-cloud-computing/mysql_tune/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/mysql_tune/_index.md @@ -15,7 +15,8 @@ author: Julio Suarez skilllevels: Advanced subjects: Databases -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse operatingsystems: diff --git a/content/learning-paths/servers-and-cloud-computing/net-aspire/_index.md b/content/learning-paths/servers-and-cloud-computing/net-aspire/_index.md index f9c900c29f..87b5b8d6aa 100644 --- a/content/learning-paths/servers-and-cloud-computing/net-aspire/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/net-aspire/_index.md @@ -20,7 +20,8 @@ author: Dawid Borycki ### Tags skilllevels: Introductory subjects: Containers and Virtualization -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/nginx-on-azure/_index.md b/content/learning-paths/servers-and-cloud-computing/nginx-on-azure/_index.md index ac71403fa2..6eba7132e3 100644 --- a/content/learning-paths/servers-and-cloud-computing/nginx-on-azure/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/nginx-on-azure/_index.md @@ -20,7 +20,8 @@ author: Pareena Verma ### Tags skilllevels: Introductory subjects: Web -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/node-js-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/node-js-gcp/_index.md index 17dc3e75f9..fe438b0011 100644 --- a/content/learning-paths/servers-and-cloud-computing/node-js-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/node-js-gcp/_index.md @@ -24,7 +24,8 @@ author: Pareena Verma ##### Tags skilllevels: Introductory subjects: Web -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/oci-terraform/_index.md b/content/learning-paths/servers-and-cloud-computing/oci-terraform/_index.md index 446eb58d9a..531dbb1244 100644 --- a/content/learning-paths/servers-and-cloud-computing/oci-terraform/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/oci-terraform/_index.md @@ -17,7 +17,8 @@ author: Frédéric -lefred- Descamps ### Tags skilllevels: Advanced subjects: Containers and Virtualization -cloud_service_providers: Oracle +cloud_service_providers: + - Oracle armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/onnx-on-azure/_index.md b/content/learning-paths/servers-and-cloud-computing/onnx-on-azure/_index.md index fe5d7bd7c6..c7de8e0c29 100644 --- a/content/learning-paths/servers-and-cloud-computing/onnx-on-azure/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/onnx-on-azure/_index.md @@ -20,7 +20,8 @@ author: Pareena Verma ### Tags skilllevels: Introductory subjects: ML -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/onnx/_index.md b/content/learning-paths/servers-and-cloud-computing/onnx/_index.md index 27dd6e766e..8cf67f15c0 100644 --- a/content/learning-paths/servers-and-cloud-computing/onnx/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/onnx/_index.md @@ -20,7 +20,8 @@ author: Nobel Chowdary Mandepudi ### Tags skilllevels: Advanced -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse subjects: ML diff --git a/content/learning-paths/servers-and-cloud-computing/opentelemetry/_index.md b/content/learning-paths/servers-and-cloud-computing/opentelemetry/_index.md new file mode 100644 index 0000000000..8263d0e7d6 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/opentelemetry/_index.md @@ -0,0 +1,73 @@ +--- +title: Deploy OpenTelemetry on Google Cloud C4A Axion processors + +minutes_to_complete: 40 + +who_is_this_for: This learning path is for DevOps engineers, platform engineers, and software developers who want to deploy and observe a cloud-native microservice on Arm64-based Google Cloud C4A Axion processors using OpenTelemetry. + +learning_objectives: + - Deploy an instrumented Python Flask microservice on Google Cloud C4A Axion processors + - Configure OpenTelemetry Collector to process and route distributed traces and metrics + - Integrate Prometheus and Jaeger for comprehensive metrics collection and distributed tracing visualization + - Generate and analyze telemetry data to monitor application performance on Arm-based infrastructure + +prerequisites: + - A [Google Cloud Platform (GCP)](https://cloud.google.com/free) account with billing enabled + - Basic familiarity with Python and Flask + - Basic understanding of containers and Kubernetes concepts + +author: Pareena Verma + +##### Tags +skilllevels: Introductory +subjects: Performance and Architecture +cloud_service_providers: +- Google Cloud + +armips: +- Neoverse + +tools_software_languages: +- Flask +- Docker +- Prometheus +- Jaeger + +operatingsystems: +- Linux + +# ================================================================================ +# FIXED, DO NOT MODIFY +# ================================================================================ + +further_reading: + - resource: + title: Google Cloud documentation + link: https://cloud.google.com/docs + type: documentation + + - resource: + title: OpenTelemetry documentation + link: https://opentelemetry.io/docs/ + type: documentation + + - resource: + title: Prometheus documentation + link: https://prometheus.io/docs/introduction/overview/ + type: documentation + + - resource: + title: Jaeger documentation + link: https://www.jaegertracing.io/docs/ + type: documentation + + - resource: + title: Docker documentation + link: https://docs.docker.com/ + type: documentation + +weight: 1 +layout: "learningpathall" +learning_path_main_page: yes +--- + diff --git a/content/learning-paths/servers-and-cloud-computing/opentelemetry/_next-steps.md b/content/learning-paths/servers-and-cloud-computing/opentelemetry/_next-steps.md new file mode 100644 index 0000000000..c3db0de5a2 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/opentelemetry/_next-steps.md @@ -0,0 +1,8 @@ +--- +# ================================================================================ +# FIXED, DO NOT MODIFY THIS FILE +# ================================================================================ +weight: 21 # Set to always be larger than the content in this path to be at the end of the navigation. +title: "Next Steps" # Always the same, html page title. +layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing. +--- diff --git a/content/learning-paths/servers-and-cloud-computing/opentelemetry/background.md b/content/learning-paths/servers-and-cloud-computing/opentelemetry/background.md new file mode 100644 index 0000000000..894d17576d --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/opentelemetry/background.md @@ -0,0 +1,38 @@ +--- +title: Get started with OpenTelemetry on Google Axion C4A + +weight: 2 + +layout: "learningpathall" +--- + +## Explore Axion C4A Arm instances in Google Cloud + +Google Axion C4A is a family of Arm-based virtual machines built on Google’s custom Axion CPU, which is based on Arm Neoverse-V2 cores. Designed for high-performance and energy-efficient computing, these virtual machines offer strong performance for modern cloud workloads such as CI/CD pipelines, microservices, media processing, and general-purpose applications. + +The C4A series provides a cost-effective alternative to x86 virtual machines while leveraging the scalability and performance benefits of the Arm architecture in Google Cloud. + +To learn more, see the Google blog [Introducing Google Axion Processors, our new Arm-based CPUs](https://cloud.google.com/blog/products/compute/introducing-googles-new-arm-based-cpu). + + +## Explore OpenTelemetry on Google Axion C4A (Arm Neoverse V2) + +OpenTelemetry is an open-source observability framework that provides standardized APIs, SDKs, and tools for collecting telemetry data such as traces, metrics, and logs from cloud-native applications. It is a CNCF (Cloud Native Computing Foundation) project and is widely adopted for building vendor-neutral observability solutions. + +OpenTelemetry enables developers to instrument applications once and export telemetry data to multiple backend systems including Prometheus, Grafana, Jaeger, Zipkin, and cloud monitoring platforms. + +Running OpenTelemetry on Google Axion C4A Arm-based infrastructure allows you to achieve high-throughput telemetry processing with improved performance per watt and reduced infrastructure costs, making it ideal for modern distributed systems. + +Common use cases include application performance monitoring (APM), distributed tracing, infrastructure metrics collection, log aggregation, and monitoring microservices architectures. + +To learn more, visit the [OpenTelemetry website](https://opentelemetry.io/) and explore the [OpenTelemetry documentation](https://opentelemetry.io/docs/). + +## What you've accomplished and what's next + +In this section, you learned about: + +* Google Axion C4A Arm-based VMs and their performance characteristics +* OpenTelemetry observability framework and its role in modern cloud-native monitoring +* How Arm architecture enables cost-effective, high-performance telemetry processing + +Next, you'll configure firewall rules and network access to allow external communication between your OpenTelemetry components and monitored services. diff --git a/content/learning-paths/servers-and-cloud-computing/opentelemetry/firewall-setup.md b/content/learning-paths/servers-and-cloud-computing/opentelemetry/firewall-setup.md new file mode 100644 index 0000000000..d44d9debcd --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/opentelemetry/firewall-setup.md @@ -0,0 +1,57 @@ +--- +title: Create firewall rules on GCP for Flask and observability components +weight: 3 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Configure GCP firewall for OpenTelemetry + +To allow inbound traffic for the Flask application and observability components, you must create a firewall rule in the Google Cloud Console. + +{{% notice Note %}} For more information about GCP setup, see [Getting started with Google Cloud Platform](/learning-paths/servers-and-cloud-computing/csp/google/).{{% /notice %}} + +## Required ports + +| Service | Port | Purpose | +| ------- | ---- | ------- | +| Flask Application | 8080 | Application traffic | +| Jaeger UI | 16686 | Trace visualization | +| Prometheus UI | 9090 | Metrics dashboard | +| OTLP gRPC | 4317 | Telemetry ingestion | +| OTLP HTTP | 4318 | Telemetry ingestion | +| Collector Metrics | 8889 | Prometheus scrape endpoint | + +## Create a firewall rule in GCP + +To expose the TCP ports listed above, create a firewall rule. + +Navigate to the [Google Cloud Console](https://console.cloud.google.com/), go to **VPC Network > Firewall**, and select **Create firewall rule**. + +![Google Cloud Console VPC Network Firewall page showing existing firewall rules and Create Firewall Rule button alt-txt#center](images/firewall-rule1.png "Create a firewall rule") + +Next, create the firewall rule that exposes the TCP ports. +Set the **Name** of the new rule to `allow-all-opentelemetry`. Select the network you intend to bind to your VM (the default is `default`, but your organization may use a different one). + +Set **Direction of traffic** to "Ingress". Set **Allow on match** to "Allow" and **Targets** to "Specified target tags". + +![Google Cloud Console firewall rule creation form showing name field, network selection, direction set to Ingress, and targets set to Specified target tags alt-txt#center](images/network-rule2.png "Creating opentelemetry firewall rule") + +Next, enter `allow-all-opentelemetry` in the **Target tags** field. Set **Source IPv4 ranges** to `0.0.0.0/0`. + +![Google Cloud Console firewall rule form showing target tags field with allow-all-opentelemetry entered and source IPv4 ranges set to 0.0.0.0/0 alt-txt#center](images/network-rule3.png "Creating the Opentelemetry firewall rule") + +Finally, select **Specified protocols and ports** under the **Protocols and ports** section. Select the **TCP** checkbox, enter `8080,16686,9090,4317,4318,8889` in the **Ports** field, and select **Create**. + +![Google Cloud Console firewall rule form showing protocols and ports section with TCP selected and ports 8080,16686,9090,4317,4318,8889 specified alt-txt#center](images/network-port.png "Specifying TCP ports for OpenTelemetry") + +## What you've accomplished and what's next + +You've successfully: + +- Created firewall rules in Google Cloud to expose ports for the Flask application and observability components +- Configured network access for Jaeger, Prometheus, and OpenTelemetry Collector endpoints +- Set up secure ingress rules for telemetry data collection + +Next, you'll provision a Google Axion C4A Arm virtual machine and apply these firewall rules to enable external access to your observability stack. diff --git a/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/firewall-rule1.png b/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/firewall-rule1.png new file mode 100644 index 0000000000..e1ab8aecb5 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/firewall-rule1.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/gcp-pubip-ssh.png b/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/gcp-pubip-ssh.png new file mode 100644 index 0000000000..558745de3e Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/gcp-pubip-ssh.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/gcp-shell.png b/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/gcp-shell.png new file mode 100644 index 0000000000..7e2fc3d1b5 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/gcp-shell.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/gcp-vm.png b/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/gcp-vm.png new file mode 100644 index 0000000000..0d1072e20d Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/gcp-vm.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/jaeger-ui.png b/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/jaeger-ui.png new file mode 100644 index 0000000000..c93c35353d Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/jaeger-ui.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/network-port.png b/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/network-port.png new file mode 100644 index 0000000000..e5370ef594 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/network-port.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/network-rule2.png b/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/network-rule2.png new file mode 100644 index 0000000000..4f3807a23d Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/network-rule2.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/network-rule3.png b/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/network-rule3.png new file mode 100644 index 0000000000..5e920e1c5c Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/network-rule3.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/prometheus.png b/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/prometheus.png new file mode 100644 index 0000000000..8f0a70c7e7 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/opentelemetry/images/prometheus.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/opentelemetry/instance.md b/content/learning-paths/servers-and-cloud-computing/opentelemetry/instance.md new file mode 100644 index 0000000000..4e0f5da3a0 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/opentelemetry/instance.md @@ -0,0 +1,58 @@ +--- +title: Create a Google Axion C4A Arm virtual machine on GCP +weight: 4 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Provision a Google Axion C4A Arm VM + +In this section you'll create a Google Axion C4A Arm-based virtual machine on Google Cloud Platform. You'll use the `c4a-standard-4` machine type, which provides 4 vCPUs and 16 GB of memory. This VM will host your OpenTelemetry application. + +{{% notice Note %}} +For help with GCP setup, see the Learning Path [Getting started with Google Cloud Platform](/learning-paths/servers-and-cloud-computing/csp/google/). +{{% /notice %}} + +## Provision a Google Axion C4A Arm VM in Google Cloud Console + +To create a virtual machine based on the C4A instance type: + +* Navigate to the [Google Cloud Console](https://console.cloud.google.com/). +* Go to **Compute Engine > VM Instances** and select **Create Instance**. +* Under **Machine configuration**: + * Populate fields such as **Instance name**, **Region**, and **Zone**. + * Set **Series** to `C4A`. + * Select `c4a-standard-4` for machine type. + +![Screenshot of the Google Cloud Console showing the Machine configuration section. The Series dropdown is set to C4A and the machine type c4a-standard-4 is selected alt-txt#center](images/gcp-vm.png "Configuring machine type to C4A in Google Cloud Console") + + +* Under **OS and storage**, select **Change**, and then choose an Arm64-based operating system image. + * For this Learning Path, select **SUSE Linux Enterprise Server**. + * For the license type, choose **Pay as you go**. + * Increase **Size (GB)** from **10** to **100** to allocate sufficient disk space. + * Select **Choose** to apply the changes. +* Under **Networking**, enable **Allow HTTP traffic** and **Allow HTTPS traffic** +* Also, add the following tag: `allow-all-opentelemetry` to allow all TCP ports through for OpenTelemetry. +* For some organizations not using the **'default'** network interface, you may need to select the network appropriate for your organization. +* Select **Create** to launch the virtual machine. + +After the instance starts, select **SSH** next to the VM in the instance list to open a browser-based terminal session. + +![Google Cloud Console VM instances page displaying running instance with green checkmark and SSH button in the Connect column alt-txt#center](images/gcp-pubip-ssh.png "Connecting to a running C4A VM using SSH") + +A new browser window opens with a terminal connected to your VM. + +![Browser-based SSH terminal window with black background showing Linux command prompt and Google Cloud branding at top alt-txt#center](images/gcp-shell.png "Terminal session connected to the VM") + +## What you've accomplished and what's next + +In this section: +- You provisioned a Google Axion C4A Arm VM with 4 vCPUs and 16 GB of memory +- You configured the VM with SUSE Linux Enterprise Server and 100 GB of storage +- You connected to your VM using SSH through the Google Cloud Console + +Your VM is now ready to host the OpenTelemetry application. In the next section, you'll install Docker and Docker Compose, then deploy your instrumented Flask application. + +Next, you'll install Docker, Docker Compose, and the OpenTelemetry-instrumented Flask application on your VM. diff --git a/content/learning-paths/servers-and-cloud-computing/opentelemetry/otel-observability.md b/content/learning-paths/servers-and-cloud-computing/opentelemetry/otel-observability.md new file mode 100644 index 0000000000..0d5103b673 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/opentelemetry/otel-observability.md @@ -0,0 +1,258 @@ +--- +title: Deploy the OpenTelemetry observability stack on Arm64 +weight: 6 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Overview + +In this section, you will deploy and connect the OpenTelemetry Collector, Prometheus, and Jaeger to collect, store, and visualize telemetry data generated by the Flask microservice running on Arm64 infrastructure. + +By the end of this section, you will have a complete observability pipeline for metrics and distributed tracing. + +## Architecture overview + +```text +Flask Microservice (Arm64) + | + | OpenTelemetry SDK + v +OpenTelemetry Collector + | | +Metrics → Prometheus +Traces → Jaeger +``` + +The Flask application sends telemetry to the OpenTelemetry Collector, which routes metrics to Prometheus and traces to Jaeger for monitoring and visualization. + + +## Network and firewall requirements + +Ensure the following ports are open on your VM firewall: + +| Service | Port | Purpose | +| ----------------- | ----- | -------------------------- | +| Prometheus | 9090 | Metrics dashboard UI | +| Jaeger UI | 16686 | Distributed tracing UI | +| Collector Metrics | 8889 | Prometheus scrape endpoint | +| OTLP gRPC | 4317 | Telemetry ingestion (gRPC) | +| OTLP HTTP | 4318 | Telemetry ingestion (HTTP) | + +These ports enable telemetry ingestion and provide web interfaces for monitoring metrics and traces. + +## Configure OpenTelemetry Collector + +This configuration defines how telemetry data is received from the Flask application and exported to Prometheus and Jaeger. + +Navigate to your project directory: + +```bash +cd ~/otel-demo +``` + +Create a file `otel-collector-config.yaml` with the following content: + +```yaml +receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:4317 + http: + endpoint: 0.0.0.0:4318 + +exporters: + otlp: + endpoint: jaeger:4317 + tls: + insecure: true + + prometheus: + endpoint: 0.0.0.0:8889 + +service: + pipelines: + traces: + receivers: [otlp] + exporters: [otlp] + + metrics: + receivers: [otlp] + exporters: [prometheus] +``` + +The Collector now receives OTLP telemetry and routes traces to Jaeger while exposing metrics for Prometheus scraping. + + +## Configure Prometheus + +This configuration instructs Prometheus to scrape metrics from the OpenTelemetry Collector. + +Create a file `prometheus.yml` with the following content: + +```yaml +global: + scrape_interval: 5s + +scrape_configs: + - job_name: "otel-collector" + static_configs: + - targets: ["otel-collector:8889"] +``` + +Prometheus will now periodically collect metrics generated by the Flask application via the Collector. + +## Create Docker Compose observability stack + +Docker Compose orchestrates the Flask service, Collector, Prometheus, and Jaeger in a single deployment. + +Create a file `docker-compose.yml` with the following content: + +```yaml +services: + otel-demo-app: + build: . + ports: + - "8080:8080" + depends_on: + - otel-collector + + otel-collector: + image: otel/opentelemetry-collector-contrib:latest + command: ["--config=/etc/otel-collector-config.yaml"] + volumes: + - ./otel-collector-config.yaml:/etc/otel-collector-config.yaml + ports: + - "4317:4317" + - "4318:4318" + - "8889:8889" + + jaeger: + image: jaegertracing/all-in-one:latest + ports: + - "16686:16686" + + prometheus: + image: prom/prometheus:latest + volumes: + - ./prometheus.yml:/etc/prometheus/prometheus.yml + command: + - "--config.file=/etc/prometheus/prometheus.yml" + ports: + - "9090:9090" +``` + +All observability components and the Flask application are now defined for automated deployment. + +## Launch the observability stack + +Build the Flask image and start all services. + +```bash +sudo /usr/local/bin/docker-compose up --build -d +``` + +Verify running containers: + +```bash +docker ps +``` + +The output is similar to: + +```output +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +944ce1f16551 otel-demo-otel-demo-app "python app.py" 21 hours ago Up 5 seconds 0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp otel-demo-otel-demo-app-1 +6cdc86f7d1a9 prom/prometheus:latest "/bin/prometheus --c…" 21 hours ago Up 5 seconds 0.0.0.0:9090->9090/tcp, [::]:9090->9090/tcp otel-demo-prometheus-1 +a88d6979db39 otel/opentelemetry-collector-contrib:latest "/otelcol-contrib --…" 21 hours ago Up 5 seconds 0.0.0.0:4317-4318->4317-4318/tcp, [::]:4317-4318->4317-4318/tcp, 0.0.0.0:8889->8889/tcp, [::]:8889->8889/tcp, 55679/tcp otel-demo-otel-collector-1 +f4f7776b2201 jaegertracing/all-in-one:latest "/go/bin/all-in-one-…" 21 hours ago Up 5 seconds 4317-4318/tcp, 9411/tcp, 14250/tcp, 14268/tcp, 0.0.0.0:16686->16686/tcp, [::]:16686->16686/tcp otel-demo-jaeger-1 +``` + +### Expected services + +* otel-demo-app +* otel-collector +* jaeger +* prometheus + +The full observability stack is now running in containers on Arm64. + +## Generate application traffic + +Send requests to the Flask service to produce telemetry data. + +```bash +curl http://:8080 +``` + +Run a loop to generate more traffic: + +```bash +for i in {1..10}; do curl http://:8080; done +``` + +Each request generates traces and increments custom metrics. + +The output is similar to: + +```output +gcpuser@otel-suse-arm64:~/otel-demo> for i in {1..10}; do curl http://34.58.132.15:8080; done +Hello OpenTelemetry!Hello OpenTelemetry!Hello OpenTelemetry!Hello OpenTelemetry!Hello OpenTelemetry!Hello OpenTelemetry!Hello OpenTelemetry!Hello OpenTelemetry!Hello OpenTelemetry!Hello OpenTelemetry!gcpuser@otel-suse-arm64:~/otel-demo> +``` + +## Validate metrics in Prometheus + +Open Prometheus in your browser: + +```text +http://:9090 +``` + +### Suggested Queries + +* up +* demo_requests_total + +Successful query results confirm that metrics are flowing correctly through the pipeline. + +### Prometheus metrics view + +![Prometheus web UI showing query results for demo_requests_total metric scraped from the OpenTelemetry Collector alt-txt#center](images/prometheus.png "Prometheus confirming metrics from the OpenTelemetry Collector") + +This image confirms that Prometheus is successfully scraping metrics from the OpenTelemetry Collector, including the custom `demo_requests_total` counter generated by the Flask application. + +## Validate traces in Jaeger + +Open Jaeger UI: + +```text +http://:16686 +``` + +Select the service: + +```text +flask-arm-service +``` + +Select **Find Traces** to view request traces. + +You should now see distributed traces generated by the Flask microservice. + +### Jaeger distributed tracing view + +![Jaeger UI showing distributed trace spans for the flask-arm-service, including request timing and service dependency graph alt-txt#center](images/jaeger-ui.png "Distributed traces from the Flask microservice in Jaeger") + +This image shows distributed traces generated by the Flask microservice and collected via the OpenTelemetry pipeline, visualized in the Jaeger UI. + + +## What you've accomplished and what's next + +In this section: +- You deployed the OpenTelemetry Collector, Prometheus, and Jaeger as a Docker Compose stack on Google Cloud C4A Axion +- You configured the Collector to route traces to Jaeger and metrics to Prometheus +- You generated traffic and validated the end-to-end telemetry pipeline + +You now have a complete observability pipeline running natively on Arm infrastructure. From here, you can add custom metrics, set up alerting rules in Prometheus, or integrate additional exporters for your monitoring needs. diff --git a/content/learning-paths/servers-and-cloud-computing/opentelemetry/otel-setup.md b/content/learning-paths/servers-and-cloud-computing/opentelemetry/otel-setup.md new file mode 100644 index 0000000000..1f821901cc --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/opentelemetry/otel-setup.md @@ -0,0 +1,217 @@ +--- +title: Set up OpenTelemetry environment and application on Arm64 +weight: 5 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + + +## OpenTelemetry environment and application setup + +In this section, you prepare an arm64-based SUSE Linux virtual machine with container tooling and deploy an instrumented Python Flask microservice that emits OpenTelemetry traces and metrics. + +## Architecture overview + +This setup includes a lightweight application and telemetry flow as shown below: + +```text +Flask Microservice (Arm64) + | + | OpenTelemetry SDK + v +OpenTelemetry Collector +``` + +The Flask application generates telemetry data using the OpenTelemetry SDK and sends it to an OpenTelemetry Collector for further processing and visualization. + +## Network and firewall requirements + +Ensure the following ports are open on your VM firewall: + +| Service | Port | Purpose | +| ----------------- | ----- | -------------------------- | +| Prometheus | 9090 | Metrics dashboard UI | +| Jaeger UI | 16686 | Distributed tracing UI | +| Collector Metrics | 8889 | Prometheus scrape endpoint | +| OTLP gRPC | 4317 | Telemetry ingestion (gRPC) | +| OTLP HTTP | 4318 | Telemetry ingestion (HTTP) | + +These ports enable telemetry ingestion and provide web interfaces for monitoring metrics and traces. + +## Enable the SUSE Containers module + +Enable the SUSE Containers Module to ensure that Docker and container-related tools are fully supported. + +```bash +sudo SUSEConnect -p sle-module-containers/15.5/arm64 +sudo SUSEConnect --list-extensions | grep Containers +``` + +Verify that the output shows the Containers module as **Activated**. + +## Install Docker on SUSE Arm64 + +Docker is required to run containerized services on the Arm-based VM. + +```bash +sudo zypper refresh +sudo zypper install -y docker +sudo systemctl enable docker +sudo systemctl start docker +sudo usermod -aG docker $USER +newgrp docker +``` + +### Verify Docker installation + +```bash +docker --version +``` + +Docker Engine is now installed and configured to run without sudo for the current user. + + + +## Install Docker Compose (v2) + +Docker Compose is used to orchestrate multi-container applications. + +```bash +sudo curl -L https://github.com/docker/compose/releases/download/v2.27.0/docker-compose-linux-aarch64 \ + -o /usr/local/bin/docker-compose + +sudo chmod +x /usr/local/bin/docker-compose +``` + +### Verify Docker Compose installation + +```bash +docker-compose --version +``` + +Docker Compose v2 is now installed and ready to manage multi-service deployments. + +## Create project workspace + +Create a dedicated directory for the OpenTelemetry demo application. + +```bash +mkdir ~/otel-demo +cd ~/otel-demo +``` + +This directory will store the Flask application code, dependencies, and container configuration. + +## Build an instrumented Flask application + +This Flask service is integrated with the OpenTelemetry SDK to emit distributed traces and metrics. + +Create a file `app.py` in `~/otel-demo` with the following content: + +```python +from flask import Flask +import time + +from opentelemetry import trace, metrics +from opentelemetry.sdk.resources import Resource +from opentelemetry.sdk.trace import TracerProvider +from opentelemetry.sdk.metrics import MeterProvider +from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader +from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter +from opentelemetry.exporter.otlp.proto.grpc.metric_exporter import OTLPMetricExporter +from opentelemetry.instrumentation.flask import FlaskInstrumentor +from opentelemetry.sdk.trace.export import BatchSpanProcessor + +resource = Resource.create({ + "service.name": "flask-arm-service" +}) + +trace_provider = TracerProvider(resource=resource) +trace.set_tracer_provider(trace_provider) + +trace_exporter = OTLPSpanExporter(endpoint="otel-collector:4317", insecure=True) +trace_provider.add_span_processor( + BatchSpanProcessor(trace_exporter) +) + +metric_exporter = OTLPMetricExporter(endpoint="otel-collector:4317", insecure=True) + +metric_reader = PeriodicExportingMetricReader( + metric_exporter, + export_interval_millis=5000 +) + +meter_provider = MeterProvider( + resource=resource, + metric_readers=[metric_reader] +) + +metrics.set_meter_provider(meter_provider) + +meter = metrics.get_meter(__name__) + +request_counter = meter.create_counter( + name="demo_requests_total", + description="Total number of requests" +) + +app = Flask(__name__) +FlaskInstrumentor().instrument_app(app) + +@app.route("/") +def hello(): + request_counter.add(1) + time.sleep(0.2) + return "Hello OpenTelemetry!" + +if __name__ == "__main__": + app.run(host="0.0.0.0", port=8080) +``` + +The Flask service now automatically generates traces for HTTP requests and custom metrics for request counts. + +## Define Python dependencies + +Create a file `requirements.txt` in `~/otel-demo` to list all required Python packages: + +```text +flask +opentelemetry-api +opentelemetry-sdk +opentelemetry-exporter-otlp +opentelemetry-instrumentation-flask +``` + +This ensures all OpenTelemetry and Flask libraries are installed consistently inside the container. + +## Create the application Docker image + +Build an Arm-compatible container image for the Flask service. + +Create a file `Dockerfile` in `~/otel-demo` with the following content: + +```dockerfile +FROM python:3.10-slim + +WORKDIR /app + +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +COPY app.py . + +CMD ["python", "app.py"] +``` + +This Dockerfile packages the instrumented Flask application into a lightweight Arm64-compatible container. + +## What you've accomplished and what's next + +You've successfully: + +- Set up Docker and Docker Compose on your Google Axion C4A Arm64 virtual machine +- Built an instrumented Python Flask microservice that emits OpenTelemetry traces and metrics +- Created a containerized application ready for deployment + +Next, you'll deploy the OpenTelemetry Collector and observability stack to receive, process, and visualize the telemetry data. diff --git a/content/learning-paths/servers-and-cloud-computing/php-on-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/php-on-gcp/_index.md index fd77bac1f6..d21dfdc3aa 100644 --- a/content/learning-paths/servers-and-cloud-computing/php-on-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/php-on-gcp/_index.md @@ -21,7 +21,8 @@ author: Pareena Verma ##### Tags skilllevels: Introductory subjects: Web -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/puppet-on-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/puppet-on-gcp/_index.md index dc51715408..dffca64bc8 100644 --- a/content/learning-paths/servers-and-cloud-computing/puppet-on-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/puppet-on-gcp/_index.md @@ -19,7 +19,8 @@ prerequisites: ##### Tags skilllevels: Introductory subjects: Performance and Architecture -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/rag/_index.md b/content/learning-paths/servers-and-cloud-computing/rag/_index.md index 5687564dc8..32e28a80da 100644 --- a/content/learning-paths/servers-and-cloud-computing/rag/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/rag/_index.md @@ -23,7 +23,8 @@ author: Nobel Chowdary Mandepudi ### Tags skilllevels: Advanced -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse subjects: ML diff --git a/content/learning-paths/servers-and-cloud-computing/redis-data-searching/_index.md b/content/learning-paths/servers-and-cloud-computing/redis-data-searching/_index.md index 8977695464..b979afbda1 100644 --- a/content/learning-paths/servers-and-cloud-computing/redis-data-searching/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/redis-data-searching/_index.md @@ -20,7 +20,8 @@ author: Pareena Verma ##### Tags skilllevels: Introductory subjects: Databases -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/redis/_index.md b/content/learning-paths/servers-and-cloud-computing/redis/_index.md index 2d9e6ec935..52df6ae072 100644 --- a/content/learning-paths/servers-and-cloud-computing/redis/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/redis/_index.md @@ -18,7 +18,8 @@ author: Elham Harirpoush ### Tags skilllevels: Introductory subjects: Databases -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse operatingsystems: diff --git a/content/learning-paths/servers-and-cloud-computing/redis_tune/_index.md b/content/learning-paths/servers-and-cloud-computing/redis_tune/_index.md index a811b2a8ef..9e7e41c663 100644 --- a/content/learning-paths/servers-and-cloud-computing/redis_tune/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/redis_tune/_index.md @@ -19,7 +19,8 @@ author: Elham Harirpoush ### Tags skilllevels: Advanced subjects: Databases -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse tools_software_languages: diff --git a/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/_index.md b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/_index.md index c8f6b189ac..81d7ae18f4 100644 --- a/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/ruby-on-rails/_index.md @@ -21,7 +21,8 @@ author: Pareena Verma ### Tags skilllevels: Introductory subjects: Web -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/rust-on-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/rust-on-gcp/_index.md index fb41b3b79f..50a5485bf6 100644 --- a/content/learning-paths/servers-and-cloud-computing/rust-on-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/rust-on-gcp/_index.md @@ -22,7 +22,8 @@ author: Pareena Verma ##### Tags skilllevels: Introductory subjects: Performance and Architecture -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_index.md b/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_index.md index 5e013f07d1..14432138bc 100644 --- a/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/sentiment-analysis-eks/_index.md @@ -23,7 +23,8 @@ author: ### Tags skilllevels: Advanced subjects: Containers and Virtualization -cloud_service_providers: AWS +cloud_service_providers: + - AWS armips: - Neoverse tools_software_languages: diff --git a/content/learning-paths/servers-and-cloud-computing/serverless-framework-aws-intro/_index.md b/content/learning-paths/servers-and-cloud-computing/serverless-framework-aws-intro/_index.md index d53fa01e36..4f2cf849fb 100644 --- a/content/learning-paths/servers-and-cloud-computing/serverless-framework-aws-intro/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/serverless-framework-aws-intro/_index.md @@ -18,7 +18,8 @@ author: Dawid Borycki ### Tags skilllevels: Introductory subjects: Web -cloud_service_providers: AWS +cloud_service_providers: + - AWS armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/serverless-framework-aws-lambda-dynamodb/_index.md b/content/learning-paths/servers-and-cloud-computing/serverless-framework-aws-lambda-dynamodb/_index.md index 96e5953132..c637c0ca08 100644 --- a/content/learning-paths/servers-and-cloud-computing/serverless-framework-aws-lambda-dynamodb/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/serverless-framework-aws-lambda-dynamodb/_index.md @@ -19,7 +19,8 @@ author: Dawid Borycki ### Tags skilllevels: Introductory subjects: Web -cloud_service_providers: AWS +cloud_service_providers: + - AWS armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/serverless-framework-aws-s3/_index.md b/content/learning-paths/servers-and-cloud-computing/serverless-framework-aws-s3/_index.md index eeed91716c..ad60326a1d 100644 --- a/content/learning-paths/servers-and-cloud-computing/serverless-framework-aws-s3/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/serverless-framework-aws-s3/_index.md @@ -19,7 +19,8 @@ author: Dawid Borycki ### Tags skilllevels: Introductory subjects: Web -cloud_service_providers: AWS +cloud_service_providers: + - AWS armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/spark-on-azure/_index.md b/content/learning-paths/servers-and-cloud-computing/spark-on-azure/_index.md index 740f5557d0..59c9669d88 100644 --- a/content/learning-paths/servers-and-cloud-computing/spark-on-azure/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/spark-on-azure/_index.md @@ -21,7 +21,8 @@ author: Pareena Verma ### Tags skilllevels: Advanced subjects: Performance and Architecture -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/spark-on-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/spark-on-gcp/_index.md index cb527981a5..f017a4288c 100644 --- a/content/learning-paths/servers-and-cloud-computing/spark-on-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/spark-on-gcp/_index.md @@ -20,7 +20,8 @@ author: Pareena Verma ##### Tags skilllevels: Advanced subjects: Performance and Architecture -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/spark/_index.md b/content/learning-paths/servers-and-cloud-computing/spark/_index.md index 367d2f3879..904a80cf16 100644 --- a/content/learning-paths/servers-and-cloud-computing/spark/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/spark/_index.md @@ -17,7 +17,8 @@ author: Jason Andrews ### Tags skilllevels: Introductory subjects: Databases -cloud_service_providers: AWS +cloud_service_providers: + - AWS armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/tensorflow-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/tensorflow-gcp/_index.md index 5f462ccc96..6a16182926 100644 --- a/content/learning-paths/servers-and-cloud-computing/tensorflow-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/tensorflow-gcp/_index.md @@ -19,7 +19,8 @@ author: Pareena Verma ##### Tags skilllevels: Introductory subjects: ML -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/_index.md new file mode 100644 index 0000000000..bc05efc48c --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/_index.md @@ -0,0 +1,74 @@ +--- +title: Deploy a live sensor dashboard with TimescaleDB and Grafana on Google Cloud C4A + +draft: true +cascade: + draft: true + +minutes_to_complete: 45 + +who_is_this_for: This learning path is for DevOps engineers, database engineers, and software developers who want to deploy and operate TimescaleDB on SUSE Linux Enterprise Server (SLES) Arm64, ingest live time-series sensor data, and visualize it in Grafana. + +learning_objectives: + - Install and configure TimescaleDB on Google Cloud C4A Axion processors by building from source for Arm64 + - Create a real-time sensor data ingestion pipeline using Python with hypertables, continuous aggregates, and retention policies + - Build a live sensor dashboard with Grafana that automatically refreshes to display time-series data + - Validate end-to-end data flow from ingestion through TimescaleDB to Grafana visualization + +prerequisites: + - A [Google Cloud Platform (GCP)](https://cloud.google.com/free) account with billing enabled + - Basic familiarity with SQL, Python, and Grafana + +author: Pareena Verma + +##### Tags +skilllevels: Introductory +subjects: Databases +cloud_service_providers: + - Google Cloud + +armips: + - Neoverse + +tools_software_languages: + - TimescaleDB + - PostgreSQL + - Python + - Grafana + - psycopg2 + +operatingsystems: + - Linux + +# ================================================================================ +# FIXED, DO NOT MODIFY +# ================================================================================ + +further_reading: + - resource: + title: TimescaleDB official documentation + link: https://docs.timescale.com/ + type: documentation + + - resource: + title: PostgreSQL 15 documentation + link: https://www.postgresql.org/docs/15/index.html + type: documentation + + - resource: + title: Grafana documentation + link: https://grafana.com/docs/grafana/latest/ + type: documentation + + - resource: + title: Python psycopg2 documentation + link: https://www.psycopg.org/docs/ + type: documentation + +weight: 1 +layout: "learningpathall" +learning_path_main_page: yes +--- + +TimescaleDB is a high-performance, open-source time-series database built on PostgreSQL that provides powerful features for storing, querying, and analyzing time-series data efficiently. When you deploy TimescaleDB on Google Cloud C4A Axion Arm-based processors, you can achieve high-throughput time-series ingestion and query processing with optimized performance per watt and lower infrastructure costs. This Learning Path shows you how to build a complete time-series data pipeline with live sensor ingestion and real-time visualization using Grafana. + diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/_next-steps.md b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/_next-steps.md new file mode 100644 index 0000000000..c3db0de5a2 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/_next-steps.md @@ -0,0 +1,8 @@ +--- +# ================================================================================ +# FIXED, DO NOT MODIFY THIS FILE +# ================================================================================ +weight: 21 # Set to always be larger than the content in this path to be at the end of the navigation. +title: "Next Steps" # Always the same, html page title. +layout: "learningpathall" # All files under learning paths have this same wrapper for Hugo processing. +--- diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/background.md b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/background.md new file mode 100644 index 0000000000..a9f20c4245 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/background.md @@ -0,0 +1,38 @@ +--- +title: Get started with TimescaleDB on Google Axion C4A + +weight: 2 + +layout: "learningpathall" +--- + +## Explore Axion C4A Arm instances in Google Cloud + +Google Axion C4A is a family of Arm-based virtual machines built on Google’s custom Axion CPU, which is based on Arm Neoverse-V2 cores. Designed for high-performance and energy-efficient computing, these virtual machines offer strong performance for modern cloud workloads such as CI/CD pipelines, microservices, media processing, and general-purpose applications. + +The C4A series provides a cost-effective alternative to x86 virtual machines while leveraging the scalability and performance benefits of the Arm architecture in Google Cloud. + +To learn more, see the Google blog [Introducing Google Axion Processors, our new Arm-based CPUs](https://cloud.google.com/blog/products/compute/introducing-googles-new-arm-based-cpu). + + +## Explore TimescaleDB on Google Axion C4A (Arm Neoverse V2) + +TimescaleDB is a high-performance, open-source time-series database built on PostgreSQL. It provides powerful features for storing, querying, and analyzing time-series data efficiently, making it ideal for IoT, telemetry, financial, and observability workloads. + +TimescaleDB enables developers to handle large volumes of time-stamped data with features like hypertables, continuous aggregates, retention policies, and automated data partitioning, while maintaining full SQL compatibility. + +Running TimescaleDB on Google Axion C4A Arm-based infrastructure allows you to achieve high-throughput time-series ingestion and query processing with optimized performance per watt, lower infrastructure costs, and better scalability for distributed workloads. + +Common use cases include real-time monitoring of IoT sensors, event-driven analytics, DevOps metrics collection, financial time-series analysis, and building dashboards with tools like Grafana for live visualization. + +To learn more, visit the [TimescaleDB website](https://www.timescale.com/) and explore the [TimescaleDB documentation](https://docs.timescale.com/). + +## What you've accomplished and what's next + +In this section, you learned about: + +* Google Axion C4A Arm-based VMs and their performance advantages for time-series workloads +* TimescaleDB and its key features, including hypertables, continuous aggregates, and retention policies +* How Arm architecture enables cost-efficient, high-throughput ingestion and query processing for time-series data + +Next, you'll create firewall rules to enable remote access to the Grafana dashboard that you'll build later in this Learning Path. diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/firewall-setup.md b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/firewall-setup.md new file mode 100644 index 0000000000..ab9f33bd40 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/firewall-setup.md @@ -0,0 +1,39 @@ +--- +title: Create a firewall rule for Grafana/TimescaleDB +weight: 3 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +Create a firewall rule in Google Cloud Console to expose TCP port 3000 for the TimescaleDB (Grafana) management interface. + +{{% notice Note %}} +For support on GCP setup, see the Learning Path [Getting started with Google Cloud Platform](/learning-paths/servers-and-cloud-computing/csp/google/). +{{% /notice %}} + +## Configure the firewall rule + +Navigate to the [Google Cloud Console](https://console.cloud.google.com/), go to **VPC Network > Firewall**, and select **Create firewall rule**. + +![Create a firewall rule](images/firewall-rule.png "Create a firewall rule") + +Next, create the firewall rule that exposes TCP port 3000. +Set the **Name** of the new rule to "allow-tcp-3000". Select your network that you intend to bind to your VM (default is "autoscaling-net" but your organization might have others). + +Set **Direction of traffic** to "Ingress". Set **Allow on match** to "Allow" and **Targets** to "Specified target tags". Enter "allow-tcp-3000" in the **Target tags** text field. Set **Source IPv4 ranges** to "0.0.0.0/0". + +![Create a firewall rule](images/network-rule.png "Creating the TCP/3000 firewall rule") + +Finally, select **Specified protocols and ports** under the **Protocols and ports** section. Select the **TCP** checkbox, enter "3000" in the **Ports** text field, and select **Create**. + +![Specifying the TCP port to expose](images/network-port.png "Specifying the TCP port to expose") + +## What you've accomplished and what's next + +You've successfully: + +* Created a firewall rule in Google Cloud to expose port 3000 for Grafana web interface access +* Configured network ingress rules to allow remote connections to your dashboard + +Next, you'll provision a Google Axion C4A Arm virtual machine and apply this firewall rule to enable external access to Grafana. diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/grafana-timescaledb-setup.md b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/grafana-timescaledb-setup.md new file mode 100644 index 0000000000..7e619647d7 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/grafana-timescaledb-setup.md @@ -0,0 +1,131 @@ +--- +title: Grafana Setup & TimescaleDB Data Source Configuration +weight: 7 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Grafana Setup & TimescaleDB Data Source + +In this section, you install Grafana on a SUSE Arm64 virtual machine, access its web interface, and connect it to TimescaleDB. Grafana acts as the visualization layer that queries TimescaleDB and displays time-series data in dashboards. + +This setup enables real-time monitoring and analytics of sensor or application data stored in TimescaleDB. + +## Architecture (At This Stage) + +```text +Python Sensor Ingest Script + | + v +TimescaleDB (PostgreSQL) + | + v +Grafana Dashboard +``` + +## Install Grafana on SUSE (Arm64) + +Grafana is available via RPM packages and works natively on Arm64. + +```bash +cd $HOME +sudo zypper addrepo https://rpm.grafana.com grafana +sudo zypper refresh +sudo zypper install -y grafana +``` + +### Enable and start Grafana + +```bash +sudo systemctl start grafana-server +sudo systemctl enable grafana-server +``` + +**Verify status:** + +```bash +sudo systemctl status grafana-server +``` + +The output is similar to: + +```output +● grafana-server.service - Grafana instance + Loaded: loaded (/usr/lib/systemd/system/grafana-server.service; enabled; vendor preset: disabled) + Active: active (running) since Tue 2026-02-17 08:57:45 UTC; 1h 31min ago +```` + +## Access Grafana Web UI + +Open your browser and navigate to: + +```bash +http://:3000 +``` + +### Default Login Credentials + +| Field | Value | +| -------- | ----- | +| Username | admin | +| Password | admin | + +You will be prompted to change the password on first login. Provide and save off a new password. Re-login if needed using the new password: + +![Grafana login page#center](images/grafana-login-page.png "Grafana login page") + +You will be presented with the main dashboard for Grafana: + +![Grafana dashboard#center](images/grafana-dashboard.png "Grafana dashboard") + +## Add TimescaleDB as a Data Source + +### Step 1: Open Data Sources + +From the Grafana sidebar: + +```bash +Connections → Data sources → Add data source +``` + +### Step 2: Choose PostgreSQL + +Select PostgreSQL (TimescaleDB is PostgreSQL-compatible). + +![Add PostgreSQL data source in Grafana#center](images/psql-data-source.png "Add PostgreSQL data source") + + +### Step 3: Configure Connection Settings + +Fill the form exactly as below: + +| Field | Value | +| ------------- | ------------------------------ | +| Host URL | `localhost:5432` | +| Database name | `sensors` | +| Username | `postgres` | +| Password | `` | +| TLS/SSL Mode | `disable` | + +![PostgreSQL data source connection settings#center](images/data-source-details.png "PostgreSQL data source settings") + +**Scroll down and click:** + +```text +Save & Test +``` + +You should see "Database connection OK." + +![Grafana PostgreSQL data source save and test success#center](images/data-source-save-test.png "Grafana PostgreSQL data source save and test") + +## What You Have Accomplished + +- Installed Grafana on SUSE Arm64 +- Logged into Grafana UI +- Connected Grafana to TimescaleDB successfully + +## What’s Next + +In the next section, you will create a live dashboard to visualize real-time sensor temperature data. diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/data-source-details.png b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/data-source-details.png new file mode 100644 index 0000000000..f7a8a4297d Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/data-source-details.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/data-source-save-test.png b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/data-source-save-test.png new file mode 100644 index 0000000000..976d6b28da Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/data-source-save-test.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/data-source-visualization.png b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/data-source-visualization.png new file mode 100644 index 0000000000..fb201caaee Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/data-source-visualization.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/firewall-rule.png b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/firewall-rule.png new file mode 100644 index 0000000000..ab99314834 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/firewall-rule.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/gcp-pubip-ssh.png b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/gcp-pubip-ssh.png new file mode 100644 index 0000000000..558745de3e Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/gcp-pubip-ssh.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/gcp-shell.png b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/gcp-shell.png new file mode 100644 index 0000000000..7e2fc3d1b5 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/gcp-shell.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/gcp-vm.png b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/gcp-vm.png new file mode 100644 index 0000000000..0d1072e20d Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/gcp-vm.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/grafana-dashboard.png b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/grafana-dashboard.png new file mode 100644 index 0000000000..d7e5099d01 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/grafana-dashboard.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/grafana-login-page.png b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/grafana-login-page.png new file mode 100644 index 0000000000..7539219a81 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/grafana-login-page.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/live-sensor-temperature.png b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/live-sensor-temperature.png new file mode 100644 index 0000000000..112b8bee4e Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/live-sensor-temperature.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/network-port.png b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/network-port.png new file mode 100644 index 0000000000..2f3d52aa5e Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/network-port.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/network-rule.png b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/network-rule.png new file mode 100644 index 0000000000..905bc871a1 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/network-rule.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/psql-data-source.png b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/psql-data-source.png new file mode 100644 index 0000000000..c2d0d3b258 Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/psql-data-source.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/timescale-query.png b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/timescale-query.png new file mode 100644 index 0000000000..a369403fea Binary files /dev/null and b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/images/timescale-query.png differ diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/instance.md b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/instance.md new file mode 100644 index 0000000000..a28880fb76 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/instance.md @@ -0,0 +1,50 @@ +--- +title: Create a Google Axion C4A Arm virtual machine on GCP +weight: 4 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Provision a Google Axion C4A Arm VM + +In this section you'll create a Google Axion C4A Arm-based virtual machine on Google Cloud Platform. You'll use the `c4a-standard-4` machine type, which provides 4 vCPUs and 16 GB of memory. This VM will host your TimescaleDB application. + +{{% notice Note %}} +For help with GCP setup, see the Learning Path [Getting started with Google Cloud Platform](/learning-paths/servers-and-cloud-computing/csp/google/). +{{% /notice %}} + +## Provision a Google Axion C4A Arm VM in Google Cloud Console + +To create a virtual machine based on the C4A instance type: + +* Navigate to the [Google Cloud Console](https://console.cloud.google.com/). +* Go to **Compute Engine > VM Instances** and select **Create Instance**. +* Under **Machine configuration**: + * Populate fields such as **Instance name**, **Region**, and **Zone**. + * Set **Series** to `C4A`. + * Select `c4a-standard-4` for machine type. + +![Screenshot of the Google Cloud Console showing the Machine configuration section. The Series dropdown is set to C4A and the machine type c4a-standard-4 is selected#center](images/gcp-vm.png "Configuring machine type to C4A in Google Cloud Console") + +* Under **OS and storage**, select **Change**, and then choose an Arm64-based operating system image. + * For this Learning Path, select **SUSE Linux Enterprise Server**. + * For the license type, choose **Pay as you go**. + * Increase **Size (GB)** from **10** to **100** to allocate sufficient disk space. + * Select **Choose** to apply the changes. +* Under **Networking**, enable **Allow HTTP traffic** and **Allow HTTPS traffic**. Also, add the following tag "allow-tcp-3000" to enable remote grafana access. +* Select **Create** to launch the virtual machine. + +After the instance starts, click **SSH** next to the VM in the instance list to open a browser-based terminal session. + +![Google Cloud Console VM instances page displaying running instance with green checkmark and SSH button in the Connect column#center](images/gcp-pubip-ssh.png "Connecting to a running C4A VM using SSH") + +A new browser window opens with a terminal connected to your VM. + +![Browser-based SSH terminal window with black background showing Linux command prompt and Google Cloud branding at top#center](images/gcp-shell.png "Terminal session connected to the VM") + +## What you've accomplished and what's next + +In this section, you provisioned a Google Axion C4A Arm VM and connected to it using SSH. + +Next, you'll need to install TimescaleDB and the required dependencies on your VM. diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/live-sensor-dashboard.md b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/live-sensor-dashboard.md new file mode 100644 index 0000000000..71b863de70 --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/live-sensor-dashboard.md @@ -0,0 +1,116 @@ +--- +title: Live Sensor Temperature Dashboard +weight: 8 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Create a Live Sensor Temperature Dashboard + +In this section, you will create a **real-time Grafana dashboard** that visualizes **live temperature data** stored in **TimescaleDB**. + +This dashboard continuously updates and helps you monitor sensor temperature changes in near real time. + +## Prerequisites + +Before proceeding, ensure the following are already completed: + +- TimescaleDB is installed and running +- Grafana is installed and accessible +- PostgreSQL (TimescaleDB) data source is configured in Grafana +- Live data ingestion into the `sensor_data` table is running + +You can verify live ingestion with: + +```bash +sudo -u postgres psql sensors -c "SELECT COUNT(*) FROM sensor_data;" +``` + +The count should increase over time. + +## Access Grafana + +Open Grafana in your browser: + +```bash +http://:3000 +``` + +Log in using your Grafana credentials. + +## Create a New Dashboard + +- From the left sidebar, select **Dashboards** +- Click **New dashboard** +- Select Add a **new visualization** + +You will be redirected to the Edit panel screen. + +## Configure the Live Sensor Query + +In the Query section: + +- Data source: PostgreSQL / TimescaleDB +- Query type: SQL +- Format: Time series + +![Grafana visualization configuration showing time series panel settings#center](images/data-source-visualization.png "Grafana visualization configuration") + +Paste the following query after pressing the "Code" button on the right of the query editor: + +```sql +SELECT + time AS "time", + temperature +FROM sensor_data +WHERE $__timeFilter(time) +ORDER BY time; +``` + +![Grafana SQL query editor showing TimescaleDB query with time filter#center](images/timescale-query.png "TimescaleDB SQL query editor") + +This query retrieves live sensor temperature data within the selected time range. + +Apply the following settings in the right-hand panel: + + - Visualization Settings + + - Visualization: Time series + - Panel title: Live Sensor Temperature + - Table view: Disabled + + - Time & Refresh Settings + + - Time range: Last 5 minutes + - Refresh interval: 5s + +These settings ensure the panel refreshes automatically with new data. + +## Validate the Live Sensor Panel + +Once configured, the panel should display a continuously updating temperature graph. + +![Grafana dashboard showing Live Sensor Temperature time series panel alt-txt#center](images/live-sensor-temperature.png "Live Sensor Temperature Panel") + +## Save the Dashboard + +- Click Save dashboard (top-right corner) +- Enter a name, for example: Live Sensor Monitoring Dashboard +- Click Save + +The dashboard is now active. + +## What you've accomplished and what's next + +You've successfully: + +- Built a complete time-series data pipeline on Google Cloud C4A Axion Arm-based processors +- Installed and configured TimescaleDB by building from source for optimal Arm64 performance +- Created a real-time sensor data ingestion pipeline using Python with hypertables and continuous aggregates +- Configured retention policies and indexes for production-ready time-series storage +- Installed Grafana and connected it to TimescaleDB as a data source +- Built a live sensor dashboard that automatically refreshes to display real-time temperature data +- Validated end-to-end data flow from ingestion through TimescaleDB to Grafana visualization + +You now have a production-ready time-series monitoring solution running natively on Arm infrastructure. This setup demonstrates how TimescaleDB and Grafana work together to provide comprehensive real-time monitoring for IoT and sensor workloads. You can extend this foundation by adding more sensors, creating additional dashboards, implementing alerting rules in Grafana, or optimizing TimescaleDB for your specific workload patterns. diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/sensor-data-ingestion.md b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/sensor-data-ingestion.md new file mode 100644 index 0000000000..cf41a8f02a --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/sensor-data-ingestion.md @@ -0,0 +1,292 @@ +--- +title: Real-Time Sensor Data Ingestion on Arm64 +weight: 6 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## Real-Time Sensor Data Ingestion + +In this section, you simulate real-time sensor data using Python and continuously ingest it into TimescaleDB running on an Arm64 VM. This creates a live time-series data stream that can later be visualized using Grafana. + +## Architecture Overview + +```text +Python Sensor Generator + | + v +TimescaleDB Hypertable +``` + +- A Python script acts as a sensor, generating temperature readings. +- Each reading is written to TimescaleDB. +- TimescaleDB stores the data in a hypertable, optimized for time-series workloads. + +This architecture mirrors real-world IoT and telemetry pipelines. + +## Install Python Dependencies (SUSE) + +```bash +cd $HOME +sudo zypper install -y \ + python3 \ + python3-pip \ + python3-psycopg2 +``` + +**Verify psycopg2:** + +```bash +python3 - < ingest.log 2>&1 & +``` + +This ensures the sensor generator continues running even after you close the terminal. + +### Verify Data Ingestion + +```bash +ps -ef | grep sensor_ingest.py +``` + +The output is similar to: + +```output +gcpuser 5398 2841 0 08:55 pts/0 00:00:00 python3 sensor_ingest.py +gcpuser 5401 2841 0 08:55 pts/0 00:00:00 grep --color=auto sensor_ingest.py +``` + +```bash +sudo -u postgres psql sensors -c "SELECT COUNT(*) FROM sensor_data;" +``` + +- Verified sensor ingestion by checking running processes and data count in TimescaleDB. +- The count should increase continuously. + +The output is similar to: + +```output +gcpuser@tsdb-suse-arm64:~> sudo -u postgres psql sensors -c "SELECT COUNT(*) FROM sensor_data;" + count +------- + 14 +(1 row) + +gcpuser@tsdb-suse-arm64:~> sudo -u postgres psql sensors -c "SELECT COUNT(*) FROM sensor_data;" + count +------- + 15 +(1 row) + +gcpuser@tsdb-suse-arm64:~> sudo -u postgres psql sensors -c "SELECT COUNT(*) FROM sensor_data;" + count +------- + 16 +(1 row) +``` + +## Time-Series Optimization + +These steps make TimescaleDB production-ready. + +### Create Index for Faster Queries + +```bash +sudo -u postgres psql sensors +``` + +Issue the following SQL command: + +```psql +CREATE INDEX ON sensor_data (sensor_id, time DESC); +``` + +This index: + +- Improves Grafana query performance +- Optimized for time-range scans + +### Enable Data Retention Policy + +Automatically remove old data after 7 days: + +```sql +SELECT add_retention_policy( + 'sensor_data', + INTERVAL '7 days' +); +``` + +- Prevents disk exhaustion +- Runs automatically in the background + +### Create Continuous Aggregate (Hourly Averages) + +```sql +CREATE MATERIALIZED VIEW sensor_hourly_avg +WITH (timescaledb.continuous) AS +SELECT + time_bucket('1 hour', time) AS bucket, + sensor_id, + AVG(temperature) AS avg_temp +FROM sensor_data +GROUP BY bucket, sensor_id; +``` + +Precomputes hourly averages per sensor for faster reporting. + +### Add Aggregate Refresh Policy + +```sql +SELECT add_continuous_aggregate_policy( + 'sensor_hourly_avg', + INTERVAL '1 day', + INTERVAL '1 hour', + INTERVAL '5 minutes' +); +``` + +Automates hourly aggregate refresh every 5 minutes for near real-time analytics. + +### What this means + +| Setting | Meaning | +| ------- | ------------------ | +| 1 day | Recompute last day | +| 1 hour | Skip newest data | +| 5 min | Refresh interval | + +### Validate Optimization + +```sql +SELECT * FROM sensor_hourly_avg LIMIT 5; +SELECT COUNT(*) FROM sensor_data; +``` + +Ensures ingestion and aggregation are running correctly and data is available for queries. + +The output is similar to: + +```output +postgres=# SELECT * FROM sensor_hourly_avg LIMIT 5; + bucket | sensor_id | avg_temp +------------------------+-----------+------------------- + 2026-02-17 08:00:00+00 | sensor-1 | 26.6380487804878 + 2026-02-17 08:00:00+00 | sensor-2 | 27.21 + 2026-02-17 08:00:00+00 | sensor-3 | 28.13413793103448 +(3 rows) + +postgres=# SELECT COUNT(*) FROM sensor_data; + count +------- + 2466 +(1 row) + + +``` + +Please press "CTRL-D" to exit. + +### Set the postgres password + +Lets set a password for postgres: + +```bash +sudo -u postgres psql +``` + +Then enter the new password: + +```sql +\password postgres +``` + +Save the password as it will be used in the next section. Please press "CTRL-D" to exit. + +## What you've accomplished and what's next + +You've successfully: + +- Built a fully functioning real-time sensor data ingestion pipeline +- Created TimescaleDB hypertables optimized for time-series storage +- Implemented retention policies to automatically manage data lifecycle +- Created continuous aggregates for faster reporting and analytics +- Set up automated refresh policies for near real-time analytics +- Set the postgres password for use in the Grafana plugin + +Next, you'll install Grafana, configure TimescaleDB as a data source, and build a live sensor temperature dashboard to visualize the real-time data you're ingesting. diff --git a/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/setup-timescaledb.md b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/setup-timescaledb.md new file mode 100644 index 0000000000..003a5744ba --- /dev/null +++ b/content/learning-paths/servers-and-cloud-computing/timescaledb-on-gcp/setup-timescaledb.md @@ -0,0 +1,201 @@ +--- +title: TimescaleDB Environment Setup on Arm64 +weight: 5 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +## TimescaleDB Environment Setup + +In this section, you prepare an Arm64-based SUSE Linux Enterprise Server (SLES) virtual machine and install TimescaleDB by building it from source. Building from source ensures the database extension is fully optimized for the Arm64 architecture, which is especially important for high-ingest and time-series workloads. + +## Architecture Overview + +```text +Linux Arm64 VM (SUSE) + | + v +PostgreSQL 15 + | + v +TimescaleDB 2.25.0 Extension +``` + +TimescaleDB provides time-series optimizations on top of PostgreSQL, making it ideal for high-ingest sensor workloads. + +## Install Build Dependencies (SUSE) + +TimescaleDB must be compiled against PostgreSQL, so development headers and build tools are required. + +```bash +sudo zypper refresh +``` + +```bash +sudo zypper install \ + cmake \ + gcc gcc-c++ make \ + git \ + libopenssl-devel \ + postgresql15 \ + postgresql15-server \ + postgresql15-server-devel \ + postgresql15-devel +``` + +### Important (SUSE note) + +If you are prompted about `readline-devel`, choose **Solution 1 (vendor change/downgrade)**. + +**Why this matters:** + +- This avoids dependency conflicts on SUSE. +- It ensures compatibility with PostgreSQL development libraries. + +## Initialize PostgreSQL + +Before using PostgreSQL, its data directory must be initialized. + +```bash +sudo -u postgres initdb -D /var/lib/pgsql/data +``` + +**What this does:** + +- Creates the PostgreSQL data directory. +- Initializes system tables and default configurations. +- Runs as the postgres system user for security. + +**Enable and start PostgreSQL:** + +```bash +sudo systemctl enable postgresql +sudo systemctl start postgresql +``` + + +**Verify PostgreSQL:** + +```bash +psql --version +``` + +The output is similar to: + +```output +psql (PostgreSQL) 15.10 +``` + +## Build TimescaleDB from Source (Arm64) + +Building TimescaleDB from source ensures native Arm64 compilation and optimal performance. + +### Clone the repository + +```bash +git clone https://github.com/timescale/timescaledb.git +cd timescaledb +git checkout 2.25.0 +``` + +- Download the official TimescaleDB source code. +- Check out version 2.25.0 to ensure version consistency throughout the learning path + +{{% notice Note %}} +According to the [release notes](https://github.com/timescale/timescaledb/releases/tag/2.16.0), TimescaleDB 2.16.0 introduces performance optimizations for DML on compressed chunks, improving upsert operations by **100×** and update/delete operations by **1000×** in some cases. + +The [Arm Ecosystem Dashboard](https://developer.arm.com/ecosystem-dashboard/) recommends **TimescaleDB 2.16.0** or higher for Arm platforms. +{{% /notice %}} + +### Bootstrap the configuration + +```bash +./bootstrap +``` + +### Invoke the build + +```bash +cd build +make -j$(nproc) +sudo make install +``` + +This compiles TimescaleDB natively for Arm64. + +## Enable TimescaleDB in PostgreSQL + +TimescaleDB must be preloaded when PostgreSQL starts. + +### Edit PostgreSQL configuration and add the timescaledb library + +Using a suitable editor and "sudo", edit **/var/lib/pgsql/data/postgresql.conf** and add the following line: + +```text +shared_preload_libraries = 'timescaledb' +``` + +This update: + +- Ensures TimescaleDB is loaded when PostgreSQL starts. +- Required for advanced TimescaleDB features like background workers and compression. + +### Restart PostgreSQL + +```bash +sudo systemctl restart postgresql +``` + +## Create Database and Enable Extension + +Now you enable TimescaleDB at the database level. + +```bash +sudo -u postgres psql +``` + +```psql +CREATE DATABASE sensors; +\c sensors +CREATE EXTENSION IF NOT EXISTS timescaledb; +``` + +What this does: + +- Creates a database named sensors. +- Switches to the sensors database. +- Enables TimescaleDB features within that database. + +**Verify version:** + +```psql +SELECT extversion FROM pg_extension WHERE extname='timescaledb'; +``` + +The output is similar to: + +```output +sensors=# SELECT extversion FROM pg_extension WHERE extname='timescaledb'; + extversion +------------ + 2.25.0 +(1 row) +``` + +Press "CTRL-D" to exit. + +**What this confirms:** + +- TimescaleDB is installed correctly. +- The expected version is active in the database. + +## What you've accomplished and what's next + +You've successfully: + +- Installed PostgreSQL 15 on SUSE Arm64 +- Built TimescaleDB 2.25.0 from source for optimal Arm64 performance +- Enabled TimescaleDB at the database level and verified the installation + +Next, you'll create a real-time sensor data ingestion pipeline using Python to continuously insert time-series data into TimescaleDB. diff --git a/content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/_index.md b/content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/_index.md index b7c338d600..e08910024c 100644 --- a/content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/_index.md @@ -1,35 +1,29 @@ --- -title: Secure Multi-Architecture Containers with Trivy on Azure Cobalt 100 (Arm64) - -draft: true -cascade: - draft: true +title: Scan multi-architecture containers with Trivy on Azure Cobalt 100 minutes_to_complete: 45 -who_is_this_for: This learning path is designed for developers and DevOps engineers who want to integrate security scanning into CI/CD pipelines for multi-architecture container images. +who_is_this_for: This is an introductory topic for developers and DevOps engineers who want to integrate security scanning into CI/CD pipelines for multi-architecture container images. learning_objectives: - - Provision an Azure Arm64 virtual machine using Azure console, with Ubuntu Pro 24.04 LTS as the base image - - Build multi-architecture (amd64/arm64) container images for Azure Cobalt 100 - - Install and configure Trivy on Arm64 Ubuntu systems - - Scan container images for vulnerabilities locally and in CI - - Configure self-hosted GitHub Actions Arm runners - - Enforce security gates in CI/CD pipelines based on vulnerability severity - - Generate and analyze JSON reports for compliance and audit purposes + - Build and scan multi-architecture container images using Trivy on Azure Cobalt 100 + - Configure self-hosted GitHub Actions Arm runners for CI/CD pipelines + - Enforce security gates in CI pipelines based on vulnerability severity prerequisites: - - A [Microsoft Azure](https://azure.microsoft.com/) account with access to Cobalt 100 based instances (Dpsv6) - - Docker installed and basic knowledge of containerization - - Familiarity with CI/CD concepts - - Basic knowledge of Linux command-line operations + - A [Microsoft Azure account](https://azure.microsoft.com/) with access to Cobalt 100 based instances (Dpsv6) + - Docker installed and basic knowledge of containerization + - Familiarity with CI/CD concepts + - Basic knowledge of Linux command-line operations + - Familiarity with GitHub Actions runners author: Pareena Verma ### Tags skilllevels: Introductory subjects: Containers and Virtualization -cloud_service_providers: Microsoft Azure +cloud_service_providers: + - Microsoft Azure armips: - Neoverse @@ -57,11 +51,11 @@ further_reading: link: https://docs.docker.com/ type: documentation - resource: - title: GitHub Actions Documentation - link: https://docs.github.com/en/actions + title: GitHub Actions runners + link: https://docs.github.com/en/actions/hosting-your-own-runners type: documentation - resource: - title: Microsoft Azure Cobalt 100 Overview + title: Azure Cobalt 100 processors link: https://techcommunity.microsoft.com/blog/azurecompute/announcing-the-preview-of-new-azure-vms-based-on-the-azure-cobalt-100-processor/4146353 type: documentation diff --git a/content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/background.md b/content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/background.md index c3f2051190..1ec6ed95e8 100644 --- a/content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/background.md +++ b/content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/background.md @@ -1,21 +1,35 @@ --- -title: "Overview" +title: Learn Azure Cobalt 100 Arm64 and Use Trivy for Security Scanning weight: 2 ### FIXED, DO NOT MODIFY layout: "learningpathall" --- -## Cobalt 100 Arm-based processor +## Key features and benefits of Azure Cobalt 100 -Azure Cobalt 100 is Microsoft’s first-generation Arm-based processor, designed for cloud-native, scale-out Linux workloads. Based on Arm’s Neoverse-N2 architecture, it is a 64-bit CPU that delivers improved performance and energy efficiency. Running at 3.4 GHz, it provides a dedicated physical core for each vCPU, ensuring consistent and predictable performance. Typical workloads include web and application servers, data analytics, open-source databases, and caching systems. +Azure Cobalt 100 is Microsoft's first-generation Arm-based processor, designed for cloud-native Linux workloads. Based on Arm's Neoverse-N2 architecture, it delivers improved performance-per-watt and cost efficiency. This makes it ideal for containerized workloads and CI/CD runners that run continuously. -To learn more, see the Microsoft blog [Announcing the preview of new Azure virtual machines based on the Azure Cobalt 100 processor](https://techcommunity.microsoft.com/blog/azurecompute/announcing-the-preview-of-new-azure-vms-based-on-the-azure-cobalt-100-processor/4146353). +Each vCPU is backed by a dedicated physical core, ensuring consistent, predictable performance. Running at 3.4 GHz, Cobalt 100 handles typical cloud workloads including web servers, data analytics, databases, and container platforms efficiently. -## Trivy +Learn more from the [Microsoft Azure Cobalt 100 blog post](https://techcommunity.microsoft.com/blog/azurecompute/announcing-the-preview-of-new-azure-vms-based-on-the-azure-cobalt-100-processor/4146353). -Trivy is an open-source vulnerability scanner designed to detect security issues in container images, filesystems, and infrastructure configurations. It is widely used in modern DevSecOps workflows to identify known vulnerabilities in operating system packages and application dependencies. +## Why Trivy matters in DevSecOps workflows + +Trivy is an open-source vulnerability scanner designed to detect security issues in container images, filesystems, and infrastructure configurations. It's a core component in modern DevSecOps workflows, which shift security scanning left in the development pipeline to catch vulnerabilities before they reach production. -You can use Trivy to perform fast and reliable security scans on container images built for multiple architectures, including Arm64. It helps teams shift security left by detecting vulnerabilities early in the development and CI/CD pipeline. +DevSecOps (Development, Security, and Operations) integrates security practices throughout the entire development lifecycle rather than as an afterthought. Trivy enables this by providing fast, reliable vulnerability detection on Arm64 and other architectures. -Learn more at the [Trivy official website](https://trivy.dev/) and in the [Trivy documentation](https://trivy.dev/docs/). +You can use Trivy to perform comprehensive security scans on container images built for multiple architectures, including Arm64. Detecting vulnerabilities early saves time and reduces risk downstream. + +See the [Trivy documentation](https://trivy.dev/docs/) for comprehensive information. + +## What you've accomplished and what's next + +You now understand the core technologies in this Learning Path: + +- Azure Cobalt 100, Microsoft's Arm-based processor designed for cloud efficiency +- Trivy, a security scanner that detects vulnerabilities in container images +- DevSecOps, the practice of integrating security throughout your development workflow + +Next, you'll create an Azure Cobalt 100 virtual machine to begin building and scanning container images. diff --git a/content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/instance.md b/content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/instance.md index e064907fc6..2a05b38e87 100644 --- a/content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/instance.md +++ b/content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/instance.md @@ -20,47 +20,57 @@ This Learning Path focuses on general-purpose virtual machines in the Dpsv6 seri While the steps to create this instance are included here for convenience, you can also refer to the [Deploy a Cobalt 100 virtual machine on Azure Learning Path](/learning-paths/servers-and-cloud-computing/cobalt/). -## Create an Arm-based Azure virtual machine +## Create an Arm-based Azure virtual machine -Creating a virtual machine based on Azure Cobalt 100 is no different to creating any other virtual machine in Azure. Follow the steps below to create an Azure virtual machine: +Creating a virtual machine based on Azure Cobalt 100 is no different to creating any other virtual machine in Azure. To create an Azure virtual machine: - Launch the Azure portal and navigate to **Virtual Machines**. - Select **Create**, and select **Virtual Machine** from the drop-down list. - Inside the **Basic** tab, fill in the instance details such as **Virtual machine name** and **Region**. - Select the image for your virtual machine (for example, Ubuntu Pro 24.04 LTS) and select **Arm64** as the VM architecture. -- In the **Size** field, select **See all sizes** and select the D-Series v6 family of virtual machines. +- In the **Size** field, select **See all sizes** and select the D-Series v6 family of virtual machines. - Select **D4ps_v6** from the list as shown in the diagram below: -![Azure portal VM creation — Azure Cobalt 100 Arm64 virtual machine (D4ps_v6) alt-text#center](images/instance.png "Select the D-Series v6 family of virtual machines") +![Azure Portal VM size selection showing the D-Series v6 (Dpsv6) family highlighted with D4ps_v6 option selected for Arm64 architecture alt-txt#center](images/instance.png "Select D4ps_v6 from the D-Series v6 family") -- For **Authentication type**, select **SSH public key**. {{% notice Note %}} +- For **Authentication type**, select **SSH public key**. + +{{% notice Note %}} Azure generates an SSH key pair for you and lets you save it for future use. This method is fast, secure, and easy for connecting to your virtual machine. {{% /notice %}} + - Fill in the **Administrator username** for your VM. -- Select **Generate new key pair**, and select **RSA SSH Format** as the SSH Key Type. {{% notice Note %}} +- Select **Generate new key pair**, and select **RSA SSH Format** as the SSH Key Type. + +{{% notice Note %}} RSA offers better security with keys longer than 3072 bits. -{{% /notice %}} +{{% /notice %}} + - Give your SSH key a key pair name. - In the **Inbound port rules**, select **HTTP (80)** and **SSH (22)** as the inbound ports, as shown below: -![Azure portal VM creation — Azure Cobalt 100 Arm64 virtual machine (D4ps_v6) alt-text#center](images/instance1.png "Allow inbound port rules") +![Azure Portal inbound port rules configuration showing HTTP (80) and SSH (22) selected as allowed incoming traffic alt-txt#center](images/instance1.png "Configure inbound port rules for HTTP and SSH access") - Now select the **Review + Create** tab and review the configuration for your virtual machine. It should look like the following: -![Azure portal VM creation — Azure Cobalt 100 Arm64 virtual machine (D4ps_v6) alt-text#center](images/ubuntu-pro.png "Review and create an Azure Cobalt 100 Arm64 VM") +![Azure Portal Review + Create tab showing VM configuration summary with Ubuntu Pro 24.04 LTS image, D4ps_v6 size, and networking settings configured alt-txt#center](images/ubuntu-pro.png "Review VM configuration before creation") - When you are happy with your selection, select the **Create** button and then **Download Private key and Create Resource** button. -![Azure portal VM creation — Azure Cobalt 100 Arm64 virtual machine (D4ps_v6) alt-text#center](images/instance4.png "Download private key and create resource") +![Azure Portal showing the Create button and Download Private key and Create Resource button to finalize VM creation alt-txt#center](images/instance4.png "Download SSH key and create the virtual machine") Your virtual machine should be ready and running in a few minutes. You can SSH into the virtual machine using the private key, along with the public IP details. -![Azure portal VM creation — Azure Cobalt 100 Arm64 virtual machine (D4ps_v6) alt-text#center](images/final-vm.png "VM deployment confirmation in Azure portal") +![Azure Portal showing successful VM deployment with green checkmark, VM name, resource group, and public IP address displayed in the confirmation notification alt-txt#center](images/final-vm.png "Successful VM deployment confirmation") -{{% notice Note %}} +{{% notice Note %}}To learn more about Arm-based virtual machine in Azure, see “Getting Started with Microsoft Azure” in [Get started with Arm-based cloud instances](/learning-paths/servers-and-cloud-computing/csp/azure).{{% /notice %}} -To learn more about Arm-based virtual machine in Azure, see “Getting Started with Microsoft Azure” in [Get started with Arm-based cloud instances](/learning-paths/servers-and-cloud-computing/csp/azure). +## What you've accomplished and what's next -{{% /notice %}} +You've successfully: + +- Created an Azure Cobalt 100 Arm-based virtual machine using the D-Series v6 (Dpsv6) family +- Selected Ubuntu Pro 24.04 LTS as the operating system +- Configured SSH authentication for secure access -Your Azure Cobalt 100 Arm64 virtual machine is now ready. Continue to the next step to install and configure Trivy. +Your Azure Cobalt 100 Arm64 virtual machine is now ready. Next, you'll build and scan multi-architecture container images using Docker and Trivy. diff --git a/content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/trivy-ci-integration.md b/content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/trivy-ci-integration.md deleted file mode 100644 index 5611ea1218..0000000000 --- a/content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/trivy-ci-integration.md +++ /dev/null @@ -1,314 +0,0 @@ ---- -title: Enforce Container Security with Trivy in CI using Arm Runners on Azure Cobalt 100 -weight: 5 - -### FIXED, DO NOT MODIFY -layout: learningpathall ---- - -## Overview - -In this module, you will integrate Trivy into a CI pipeline using a self-hosted Arm64 GitHub Actions runner on Azure Cobalt 100. - -You will: - -- Set up an Arm-based GitHub runner -- Securely configure secrets -- Run Trivy scans automatically in CI -- Enforce security gates on vulnerable images -- Upload vulnerability reports for auditing - -This demonstrates a real-world DevSecOps workflow running natively on Arm infrastructure. - -You will move from local scanning to fully automated security enforcement in CI. - -## Prerequisites - -Ensure that you have: - -- Completed the local Trivy scanning module -- A GitHub repository -- An Azure Cobalt 100 Arm64 Ubuntu VM running -- A multi-architecture container image pushed to Docker Hub - -These components are required for building a secure CI pipeline. - - -## Create a New GitHub Repository - -Open in your browser: https://github.com/new - -**Fill in:** - -- Repository name: trivy-arm-ci-demo (or any name you prefer) -- Visibility: Public or Private -- Do NOT initialize with README (keep it empty) - -**Click:** - -- Create repository - -You now have an empty GitHub repository ready to receive your project files. - -## Initialize Git Repository Locally - -On your Azure Arm64 VM: - -```bash -cd ~/trivy-multiarch-demo -git init -``` - -Turns your local project folder into a Git repository. - -**Add and Commit Project Files:** - -```bash -git add . -git commit -m "Multi-arch nginx image for Trivy scan" -``` -Stage and save your Dockerfile and demo files into Git history. - -**Link Local Repo to GitHub:** - -```bash -git branch -M main -git remote add origin https://github.com//trivy-arm-ci-demo.git -``` - -You can connect your local repository to the remote GitHub repository. - -**Push Code to GitHub:** - -```bash -git push -u origin main -``` - -Uploads your project files to GitHub and sets the main branch for future pushes. - -## Setup GitHub Actions Arm Runner - -Navigate in GitHub: - -```text -Settings → Actions → Runners → Add Runner -``` - -Choose: - -Linux → ARM64 - -GitHub will display setup commands. - -This prepares GitHub to register a self-hosted Arm64 runner. - -![GitHub Actions Arm64 self-hosted runner connected alt-txt#center](images/arm64-runner.png "Arm64 GitHub Runner Status") - -## Create Runner Directory on VM - -Create a workspace for the GitHub runner software. -```bash -mkdir actions-runner -cd actions-runner -``` - -## Download Runner Package - -Use the download command provided by GitHub: - -```bash -curl -o actions-runner-linux-arm64.tar.gz -L https://github.com/actions/runner/releases/download/v2.331.0/actions-runner-linux-arm64-2.331.0.tar.gz -tar xzf actions-runner-linux-arm64.tar.gz -``` -Downloads and extracts the Arm64-compatible runner. - -**Configure Runner:** - -```bash -./config.sh --url https://github.com// --token -``` - -Registers the runner with your GitHub repository. - -**Start Runner:** - -```bash -./run.sh -``` - -```output -√ Connected to GitHub - -Current runner version: '2.331.0' -2026-01-28 05:30:41Z: Listening for Jobs -``` - -## Configure GitHub Secrets - -**In your GitHub repository:** - -```text -Settings → Secrets → Actions → New repository secret -``` -Add the following secrets: - -| Name | Value | -| ----------------- | ----------------------------------- | -| `DOCKER_USERNAME` | Your Docker Hub username | -| `DOCKER_PASSWORD` | Docker Hub password or access token | -| `IMAGE_NAME` | trivy-multiarch-nginx | -| `IMAGE_TAG` | latest | - -![GitHub Actions secrets configuration alt-txt#center](images/secrets.png "GitHub Secrets Configuration") - -## Create CI Workflow -Create Workflow Directory - -```bash -mkdir -p .github/workflows -``` -**Create file:** - -```bash -nano .github/workflows/trivy-scan.yml -``` - -Add: -Defines a CI pipeline that scans images on every push. - -```yaml -name: Trivy Scan on Arm Runner - -on: - push: - branches: [ "main" ] - -jobs: - security-scan: - runs-on: self-hosted - - env: - DOCKER_USER: ${{ secrets.DOCKER_USERNAME }} - DOCKER_PASS: ${{ secrets.DOCKER_PASSWORD }} - IMAGE_NAME: ${{ secrets.IMAGE_NAME }} - IMAGE_TAG: ${{ secrets.IMAGE_TAG }} - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Login to Docker Hub - run: | - echo "$DOCKER_PASS" | docker login -u "$DOCKER_USER" --password-stdin - - - name: Pull multi-arch image - run: | - docker pull $DOCKER_USER/$IMAGE_NAME:$IMAGE_TAG - - - name: Run Trivy Scan - run: | - trivy image \ - --severity HIGH,CRITICAL \ - --exit-code 1 \ - $DOCKER_USER/$IMAGE_NAME:$IMAGE_TAG - - - name: Generate Trivy JSON Report - run: | - trivy image \ - --format json \ - -o trivy-report.json \ - $DOCKER_USER/$IMAGE_NAME:$IMAGE_TAG - - - name: Upload Report - uses: actions/upload-artifact@v4 - with: - name: trivy-report - path: trivy-report.json -``` - -## Trigger the CI Pipeline - -```bash -git add . -git commit -m "Add Trivy scan on Arm runner" -git push origin main -``` -Push triggers GitHub Actions automatically. - -## Verify CI Execution (Trivy Security Gate on Arm Runner) - -After pushing your code to GitHub, navigate to: - -```text -GitHub → Actions → Trivy Scan on Arm Runner -``` - -Select the latest workflow run. - -Expected Results: - -![GitHub Actions Trivy security scan workflow execution log alt-txt#center](images/security-scan.png "Trivy CI Security Scan Execution") - -You should observe the following: - -- The multi-architecture container image is pulled successfully on the Arm-based Azure Cobalt 100 runner -- Trivy performs a full vulnerability scan of the container image layers and installed packages -- The pipeline fails when HIGH or CRITICAL vulnerabilities are detected - -This failure is intentional and indicates that the security scan is functioning correctly. - -## How Trivy Works in This CI Pipeline - -Trivy is a container vulnerability scanner that: - -- Analyzes OS packages inside the image (like zlib, openssl, libc, etc.) -- Scans application dependencies (npm, pip, maven, etc. if present) -- Compares components against known CVE databases -- Assigns severity levels (LOW, MEDIUM, HIGH, CRITICAL) - -In this workflow: - -```bash ---severity HIGH,CRITICAL ---exit-code 1 -``` - -This means: - -- If Trivy finds any HIGH or CRITICAL vulnerability, it returns a non-zero exit code -- GitHub Actions marks the job as FAILED -- The image is blocked from moving forward in the pipeline - -This is known as a security gate. - -## Understanding the CI Scan Result -Is This Behavior Good or Bad? - -- This behavior is GOOD and expected in real-world CI/CD pipelines - -Modern DevSecOps practices integrate security tools like Trivy directly into Continuous Integration to automatically detect vulnerabilities. - -The pipeline is designed to: - -- Stop insecure container images early in the development lifecycle --Prevent vulnerable software from reaching staging or production environments -- Enforce security and compliance policies automatically - -**What a Failing Pipeline Means** - -When the Trivy scan fails the job: - -- Trivy successfully detected HIGH or CRITICAL vulnerabilities in the container image -- The security gate blocked the insecure image -- The CI pipeline protected downstream environments - -**Why This Matters in Enterprise CI/CD** - -In enterprise environments, automated security enforcement is mandatory. - -- Failing fast on vulnerabilities ensures: -- Faster remediation -- Reduced security risk -- Strong compliance posture - -This behavior confirms that your Arm-based CI pipeline is working correctly. diff --git a/content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/trivy-setup.md b/content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/trivy-setup.md index 618df8adf2..be92ebbd3e 100644 --- a/content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/trivy-setup.md +++ b/content/learning-paths/servers-and-cloud-computing/trivy-on-gcpp/trivy-setup.md @@ -1,5 +1,5 @@ --- -title: Build and Scan Multi-Architecture Container Images with Trivy on Azure Cobalt 100 (Arm64) +title: Build and scan multi-architecture container images with Trivy weight: 4 ### FIXED, DO NOT MODIFY @@ -8,31 +8,39 @@ layout: learningpathall ## Overview -In this module, you will build a multi-architecture container image and perform vulnerability scanning using Trivy on an Azure Cobalt 100 Arm64 Ubuntu VM. +In this section, you'll build a multi-architecture container image and perform vulnerability scanning using Trivy on an Azure Cobalt 100 Arm64 Ubuntu VM. You will: -- Install Docker on Arm64 -- Build and push multi-arch container images -- Install Trivy on Arm64 -- Scan container images locally +- Configure Docker Buildx for multi-architecture builds +- Create a demo container application +- Push a multi-architecture image to Docker Hub +- Install and verify Trivy on your Arm64 VM +- Perform local vulnerability scanning - Generate vulnerability reports ## Prerequisites -Ensure: +Before starting, ensure you have: -- Azure Cobalt 100 Arm64 Ubuntu VM -- Docker Hub account -- Internet connectivity +- An Azure Cobalt 100 Arm64 Ubuntu VM running +- Docker installed and configured on your VM +- A [Docker Hub account](https://hub.docker.com) -Verify architecture: + +To install Docker on your Arm64 VM, follow the [Docker installation guide](/install-guides/docker/). + +Once Docker is installed, verify it's running: ```bash +docker --version uname -m ``` +You should see Docker version information and `aarch64` architecture output. + ## Install Docker on Arm64 VM + Update your system and install required tools for Docker installation. ```bash @@ -40,16 +48,16 @@ sudo apt update sudo apt install -y ca-certificates curl gnupg lsb-release ``` -**Add Docker GPG key:** +## Add Docker GPG key -Adds Docker’s official signing key so packages are trusted. +Add Docker’s official signing key so packages are trusted. ```bash sudo mkdir -p /etc/apt/keyrings curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg ``` -**Add repository:** +## Add repository Register Docker’s package source for Arm64 Ubuntu. @@ -58,7 +66,7 @@ echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker. $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null ``` -**Install Docker:** +## Install Docker Install Docker Engine and Buildx for multi-architecture builds. @@ -67,15 +75,14 @@ sudo apt update sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin ``` -**Enable Docker without sudo:** +## Enable Docker without sudo ```bash sudo usermod -aG docker $USER newgrp docker ``` -Adds the user to the docker group and applies the new group permissions immediately, enabling non-root access to Docker. -**Verify:** +Adds the user to the docker group and applies the new group permissions immediately, enabling non-root access to Docker. Confirm Docker is running natively on Arm64. @@ -83,9 +90,15 @@ Confirm Docker is running natively on Arm64. docker info | grep Architecture ``` -## Configure Docker Buildx for Multi-Architecture Builds +You should see a result similar to: + +```output +Architecture: aarch64 +``` + +## Configure Docker Buildx for multi-architecture builds -**Create builder:** +Create builder: Create a special Docker builder capable of building images for multiple CPU architectures. @@ -93,7 +106,7 @@ Create a special Docker builder capable of building images for multiple CPU arch docker buildx create --name multiarch-builder --use ``` -**Initialize:** +## Initialize Prepare the builder to support multi-platform builds. @@ -101,62 +114,47 @@ Prepare the builder to support multi-platform builds. docker buildx inspect --bootstrap ``` -## Create Demo Application +The first command creates a builder instance capable of cross-platform builds. The second command initializes it to support multiple platforms. -Creates a workspace for the demo container application. +## Create a demo application -```bahs -mkdir trivy-multiarch-demo -cd trivy-multiarch-demo -``` - -## Create Dockerfile: +Set up a workspace for your demo container: ```bash -nano Dockerfile +mkdir $HOME/trivy-multiarch-demo +cd $HOME/trivy-multiarch-demo ``` -**Add:** - -Use NGINX as the base image and copy a custom webpage. +Create a `Dockerfile`: -```bash +```dockerfile FROM nginx:latest COPY index.html /usr/share/nginx/html/index.html ``` -## Create HTML file: - -```bash -nano index.html -``` - -**Add:** +Create an `index.html` file: -Create a simple webpage to confirm the container runs correctly. - -```bash +```html

Multi-Architecture NGINX on Azure Cobalt Arm64

``` -## Login to Docker Hub +## Authenticate with Docker Hub -**Run the login command:** +Run the Docker login command to authenticate: ```bash docker login ``` -- Docker will display a one-time device code and a login URL: +Docker displays a one-time device code and a login URL: ```text https://login.docker.com/activate ``` -**Steps to complete login:** +Steps to complete login: - Open the displayed URL in your web browser -- Sign in to your Docker Hub account (or create one if you don’t have it) - Enter the one-time confirmation code shown in the terminal - Click Confirm / Activate @@ -169,65 +167,73 @@ https://docs.docker.com/go/credential-store/ Login Succeeded ``` + This confirms your system is now authenticated with Docker Hub and ready to push or pull container images. -## Build and Push Multi-Architecture Image +Next, run the docker login again: + +```bash +docker login +``` + +Note the "Username" that is presented and save it, as you'll use it in the next step (as DOCKER_USERNAME below). + +Finally, create a personal access token in Docker Hub. Log into [Docker Hub](https://hub.docker.com) with your Docker username and password, then select "Account Settings" -> "Personal Access Token" to create a token. Select "Read-Only" privileges and copy and save the token, as it will become your "DOCKER_PASSWORD" in future steps. + +## Build and push multi-architecture images + +Build your image for both amd64 and arm64 architectures. Replace `` with your Docker username: ```bash +cd $HOME/trivy-multiarch-demo docker buildx build \ --platform linux/amd64,linux/arm64 \ -t /trivy-multiarch-nginx:latest \ --push . ``` -- Builds the container for both amd64 and arm64 -- Pushes the multi-arch image to Docker Hub - -This allows the same image to run on different CPU architectures. +This command builds the container for both architectures and pushes the multi-architecture image directly to Docker Hub. The same image specification can now run on both x86 and Arm systems. -![Trivy scanning multi-architecture container image alt-txt#center](images/trivy-multiarch.png "Trivy Multi-Arch Image Scan") +## Install and verify Trivy -## Install Trivy on Arm64 - -**Download:** - -Download the Arm64-compatible Trivy scanner. +Download the Arm64-compatible Trivy scanner: ```bash +cd $HOME wget https://github.com/aquasecurity/trivy/releases/download/v0.68.1/trivy_0.68.1_Linux-ARM64.deb ``` + {{% notice Note %}} The [Arm Ecosystem Dashboard](https://developer.arm.com/ecosystem-dashboard/) recommends Trivy 0.29.0 or later for Arm platforms. {{% /notice %}} -**Install:** - -Install Trivy on your system. +Install Trivy on your system: ```bash sudo dpkg -i trivy_0.68.1_Linux-ARM64.deb ``` -**Verify:** +Verify the installation: ```bash trivy version ``` -```output -Version: 0.68.1 -``` +You should see version information displayed. -## Scan Image Locally +## Perform local vulnerability scanning -**Run scan:** +Scan your Docker Hub image (replace `` with your username): ```bash trivy image /trivy-multiarch-nginx:latest ``` -Trivy analyzes the container image and lists security vulnerabilities. -## Generate JSON report +Trivy analyzes the container layers and reports all detected vulnerabilities with severity levels (LOW, MEDIUM, HIGH, CRITICAL). + +## Generate a JSON vulnerability report + +Create a machine-readable report for audits and CI pipelines: ```bash trivy image \ @@ -249,13 +255,14 @@ Create a machine-readable vulnerability report for audits and CI pipelines. 2026-01-23T06:42:33Z WARN Using severities from other vendors for some vulnerabilities. Read https://trivy.dev/docs/v0.68/guide/scanner/vulnerability#severity-selection for details. ``` -## Outcome +## What you've accomplished and what's next + +In this section, you: + +- Built and pushed a multi-architecture container image to Docker Hub +- Installed Trivy on your Arm64 VM +- Scanned your container image for vulnerabilities +- Generated a JSON vulnerability report for analysis -You have: +You now have a working local security scanning setup. Next, you'll integrate Trivy into a GitHub Actions CI/CD pipeline to automate security scanning on every code push. -- Installed Docker on Arm64 -- Built multi-architecture container images -- Pushed images to Docker Hub -- Installed Trivy on Azure Cobalt 100 -- Scanned images for vulnerabilities -- Generated security reports diff --git a/content/learning-paths/servers-and-cloud-computing/typescript-on-gcp/_index.md b/content/learning-paths/servers-and-cloud-computing/typescript-on-gcp/_index.md index 8a1292870a..8ca2cab57f 100644 --- a/content/learning-paths/servers-and-cloud-computing/typescript-on-gcp/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/typescript-on-gcp/_index.md @@ -21,7 +21,8 @@ author: Pareena Verma ##### Tags skilllevels: Introductory subjects: Web -cloud_service_providers: Google Cloud +cloud_service_providers: + - Google Cloud armips: - Neoverse diff --git a/content/learning-paths/servers-and-cloud-computing/vllm-acceleration/_index.md b/content/learning-paths/servers-and-cloud-computing/vllm-acceleration/_index.md index 049ec8fce8..be2944f312 100644 --- a/content/learning-paths/servers-and-cloud-computing/vllm-acceleration/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/vllm-acceleration/_index.md @@ -23,7 +23,8 @@ author: ### Tags skilllevels: Introductory subjects: ML -cloud_service_providers: AWS +cloud_service_providers: + - AWS armips: - Neoverse operatingsystems: diff --git a/content/learning-paths/servers-and-cloud-computing/whisper/_index.md b/content/learning-paths/servers-and-cloud-computing/whisper/_index.md index 8f05259578..26bc93c01e 100644 --- a/content/learning-paths/servers-and-cloud-computing/whisper/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/whisper/_index.md @@ -33,7 +33,8 @@ tools_software_languages: - Demo - Hugging Face -cloud_service_providers: AWS +cloud_service_providers: + - AWS further_reading: diff --git a/content/learning-paths/servers-and-cloud-computing/wordpress/_index.md b/content/learning-paths/servers-and-cloud-computing/wordpress/_index.md index 42ed1cb88c..6aa31bd865 100644 --- a/content/learning-paths/servers-and-cloud-computing/wordpress/_index.md +++ b/content/learning-paths/servers-and-cloud-computing/wordpress/_index.md @@ -17,7 +17,8 @@ learning_objectives: ### Tags skilllevels: Introductory subjects: Databases -cloud_service_providers: Oracle +cloud_service_providers: + - Oracle armips: - Neoverse diff --git a/themes/arm-design-system-hugo-theme/layouts/learning-paths/list.html b/themes/arm-design-system-hugo-theme/layouts/learning-paths/list.html index 356b2a2adf..f91ea99da7 100644 --- a/themes/arm-design-system-hugo-theme/layouts/learning-paths/list.html +++ b/themes/arm-design-system-hugo-theme/layouts/learning-paths/list.html @@ -113,7 +113,9 @@ tag-{{. | urlize}} {{ end }} {{ with .learning_path.Params.cloud_service_providers }} - tag-{{. | urlize}} + {{ range . }} + tag-{{. | urlize}} + {{ end }} {{ end }} {{ with .learning_path.Params.armips }} {{range .}} @@ -142,4 +144,4 @@ -{{end}} \ No newline at end of file +{{end}} diff --git a/themes/arm-design-system-hugo-theme/layouts/partials/footer/script-includes.html b/themes/arm-design-system-hugo-theme/layouts/partials/footer/script-includes.html index 46dd6ec14c..333ea4be6a 100644 --- a/themes/arm-design-system-hugo-theme/layouts/partials/footer/script-includes.html +++ b/themes/arm-design-system-hugo-theme/layouts/partials/footer/script-includes.html @@ -65,6 +65,43 @@ {{end}} + {{if .File}} {{if .File.TranslationBaseName}} {{if hasPrefix .File.TranslationBaseName "_review"}} @@ -72,5 +109,3 @@ {{end}} {{end}} {{end}} - - diff --git a/themes/arm-design-system-hugo-theme/layouts/partials/general-formatting/metadata-table.html b/themes/arm-design-system-hugo-theme/layouts/partials/general-formatting/metadata-table.html index 85b9bdb66b..efaee7650c 100644 --- a/themes/arm-design-system-hugo-theme/layouts/partials/general-formatting/metadata-table.html +++ b/themes/arm-design-system-hugo-theme/layouts/partials/general-formatting/metadata-table.html @@ -270,13 +270,13 @@

{{$page_h2}}

{{ .Params.subjects }} {{end}} - {{ if .Params.cloud_service_providers }} - + {{ range .Params.cloud_service_providers }} + - {{ .Params.cloud_service_providers }} + {{ . }} - {{end}} + {{ end }} {{ range .Params.operatingsystems }} @@ -399,13 +399,13 @@

{{$page_h2}}

{{ .Params.subjects }}
{{end}} - {{ if .Params.cloud_service_providers }} - + {{ range .Params.cloud_service_providers }} + - {{ .Params.cloud_service_providers }} + {{ . }} - {{end}} + {{ end }} {{ range .Params.operatingsystems }}