diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index fb6af22af..72d7958a3 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -2,7 +2,8 @@ Before submitting a pull request for a new Learning Path, please review [Create a Learning Path](https://learn.arm.com//learning-paths/cross-platform/_example-learning-path/) - [ ] I have reviewed Create a Learning Path -Please do not include any confidential information in your contribution. This includes confidential microarchitecture details and unannounced product information. +Please do not include any confidential information in your contribution. This includes confidential microarchitecture details and unannounced product information. No AI tool can be used to generate either content or code when creating a learning path or install guide. + - [ ] I have checked my contribution for confidential information By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of the Creative Commons Attribution 4.0 International License. diff --git a/.gitignore b/.gitignore index 68931b27e..8f8cfa8d6 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ package-lock.json # macOS files *.DS_Store +nohup.out diff --git a/.wordlist.txt b/.wordlist.txt index ec2682945..768f232ab 100644 --- a/.wordlist.txt +++ b/.wordlist.txt @@ -2032,4 +2032,210 @@ uv uvmpw libhugtlbfs mcpu -NoLSE \ No newline at end of file +NoLSE +AEMvA +ActAgent +AgentDrArmComponent +AgentsSettings +AppManager +ApplyMlMovement +AttributeError +BaseViewModel +BehaviorParametersComponent +BehaviourName +BehaviourParameters +BindingContext +CEF +CEF's +CanExecute +CanExecuteChanged +Cinemachine +CollateObservations +Compiling Dictionary... +ComputationTime +ContentPage +DComponent +DOM +DataPoint +DataPoints +DecisionRequester +DecisionRequesterComponent +DesktopApp +DirectX +DontDestroyOnLoad +ESM +EZ +FMADD +FontSize +FontWeight +GEMV +GenerateRandomMatrix +ICommand +INotifyPropertyChanged +ISB +JSONPlaceholder +LINQ +ListBox +LongPath +MLAgents +MLPlayerManagerComponent +MLPs +MVVM +MainPage +MainViewModel +MainWindow +MatrixHelper +MatrixMultiplication +MaxStep +MeasurePerformance +Misspelled words: +MlPlayerManager +MobileApp +MonoBehaviour +Multilayer +NextDouble +NuGet +NumberBox +NumberBoxExecutionCount +NumberBoxMatrixSize +NumericUpDown +OnActionReceived +OnLaunched +OnPropertyChanged +PFR +Perceptrons +PlayerInput +PlotResultsCommand +PropertyChanged +RESTful +RayPerceptionSensor +ReadyToPlay +Realtime +RunCalculationsCommand +Running Task: Markdown... +SME +SMSTART +SVCR +SVL +SerializeField +SetProperty +SettingsController +SfChart +SimpleCommand +Syncfusion +TFP +TODO +TableLayoutPanel +TargetType +TensorBoard +TextBlock +Theobald +ThirdPersonCameraMovement +Timestep +Typicode +UWP +UnityEngine +Using aspell to spellcheck Markdown +VfxService +ViewModel +ViewModels +Walkthrough +WinForms +WinUI +WinUIApp +WindowsForms +XAML +XY +XamarinForms +Xn +ZA +ZT +appOutDir +archs +async +axios +bitfield +blockMapFile +blockmap +bool +buttonStart +ce +cef +chromiumembedded +codebase +coe +computationTime +computationTimeHistory +distributables +doumentation +electronjs +executionCount +firstrun +gameplay +halfwords +incentivize +isPlayer +jQuery +jsonplaceholder +labelArchitecture +listBox +listBoxResults +mana +matLeft +matResult +matRight +matmul +microservice +mvvm +netdesktop +nsis +numericUpDownExecutionCount +numericUpDownMatrixSize +oneClick +onwards +perMachine +pypi +raycast +realtime +resizable +scrollable +sindresorhus +timeScale +toolkit's +windowsarm +winforms +winui +xamarin +xaml +advancedweb +buzzerPin +Compiling Dictionary... +cpio +digitalWrite +doBeep +gzipped +hu +initramfs +ino +kvmtool +ledOff +ledOn +ledPin +linenos +linenostart +MicroPython +Misspelled words: +motionPin +motionState +peizo +pir +PIR +pratapkute +println +PWM +RaspberryPi +skillset +supervisord +UARTs +USD +webserver \ No newline at end of file diff --git a/content/install-guides/_images/arduino_rp2040_boards.png b/content/install-guides/_images/arduino_rp2040_boards.png new file mode 100644 index 000000000..ad41e7d49 Binary files /dev/null and b/content/install-guides/_images/arduino_rp2040_boards.png differ diff --git a/content/install-guides/_images/arduino_rp2040_select.png b/content/install-guides/_images/arduino_rp2040_select.png new file mode 100644 index 000000000..60e15fdaf Binary files /dev/null and b/content/install-guides/_images/arduino_rp2040_select.png differ diff --git a/content/install-guides/anaconda.md b/content/install-guides/anaconda.md index 1500a691c..a847598be 100644 --- a/content/install-guides/anaconda.md +++ b/content/install-guides/anaconda.md @@ -2,7 +2,7 @@ additional_search_terms: - Python - TensorFlow -- Pytorch +- PyTorch - linux layout: installtoolsall @@ -94,7 +94,7 @@ eval "$($HOME/anaconda3/bin/conda shell.bash hook)" ## Get started -Test Anaconda Distribution by running simple TensorFlow and Pytorch examples. +Test Anaconda Distribution by running simple TensorFlow and PyTorch examples. ### TensorFlow @@ -140,7 +140,7 @@ The expected output format is below. Your version may be slightly different. tf.Tensor(342.34387, shape=(), dtype=float32) ``` -### Pytorch +### PyTorch Create a new conda environment named torch, install PyTorch, and activate the new environment. @@ -156,6 +156,7 @@ Using a text editor copy and paste the code below into a text file named `pytorc ```console import torch +print(torch.__version__) x = torch.rand(5,3) print(x) exit() @@ -170,14 +171,15 @@ python ./pytorch.py The expected output is similar to: ```output -tensor([[0.9825, 0.4797, 0.0978], - [0.2175, 0.8025, 0.9663], - [0.6342, 0.5408, 0.4781], - [0.0655, 0.7505, 0.9290], - [0.7643, 0.6878, 0.0993]]) +2.1.0 +tensor([[0.9287, 0.5931, 0.0239], + [0.3402, 0.9447, 0.8897], + [0.3161, 0.3749, 0.6848], + [0.8091, 0.6998, 0.7517], + [0.2873, 0.0549, 0.2914]]) ``` You are ready to use Anaconda Distribution. -Explore the many machine learning articles and examples using TensorFlow and Pytorch. +Explore the many machine learning articles and examples using TensorFlow and PyTorch. diff --git a/content/install-guides/arduino-pico.md b/content/install-guides/arduino-pico.md new file mode 100644 index 000000000..287eca021 --- /dev/null +++ b/content/install-guides/arduino-pico.md @@ -0,0 +1,78 @@ +--- +title: Arduino core for the Raspberry Pi Pico +author_primary: Michael Hall +additional_search_terms: +- arduino +- raspberrypi +- pico + +layout: installtoolsall +minutes_to_complete: 15 +official_docs: https://docs.aws.amazon.com/greengrass/v2/developerguide/quick-installation.html +prerequisites: Arduino IDE +test_images: +- ubuntu:latest +tool_install: true +multi_install: false +multitool_install_part: false + +weight: 1 +--- + +You can install the Arduino IDE and Arduino core software for the Raspberry Pi Pico and the Raspberry Pi Pico W. + +Arduino core is the software stack that powers Arduino devices and development boards. While the Raspberry Pi Pico isn't an Arduino board, it uses the same RP2040 SoC as the Arduino RP2040 Connect, and therefore can run the same Arduino core software. + +## Install Arduino IDE + +First, you need to install the Arduino IDE on your laptop or desktop. You can download it for your operating system from [the Arduino Software website](https://www.arduino.cc/en/software). Follow the provided instructions for installing the IDE. + +Start the IDE by clicking the Arduino IDE icon. + +## Install board support package + +The Arduino software is comprised of the core libraries and a Board Support Package that is specific to your device. You need to install the `Arduino Mbed OS RP2040 Boards` package to support the Raspberry Pi Pico. + +You can install this package by opening the `Boards Manager`. + +From the menu select `Tools -> Board -> Boards Manager`. + +When the `Boards Manager` opens search for `pico` and the `Arduino Mbed OS RP2040 Boards` will be displayed. Click the `Install` button to add it to the Arduino IDE. + +![Arduino Board Manager](/install-guides/_images/arduino_rp2040_boards.png) + +### Raspberry Pi Pico W + +The `Boards Manager` package for for `Arduino Mbed OS RP2040 Boards` does not include the Raspberry Pi Pico W. + +If you want to use the Pico W go to `File -> Preferences` (or `Arduino IDE -> Settings` on macOS) and enter the URL below into the `Additional Boards Manager URLs` field: + +```console +https://github.com/earlephilhower/arduino-pico/releases/download/global/package_rp2040_index.json +``` + +Return to `Tools -> Board -> Boards Manager` and search for `pico` and you will see a new entry `Raspberry Pi Pico/RP2040`. Click the `Install` button to add it to the Arduino IDE. + +## Select your board + +Once the support package is installed, you need to tell the Arduino IDE which supported board you will be using. From the `Tools -> Board` menu, find and select `Raspberry Pi Pico` or `Raspberry Pi Pico W` depending on your board type. + +![Arduino Board Selection](/install-guides/_images/arduino_rp2040_select.png) + +## Upload to your board + +Because the Raspberry Pi Pico doesn't come with the Arduino core software installed, the Arduino IDE won't recognize it. + +To fix that, you must upload a sketch. A sketch is another name for an Arduino software application. + +Go to `File -> Examples -> 01.Basics -> Blink` and load the sketch. + +Click the upload button (right arrow icon) and wait for the sketch to be uploaded. + +You should see the LED on your Raspberry Pi Pico blink on and off every second. + +{{% notice Note %}} +If you have trouble uploading a sketch, unplug the board, press and hold the `BOOTSEL` button on the board, plug it in, and then release the button. +{{% /notice %}} + +You are ready to start writing your own Arduino sketches for Raspberry Pi Pico. \ No newline at end of file diff --git a/content/install-guides/aws-copilot.md b/content/install-guides/aws-copilot.md new file mode 100644 index 000000000..3a4b076cb --- /dev/null +++ b/content/install-guides/aws-copilot.md @@ -0,0 +1,85 @@ +--- +additional_search_terms: +- cloud +- deploy + + +layout: installtoolsall +minutes_to_complete: 10 +author_primary: Jason Andrews +multi_install: false +multitool_install_part: false +official_docs: https://aws.github.io/copilot-cli/ +test_images: +- ubuntu:latest +test_link: null +test_maintenance: false +test_status: +- passed +title: AWS Copilot CLI +tool_install: true +weight: 1 +--- + +AWS Copilot CLI is an open source command line interface for running containers on AWS App Runner, Amazon Elastic Container Service (ECS), and AWS Fargate. + +It is available for a variety of operating systems and Linux distributions and supports the Arm architecture. + +## Before you begin + +This article provides quick solutions to install the latest version of AWS Copilot CLI for Ubuntu on Arm and macOS. + +Confirm you are using an Arm computer by running: + +```bash { target="ubuntu:latest" } +uname -m +``` + +If you are on Arm Linux the output should be: + +```output +aarch64 +``` + +If you are on macOS with Apple Silicon the output should be: + +```output +arm64 +``` + +## Download and install AWS Copilot CLI + +Copilot requires Docker. Refer to the [Docker](/install-guides/docker/) install guide for installation instructions. + +If you are using Docker on Linux you will need to install QEMU to build container images for both the `arm64` and the `amd64` architectures. + +```console +sudo apt-get install qemu-user-static +``` + +Docker Desktop for macOS includes the ability to build for multiple architectures, so you don't need to do anything extra. + +To install Copilot on Arm Linux: + +```console +sudo curl -Lo /usr/local/bin/copilot https://github.com/aws/copilot-cli/releases/latest/download/copilot-linux-arm64 \ + && sudo chmod +x /usr/local/bin/copilot \ + && copilot --help +``` + +To install Copilot on macOS: + +```console +curl -Lo copilot https://github.com/aws/copilot-cli/releases/latest/download/copilot-darwin && chmod +x copilot && sudo mv copilot /usr/local/bin/copilot && copilot --help +``` + +Verify Copilot CLI is installed by running: + +```console +copilot --version +``` +The version should be printed: + +```output +copilot version: v1.33.0 +``` \ No newline at end of file diff --git a/content/install-guides/pytorch.md b/content/install-guides/pytorch.md new file mode 100644 index 000000000..173736b6f --- /dev/null +++ b/content/install-guides/pytorch.md @@ -0,0 +1,255 @@ +--- +additional_search_terms: +- Python +- PyTorch +- linux + +layout: installtoolsall +minutes_to_complete: 15 +author_primary: Jason Andrews +draft: true +multi_install: false +multitool_install_part: false +official_docs: https://pytorch.org/docs/stable/index.html +test_images: +- ubuntu:latest +test_link: null +test_maintenance: true +test_status: +- passed +title: PyTorch +tool_install: true +weight: 1 +--- + +[PyTorch](https://pytorch.org/) is a popular end-to-end machine learning framework for Python used to build and deploy neural networks. It is used for tasks such as computer vision and natural language processing (NLP). + +Follow the instructions below to install and use PyTorch on Arm Linux. + +{{% notice Note %}} +Anaconda provides another way to install PyTorch. Refer to the [Anaconda install guide](/install-guides/anaconda/) to find out how to use PyTorch from Anaconda. The Anaconda version of PyTorch may be older than the version available using `pip`. +{{% /notice %}} + +## Before you begin + +Confirm you are using an Arm Linux system by running: + +```bash +uname -m +``` + +The output should be: + +```output +aarch64 +``` + +If you see a different result, you are not using an Arm computer running 64-bit Linux. + +PyTorch requires Python 3 and can be installed with `pip`. + +For Ubuntu run: + +```console +sudo apt install python-is-python3 python3-pip -y +``` + +For Amazon Linux run: + +```console +sudo dnf install python-pip -y +alias python=python3 +``` + +## Download and install PyTorch + +To install PyTorch run: + +```bash +sudo pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu +``` + +## Get started + +Test PyTorch: + +Use a text editor to copy and paste the code below into a text file named `pytorch.py` + +```console +import torch +print(torch.__version__) +x = torch.rand(5,3) +print(x) +exit() +``` + +Run the example code: + +```console +python ./pytorch.py +``` + +The expected output is similar to: + +```output +2.2.0 +tensor([[0.7358, 0.4406, 0.3058], + [0.7919, 0.9060, 0.2878], + [0.4064, 0.4203, 0.1987], + [0.7894, 0.6234, 0.8547], + [0.6395, 0.5062, 0.1668]]) +``` + +To get more details about the build options for PyTorch run: + +```console +python -c "import torch; print(*torch.__config__.show().split(\"\n\"), sep=\"\n\")" +``` + +The output will be similar to: + +```output +PyTorch built with: + - GCC 10.2 + - C++ Version: 201703 + - Intel(R) MKL-DNN v3.3.2 (Git Hash 2dc95a2ad0841e29db8b22fbccaf3e5da7992b01) + - OpenMP 201511 (a.k.a. OpenMP 4.5) + - LAPACK is enabled (usually provided by MKL) + - NNPACK is enabled + - CPU capability usage: NO AVX + - Build settings: BLAS_INFO=open, BUILD_TYPE=Release, CXX_COMPILER=/opt/rh/devtoolset-10/root/usr/bin/c++, CXX_FLAGS= -D_GLIBCXX_USE_CXX11_ABI=0 -fabi-version=11 -fvisibility-inlines-hidden -DUSE_PTHREADPOOL -DNDEBUG -DUSE_KINETO -DLIBKINETO_NOCUPTI -DLIBKINETO_NOROCTRACER -DUSE_QNNPACK -DUSE_PYTORCH_QNNPACK -DUSE_XNNPACK -DSYMBOLICATE_MOBILE_DEBUG_HANDLE -O2 -fPIC -Wall -Wextra -Werror=return-type -Werror=non-virtual-dtor -Werror=bool-operation -Wnarrowing -Wno-missing-field-initializers -Wno-type-limits -Wno-array-bounds -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-function -Wno-unused-result -Wno-strict-overflow -Wno-strict-aliasing -Wno-stringop-overflow -Wsuggest-override -Wno-psabi -Wno-error=pedantic -Wno-error=old-style-cast -Wno-missing-braces -fdiagnostics-color=always -faligned-new -Wno-unused-but-set-variable -Wno-maybe-uninitialized -fno-math-errno -fno-trapping-math -Werror=format -Wno-stringop-overflow, LAPACK_INFO=open, TORCH_VERSION=2.2.0, USE_CUDA=OFF, USE_CUDNN=OFF, USE_EIGEN_FOR_BLAS=ON, USE_EXCEPTION_PTR=1, USE_GFLAGS=OFF, USE_GLOG=OFF, USE_MKL=OFF, USE_MKLDNN=ON, USE_MPI=OFF, USE_NCCL=OFF, USE_NNPACK=ON, USE_OPENMP=ON, USE_ROCM=OFF, USE_ROCM_KERNEL_ASSERT=OFF, + +``` + +The configuration output is an advanced option to check the tools and configuration used to build PyTorch. + +# BFloat16 floating-point number format + +Recent Arm processors support the BFloat16 (BF16) number format in PyTorch. For example, AWS Graviton3 processors support BFloat16. + +To check if your system includes BFloat16 use the `lscpu` command: + +```console +lscpu | grep bf16 +``` + +If the `Flags` are printed, then you have a processor with BFloat16. + +```output +Flags: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 sve asimdfhm dit uscat ilrcpc flagm ssbs paca pacg dcpodp svei8mm svebf16 i8mm bf16 dgh rng +``` + +If the result is blank, you do not have a processor with BFloat16. + +BFloat16 provides improved performance and smaller memory footprint with the same dynamic range. You may want to experiment with BFloat16 when trading off accuracy with performance. + +You can use an environment variable to enable BFloat16: + +```console +export DNNL_DEFAULT_FPMATH_MODE=BF16 +``` + +## Transparent huge pages + +Transparent huge pages (TLP) provide an alternative method of utilizing huge pages for virtual memory. Enabling TLP may result in improved performance because it reduces the overhead of Translation Lookaside Buffer (TLB) lookups by using a larger virtual memory page size. + +To check if TLP is available on your system run: + +```console +cat /sys/kernel/mm/transparent_hugepage/enabled +``` + +The setting in brackets is your current setting. + +The most common output, `madvise`, is shown below: + +```output +always [madvise] never +``` + +If the setting is `never` you can change to `madvise` by running: + +```console +echo madvise | sudo tee /sys/kernel/mm/transparent_hugepage/enabled +``` + +With `madvise` you can use an environment variable to check performance with and without THP. + +To enable THP for PyTorch: + +```console +export THP_MEM_ALLOC_ENABLE=1 +``` + +## Profiling example + +Use a text editor to save the code below as `profile.py`: + +```python +import torch +from torch.profiler import profile, record_function, ProfilerActivity + +model = torch.hub.load('pytorch/vision:v0.10.0', 'resnet18', pretrained=True) + +batch_size = 64 + +input = torch.randn(batch_size, 3, 224, 224) + +with profile(activities=[ProfilerActivity.CPU]) as prof: + with record_function("mymodel_inference"): + for _ in range(10): + model(input) + +print(prof.key_averages().table(sort_by="self_cpu_time_total")) +``` + +Run the example and check the performance information printed: + +```console +python ./profile.py +``` + +The output will be similar to: + +```output +STAGE:2024-02-13 18:20:01 1981:1981 ActivityProfilerController.cpp:314] Completed Stage: Warm Up +STAGE:2024-02-13 18:20:16 1981:1981 ActivityProfilerController.cpp:320] Completed Stage: Collection +STAGE:2024-02-13 18:20:16 1981:1981 ActivityProfilerController.cpp:324] Completed Stage: Post Processing +--------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ + Name Self CPU % Self CPU CPU total % CPU total CPU time avg # of Calls +--------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ + aten::mkldnn_convolution 78.50% 11.266s 86.21% 12.373s 61.863ms 200 + aten::copy_ 7.59% 1.089s 7.59% 1.089s 4.950ms 220 + aten::max_pool2d_with_indices 6.24% 896.186ms 6.24% 896.186ms 89.619ms 10 + aten::native_batch_norm 5.90% 846.534ms 5.94% 852.410ms 4.262ms 200 + aten::clamp_min_ 0.57% 82.128ms 0.57% 82.128ms 483.106us 170 + mymodel_inference 0.52% 74.722ms 100.00% 14.352s 14.352s 1 + aten::add_ 0.33% 47.261ms 0.33% 47.261ms 168.789us 280 + aten::empty 0.12% 16.709ms 0.12% 16.709ms 7.595us 2200 + aten::convolution 0.04% 5.484ms 86.27% 12.381s 61.906ms 200 + aten::relu_ 0.04% 5.041ms 0.61% 87.169ms 512.759us 170 + aten::addmm 0.03% 4.414ms 0.03% 4.571ms 457.100us 10 + aten::_convolution 0.02% 3.173ms 86.23% 12.376s 61.878ms 200 + aten::_batch_norm_impl_index 0.02% 2.194ms 5.96% 854.955ms 4.275ms 200 + aten::clone 0.01% 2.030ms 7.64% 1.097s 5.485ms 200 + aten::as_strided_ 0.01% 2.028ms 0.01% 2.028ms 10.140us 200 + aten::sum 0.01% 1.553ms 0.01% 1.617ms 161.700us 10 + aten::empty_like 0.01% 1.431ms 0.06% 9.319ms 23.297us 400 + aten::conv2d 0.01% 1.322ms 86.28% 12.382s 61.912ms 200 + aten::batch_norm 0.01% 1.138ms 5.97% 856.093ms 4.280ms 200 + aten::contiguous 0.01% 880.000us 7.65% 1.098s 5.489ms 200 + aten::resize_ 0.00% 535.000us 0.00% 535.000us 2.675us 200 + aten::div_ 0.00% 409.000us 0.00% 684.000us 68.400us 10 + aten::mean 0.00% 331.000us 0.02% 2.632ms 263.200us 10 +<> +--------------------------------- ------------ ------------ ------------ ------------ ------------ ------------ +Self CPU time total: 14.352s +``` + +Experiment with the 2 environment variables for BFloat16 and THP and observe the performance differences. + +You can set each variable and run the test again and observe the new profile data and run time. + +You are ready to use PyTorch on Arm Linux. + +Explore the many machine learning articles and examples using PyTorch. diff --git a/content/learning-paths/cross-platform/_example-learning-path/overview.md b/content/learning-paths/cross-platform/_example-learning-path/overview.md index 9613c5fe3..77957a189 100644 --- a/content/learning-paths/cross-platform/_example-learning-path/overview.md +++ b/content/learning-paths/cross-platform/_example-learning-path/overview.md @@ -58,6 +58,8 @@ Learning Paths are about software development on Arm. Content is segmented into Learning Paths include only public information. Do not include confidential information, trade secrets, unannounced products, or any other information which should not be on a public website. +No AI tool can be used to generate either content or code when creating a learning path or install guide. + ## Is there a way to ask about my Learning Path idea? You can use [GitHub Discussions](https://github.com/ArmDeveloperEcosystem/arm-learning-paths/discussions) to ask questions about your Learning Path idea. You may want to do this if you are unsure about the usefulness of your concept or think it might already be covered by other content. You can also use it to determine the best category for your Learning Path. It is possible to have a Learning Path appear in multiple categories, so use GitHub discussions to ask. diff --git a/content/learning-paths/cross-platform/_example-learning-path/write-1-init.md b/content/learning-paths/cross-platform/_example-learning-path/write-1-init.md index 9de8c9ea7..759b83c3d 100644 --- a/content/learning-paths/cross-platform/_example-learning-path/write-1-init.md +++ b/content/learning-paths/cross-platform/_example-learning-path/write-1-init.md @@ -42,6 +42,12 @@ Result: The following markdown files are added to the `my-new-learning-path` dir | _review.md | This file contains simple questions and answers to reinforce knowledge gained from your Learning Path. | | _next_steps.md | This file contains the next recommended steps and related resources for the reader to use on completion of this Learning Path. | +### Order the content within the Learning Path + +Each markdown file has a field called `weight`. Use this field to order the way your content is displayed. The content with the lowest weight is displayed first. + +The _index.md is first with `weight: 1`. You should start with `weight: 2` for your next page (`how-to-1.md`) and `weight: 3` for the page you want displayed after that. + ### Create a new install guide Create a new install guide by copying an existing file in the `content/install-guides` directory and modifying the contents. diff --git a/content/learning-paths/cross-platform/docker/_review.md b/content/learning-paths/cross-platform/docker/_review.md index 38a2fcc05..4e14e0290 100644 --- a/content/learning-paths/cross-platform/docker/_review.md +++ b/content/learning-paths/cross-platform/docker/_review.md @@ -23,7 +23,7 @@ review: - questions: question: > - Can docker manifest be used to create a multi-architecdture image? + Can docker manifest be used to create a multi-architecture image? answers: - "Yes" - "No" diff --git a/content/learning-paths/cross-platform/docker/buildx.md b/content/learning-paths/cross-platform/docker/buildx.md index cb7a24a46..b885d6069 100644 --- a/content/learning-paths/cross-platform/docker/buildx.md +++ b/content/learning-paths/cross-platform/docker/buildx.md @@ -31,7 +31,7 @@ Docker Desktop provides the ability to build and run multi-architecture images u For Ubuntu, install emulation support using the command below. ```console -sudo apt-get install qemu-user-static +sudo apt-get install qemu-user-static -y ``` If emulation support is not installed on a Linux machine running Docker Engine, an error message similar to this one will occur: diff --git a/content/learning-paths/cross-platform/sme/ZA.png b/content/learning-paths/cross-platform/sme/ZA.png new file mode 100644 index 000000000..2ed5e7b61 Binary files /dev/null and b/content/learning-paths/cross-platform/sme/ZA.png differ diff --git a/content/learning-paths/cross-platform/sme/_index.md b/content/learning-paths/cross-platform/sme/_index.md new file mode 100644 index 000000000..7bde2094c --- /dev/null +++ b/content/learning-paths/cross-platform/sme/_index.md @@ -0,0 +1,45 @@ +--- +title: Get started with the Scalable Matrix Extension (SME) + +draft: true + +minutes_to_complete: 20 + +who_is_this_for: This is an introductory topic for software developers who want to learn about Scalable Matrix Extension (SME2) to optimize the processing of matrices. + +learning_objectives: + - Understand the SME architecture + - Build, run, and debug an SME2 single-precision floating-point matrix multiply example + +prerequisites: + - A computer with Arm DS installed + - Some understanding of the Arm Architecture + +author_primary: Stephen Theobald + +### Tags +skilllevels: Introductory +subjects: Performance and Architecture +armips: + - Armv9-A + +tools_software_languages: + - Coding + - Arm Development Studio + +operatingsystems: + - Bare-metal + +### Cross-platform metadata only +shared_path: true +shared_between: + - servers-and-cloud-computing + - laptops-and-desktops + - embedded-systems + +### 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/cross-platform/sme/_next-steps.md b/content/learning-paths/cross-platform/sme/_next-steps.md new file mode 100644 index 000000000..609bd1e5f --- /dev/null +++ b/content/learning-paths/cross-platform/sme/_next-steps.md @@ -0,0 +1,23 @@ +--- +next_step_guidance: You now have an understanding of the Scalable Matrix Extension. + +recommended_path: /learning-paths/servers-and-cloud-computing/sve + +further_reading: + - resource: + title: Introducing the Scalable Matrix Extension for the Armv9-A Architecture + link: https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/scalable-matrix-extension-armv9-a-architecture + type: blog + - resource: + title: The Scalable Matrix Extension (SME), for Armv9-A. Arm Architecture Reference Manual Supplement + link: https://developer.arm.com/documentation/ddi0616 + type: documentation + + +# ================================================================================ +# FIXED, DO NOT MODIFY +# ================================================================================ +weight: 21 # set to always be larger than the content in this path, and one more than 'review' +title: "Next Steps" # Always the same +layout: "learningpathall" # All files under learning paths have this same wrapper +--- diff --git a/content/learning-paths/cross-platform/sme/_review.md b/content/learning-paths/cross-platform/sme/_review.md new file mode 100644 index 000000000..4ba33dd37 --- /dev/null +++ b/content/learning-paths/cross-platform/sme/_review.md @@ -0,0 +1,43 @@ +--- +review: + - questions: + question: > + How large is the ZA storage? + answers: + - (SVL/8) x (SVL/8) bits + - (SVL/8) x (SVL/8) bytes + - (SVL/8) x (SVL/8) floats + correct_answer: 2 + explanation: > + The ZA storage is a two-dimensional array of (SVL/8) x (SVL/8) bytes. Since SVL is a power of two in the range 128 to 2048 bits, (SVL/8) will be a power of two in the range 16 to 256 bytes. + + - questions: + question: > + When is the ZA array activated at run-time? + answers: + - When the first FMOPA instruction is executed + - When an SMSTART instruction is executed + - When the processor is powered-up/reset (or the FVP model is started) + correct_answer: 2 + explanation: > + The ZA array is activated at run-time when an SMSTART instruction is executed. + + - questions: + question: > + How can the contents of the ZA tiles be viewed in the Arm Debugger? + answers: + - The ZA array is memory mapped, so the tiles can be viewed by their address in the Memory view + - The tiles reside on the stack, so can be viewed as an offset from the Stack Pointer + - The Registers view can show the contents of the various tiles in a variety of formats + correct_answer: 3 + explanation: > + The ZA tiles can be viewed in the Registers view in a variety of formats. Their contents can also be viewed in the Commands view by using `output` commands. + + +# ================================================================================ +# FIXED, DO NOT MODIFY +# ================================================================================ +title: "Review" # Always the same title +weight: 20 # Set to always be larger than the content in this path +layout: "learningpathall" # All files under learning paths have this same wrapper +--- diff --git a/content/learning-paths/cross-platform/sme/armds_sme2.png b/content/learning-paths/cross-platform/sme/armds_sme2.png new file mode 100644 index 000000000..80f1842c4 Binary files /dev/null and b/content/learning-paths/cross-platform/sme/armds_sme2.png differ diff --git a/content/learning-paths/cross-platform/sme/matrix-multiply-example.md b/content/learning-paths/cross-platform/sme/matrix-multiply-example.md new file mode 100644 index 000000000..079d000cc --- /dev/null +++ b/content/learning-paths/cross-platform/sme/matrix-multiply-example.md @@ -0,0 +1,100 @@ +--- +title: Matrix multiply example +weight: 3 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +A single-precision floating-point matrix multiply (vector length agnostic) bare-metal example to illustrate Scalable Matrix Extension (SME) is provided with Arm Development Studio, 2023.0 and later. + +The example shows a reference C implementation compared to an optimized version in assembler using SME2 instructions. + +The example builds with Arm Compiler for Embedded 6, executes on the Arm Architecture Envelope Model for A-class (AEMvA) Fixed Virtual Platform (FVP) model, and can be run/debugged with the Arm Debugger. + +The compiler, FVP model, and debugger are all provided in Arm Development Studio. + +## Import the example + +Open the Arm Development Studio IDE. Navigate to `File` > `Import...` > `Arm Development Studio` > `Examples & Programming Libraries` > `Examples` > `Armv9 Bare-Metal`, and select the `sme2_matmul_fp32` example. Using the text filter at the top of the pane can help locate the example. Click `Finish` to import. + +Alternatively extract the example on the command line from the `\examples\Bare-metal_examples_Armv9.zip` archive. For interactive debug (see later) using the IDE is recommended. + +Though the project is provided pre-compiled, you can also rebuild with the `Build` icon, or the `make` command from the command line. + +The example is compiled with `-march=armv9-a+sme2`, as set in the `makefile`. + +See the supplied `readme.html` for more information. + +## Load the example + +There is a supplied `sme2_matmul_fp32.launch` debug connection which has all necessary settings configured. + +Double-click on the `.launch` file to open. + +The AEMvA FVP model is a generic Arm implementation, which can be configured appropriately to enable Arm architectural features. + +The model is launched with appropriate settings to implement full SME2 support, including: + +`-C SVE.ScalableVectorExtension.has_sme=1 -C SVE.ScalableVectorExtension.has_sme2=1 -C SVE.ScalableVectorExtension.sme_veclens_implemented=7` + +The `has_sme=1` and `has_sme2=1` parameters enable support for SME and SME2 respectively. + +The `sme_veclens_implemented` parameter sets which SME vector lengths are implemented in the model. This is represented as a bitfield where bit[n]==1 implies a vector length of 128*2^n bits is implemented. The default `sme_veclens_implemented=7` means vector lengths of 128, 256, and 512 are supported. You can change this to fix a particular vector length by setting, for example, `sme_veclens_implemented=2` for 256 bits. +The vector length can also be read by software at run-time using the `RDSVL` instruction (see later). + +For more information on the model parameters, launch the model with `FVP_Base_AEMvA --list-params` + +Click `Debug` to launch the FVP and load the image. + +Execution can be controlled by the `Debug Control` pane icon bar (eg `Step Instruction` ), the command line (`stepi`), or short-cut keys (`F5`). + +## Understand the example + +![example image alt-text#center](armds_sme2.png "Figure 2. Debugging the SME2 example in Arm Development Studio") + +1. In the Registers view, expand AArch64 > System > ID > ID_AA64PFR1_EL1. Notice the SME bits are set to 2, meaning the SME2 architectural state and programmers model are implemented on this target. +2. This bit can also be inspected in the Commands view, by entering `output $AArch64::$System::$ID::$ID_AA64PFR1_EL1.SME`. Other bits in other registers may be inspected similarly. +3. In the Registers view, expand AArch64 > System > PSTATE > SVCR. Notice the ZA bit is currently 0, meaning the ZA array storage is invalid and not accessible. This will change to 1 later, when an SMSTART instruction is executed. +4. In `main.c`, observe that `main()` initializes the sizes (M, N, K) of the matrices, prints a welcome banner, then disables SVE and SIMD traps. +5. Set a breakpoint on the `disable_sve_traps` function with `break disable_sve_traps` and run to it (press F8). It is written in assembler. +6. In the Registers view, expand AArch64 > System > Secure > CPTR_EL3. To avoid SME, SVE, or SIMD instructions being trapped, the ESM and EZ bits must be set to 1 and the TFP bit must be cleared to 0, respectively, in CPTR_EL3. These bits reset to an architecturally unknown value on startup. +7. In the Debug Control view, select Stepping By Instruction (press F10) to switch stepping mode to instruction level. +8. Single-step (press F5) over the MRS, BIC, ORR, MSR, ISB instructions, and observe those bits are set/cleared as required. +9. The vector length is read at run-time using an `RDSVL` instruction. To see this, set a breakpoint on `sve_cntw()` with `break sve_cntw` and run to it (press F8). Single-step (press F5) the `RDSVL` instruction. The value returned by `RDSVL` in the specified register is SVL DIV 8. +10. In the Debug Control view, select Stepping By Source (press F10) to switch stepping mode back to C source level. +11. The C code then initializes the matLeft and matRight arrays with random single-precision floating-point values. The input (and result) matrices are stored in memory in a row-major memory layout. To see the input values matLeft and matRight, set a breakpoint on the call to matmul() on line 85 and run to it (press F8). Open the Memory view, select Xn (Format) > Float > 4 bytes, then enter either matLeft or matRight in the address field (top-left text entry box). +12. The C code then calls two functions, `matmul()` and `matmul_opt()`, to multiply the matLeft and matRight values. `matmul()` is a generic reference C implementation. `matmul_opt()` is an optimized version in assembler using SME2 instructions. +13. Set a breakpoint on `matmul()` with `break matmul` and run to it (press F8). In the Registers view, expand AArch64 > Core, and note the value of X5. Parameters are passed here in registers, so X5 (6th parameter) will contain the address where the matResult will be stored. +14. In the Disassembly view, notice that the inner loop calculations are performed using FMADD instructions on the SIMD single-precision registers S0, S1, S2. +15. In the Registers view, expand AArch64 > SIMD > Single. +16. In the Disassembly view, set a breakpoint on the FMADD instruction and run to it (press F8), and see the SIMD single-precision registers S0, S1, S2 changing. Run again and again. +17. Delete the breakpoint on the FMADD instruction, then step-out of the function (press F7) back into main(). +18. To see the result matResult, in the Memory view, enter the previously noted address from X5 in the address field. +19. Set a breakpoint on `matmul_opt()` with `break matmul_opt` and run to it (press F8). The optimized SME2 assembler is displayed in the Editor and Disassembly views. +20. In the Registers view, expand AArch64 > Core, and again note the value of X5, which will now contain the address where the matResult_opt will be stored. +21. In the Registers view, expand AArch64 > System > PSTATE > SVCR. Notice the ZA and SM bits are still 0. +22. Single-step (press F5) up to and over the SMSTART instruction, and see the ZA changing to 1, meaning the ZA array storage is now valid and accessible. +23. Set a breakpoint on the first instruction (`fmopa za2.s ...`) in `.Loop_K` at line 124 and run to it (press F8). This instruction performs a floating-point outer product and accumulate, putting the result in tile ZA2. +24. To see a full description of this instruction, or any other instruction in this example, simply hover the mouse over the instruction, in either the Editor or Disassembly views. +25. In the Registers view, expand AArch64 > SME > Tiles > ZA2H_S > F32 > [0]. This shows the contents of the zeroth row ('H') of tile ZA2 as floats, initially all zero. +26. In the Registers view, expand AArch64 > SME > Tiles > ZA2V_S > F32 > [0]. This shows the contents of the zeroth column ('V') of tile ZA2 as floats, also initially all zero. +27. Double-click on ZA2H_S.F32[0][0], and change its value to e.g. 99. Notice that ZA2V_S.F32[0][0] changes to the same value, because the zeroth element of the zeroth column is the same as the zeroth element of the zeroth row (the top-left element of the matrix). +28. In the Commands view, notice that the equivalent command is also shown, e.g. `set var $AARCH64::$SME::$Tiles::$ZA2H_S.F32[0][0] = 99`. This may be abbreviated to `set $ZA2H_S.F32[0][0] = 99`. +29. Single-step (press F5) to execute the `fmopa` instruction. Notice the values in ZA2H_S.F32[0] and ZA2V_S.F32[0] have updated. +30. Run again and again to see the values changing. You can do the same for ZA0, ZA1, etc. +31. The contents of the tile may also be viewed in the Commands view using the CLI, for example: + To view the zeroth element of the zeroth row, enter `output $ZA2H_S.F32[0][0]`. + To view all elements of the zeroth row, enter `output $ZA2H_S.F32[0]`. + To view all elements of the zeroth column, enter `output $ZA2V_S.F32[0]`. + To view the whole tile (as rows), enter `output $ZA2H_S.F32`. + To view the whole tile (as columns), enter `output $ZA2V_S.F32`. + Sequences of commands such as these may be easily scripted to construct groups of automated tests. +32. Delete all breakpoints, then set a breakpoint on the first instruction (`st1w {za0h.s[w13, #0]}, p4, [x10]`) in `.Ktail_end` at line 176 and run to it (press F8). This instruction stores words from ZA0, from the row in w13 to memory at the address in x10. +33. In the Commands view, enter `output /x $ZA0H_S.F32[$w13]` to show the w13th row of ZA0 in hexadecimal. +34. In the Commands view, enter `x /16 $x10` to show the memory at x10, or open a Memory view and enter x10 in the starting address field. +35. Single-step (press F5) to execute the st1w instruction. +36. In the Commands view, enter `x /16 $x10` again to show the memory at x10. Notice in the Commands view or the Memory view that the memory has been loaded with the content of the w13th row of ZA0. +37. Delete all breakpoints, then step-out of the function (press F7) back into main(). +38. To see the result matResult_opt, in the Memory view, enter the previously noted address from X5 in the address field. +39. Continue running until the example completes normally. diff --git a/content/learning-paths/cross-platform/sme/sme-intro.md b/content/learning-paths/cross-platform/sme/sme-intro.md new file mode 100644 index 000000000..760ac8ac8 --- /dev/null +++ b/content/learning-paths/cross-platform/sme/sme-intro.md @@ -0,0 +1,41 @@ +--- +title: Introducing Scalable Matrix Extension (SME) +weight: 2 + +### FIXED, DO NOT MODIFY +layout: learningpathall +--- + +The [Scalable Matrix Extension](https://community.arm.com/arm-community-blogs/b/architectures-and-processors-blog/posts/scalable-matrix-extension-armv9-a-architecture) (SME) is a system solution consisting of hardware components to efficiently process matrices. + +SME introduces: +* A register array storage ("ZA") capable of holding two-dimensional matrix tiles. +* A Streaming SVE processing mode, which supports execution of SVE2 instructions with a vector length that matches the tile width. +* Instructions that accumulate the outer product of two vectors into a tile. +* Instructions that transfer a vector to or from a tile row or column. +* System registers and fields that identify the presence and capabilities of SME, and enable and control its behavior at each Exception level. + +The ZA storage is a two-dimensional array of width SVL bits, and height equal to its width in bytes, in other words, (SVL / 8) rows. +SVL (the Effective Streaming SVE Vector Length) can be configured in software, and is a power of two in the range 128 to 2048 bits inclusive. + +The ZA storage is accessed as tiles. A ZA tile is a square, two-dimensional sub-array of elements within the ZA array, whose elements must all be the same width, which can be 8-bit, 16-bit, 32-bit, 64-bit, or 128-bit. + +The tile width is the same as the ZA storage width, which is always SVL bits. If N = SVL/8 then the ZA storage would be N rows x N bytes in size. +When accessing the tile as 16-bit halfwords, it would only be N/2 halfwords wide. Since tiles are square, it would also be N/2 rows high, and therefore there is space in the ZA storage for two such tiles. + +Similarly, when accessing 32-bit elements, tiles would have height and width both equal to N/4, so there would be four such tiles in the ZA storage. This trend continues so that there would be 16 tiles of element width 128-bits. + +You can read or write a ZA tile slice, which is a one-dimensional vector representing a complete row or column within a tile slice. + +![example image alt-text#center](ZA.png "Figure 1. The ZA storage, accessed by 32-bit elements, shown for SVL = 256 bits, and showing the mapping to horizontal and vertical slices of the four ZA0-3 tiles.") + +The Scalable Matrix Extension version 2 (SME2) extends the SME architecture to increase the number of applications that can benefit from the computational efficiency of SME, beyond its initial focus on outer products and matrix-matrix multiplication. SME2 adds: +* Data processing instructions with multi-vector operands and a multi-vector predication mechanism. +* A Range Prefetch hint instruction. +* Compressed neural network capability using dedicated lookup table instructions and outer product instructions that support binary neural networks. +* A 512-bit architectural register, ZT0, to support the lookup table feature. + +The new instructions enable SME2 to accelerate more workloads than the original SME, including GEMV, Non-Linear Solvers, Small and Sparse Matrices, and Feature Extraction or tracking. + +SME is represented by the architectural feature FEAT_SME. FEAT_SME is an optional extension from Armv9.2-A. +SME2 is represented by the architectural feature FEAT_SME2. FEAT_SME2 is an optional extension from Armv9.2-A. FEAT_SME2 requires FEAT_SME. diff --git a/content/learning-paths/laptops-and-desktops/electron/Figures/01.png b/content/learning-paths/laptops-and-desktops/electron/Figures/01.png new file mode 100644 index 000000000..1baf060a8 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/electron/Figures/01.png differ diff --git a/content/learning-paths/laptops-and-desktops/electron/Figures/02.png b/content/learning-paths/laptops-and-desktops/electron/Figures/02.png new file mode 100644 index 000000000..34bb9bbf9 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/electron/Figures/02.png differ diff --git a/content/learning-paths/laptops-and-desktops/electron/Figures/03.png b/content/learning-paths/laptops-and-desktops/electron/Figures/03.png new file mode 100644 index 000000000..76f24a268 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/electron/Figures/03.png differ diff --git a/content/learning-paths/laptops-and-desktops/electron/Figures/04.png b/content/learning-paths/laptops-and-desktops/electron/Figures/04.png new file mode 100644 index 000000000..5955139cc Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/electron/Figures/04.png differ diff --git a/content/learning-paths/laptops-and-desktops/electron/_index.md b/content/learning-paths/laptops-and-desktops/electron/_index.md new file mode 100644 index 000000000..fb1cf24b3 --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/electron/_index.md @@ -0,0 +1,36 @@ +--- +title: Develop cross-platform desktop applications with Electron on Windows on Arm + +minutes_to_complete: 30 + +who_is_this_for: This learning path is for developers who want to learn how to develop cross-platform desktop applications using the Electron Framework on Windows on Arm (WoA). + +learning_objectives: + - Implement a sample application using the electron framework on a Windows on Arm machine + - Learn how to create a multi platform build of the application + +prerequisites: + - A Windows on Arm computer such as [Windows Dev Kit 2023](https://learn.microsoft.com/en-us/windows/arm/dev-kit), Lenovo Thinkpad X13s running Windows 11 or a Windows on Arm[virtual machine](/learning-paths/cross-platform/woa_azure/). + - Node.js for Arm64. You can find the installer [here](https://nodejs.org/dist/v20.10.0/node-v20.10.0-arm64.msi) + - Any code editor; we recommend using [Visual Studio Code for Arm64](https://code.visualstudio.com/docs/?dv=win32arm64user). + +author_primary: Dawid Borycki + +### Tags +skilllevels: Introductory +subjects: Migration to Arm +armips: + - Cortex-A +operatingsystems: + - Windows +tools_software_languages: + - JavaScript + - HTML + - Visual Studio Code + +### 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/laptops-and-desktops/electron/_next-steps.md b/content/learning-paths/laptops-and-desktops/electron/_next-steps.md new file mode 100644 index 000000000..34174894f --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/electron/_next-steps.md @@ -0,0 +1,39 @@ +--- +# ================================================================================ +# Edit +# ================================================================================ + +next_step_guidance: > + You have learned how to implement cross-platform desktop applications with Electron. You might be interested in learning how to build a Windows on Arm native application with the .NET Framework. +# 1-3 sentence recommendation outlining how the reader can generally keep learning about these topics, and a specific explanation of why the next step is being recommended. + +recommended_path: "/learning-paths/laptops-and-desktops/win_net" +# Link to the next learning path being recommended(For example this could be /learning-paths/servers-and-cloud-computing/mongodb). + + +# further_reading links to references related to this path. Can be: + # Manuals for a tool / software mentioned (type: documentation) + # Blog about related topics (type: blog) + # General online references (type: website) + +further_reading: + - resource: + title: Electron + link: https://www.electronjs.org/blog/electron-doumentation + type: documentation + - resource: + title: Awesome Electron + link: https://github.com/sindresorhus/awesome-electron + type: website + - resource: + title: Electron support for Windows on Arm + link: https://www.electronjs.org/docs/latest/tutorial/windows-arm + type: documentation + +# ================================================================================ +# FIXED, DO NOT MODIFY +# ================================================================================ +weight: 21 # set to always be larger than the content in this path, and one more than 'review' +title: "Next Steps" # Always the same +layout: "learningpathall" # All files under learning paths have this same wrapper +--- diff --git a/content/learning-paths/laptops-and-desktops/electron/_review.md b/content/learning-paths/laptops-and-desktops/electron/_review.md new file mode 100644 index 000000000..6b3e16b48 --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/electron/_review.md @@ -0,0 +1,41 @@ +--- +# ================================================================================ +# Edit +# ================================================================================ + +# Always 3 questions. Should try to test the reader's knowledge, and reinforce the key points you want them to remember. + # question: A one sentence question + # answers: The correct answers (from 2-4 answer options only). Should be surrounded by quotes. + # correct_answer: An integer indicating what answer is correct (index starts from 0) + # explanation: A short (1-3 sentence) explanation of why the correct answer is correct. Can add additional context if desired + + +review: + - questions: + question: > + How do you style the Electron application? + answers: + - "Using CSS" + - "Using a style package" + - "Using an npm" + correct_answer: 1 + explanation: > + CSS is the common approach to style Electron applications + + - questions: + question: > + What is the JSONPlaceholder? + answers: + - "A library for JSON serialization" + - "A mock API for testing web apps" + correct_answer: 2 + explanation: > + JSONPlaceholder is a free online REST API service that serves as a mock server for testing and prototyping web applications + +# ================================================================================ +# FIXED, DO NOT MODIFY +# ================================================================================ +title: "Review" # Always the same title +weight: 20 # Set to always be larger than the content in this path +layout: "learningpathall" # All files under learning paths have this same wrapper +--- diff --git a/content/learning-paths/laptops-and-desktops/electron/how-to-1.md b/content/learning-paths/laptops-and-desktops/electron/how-to-1.md new file mode 100644 index 000000000..53488e239 --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/electron/how-to-1.md @@ -0,0 +1,312 @@ +--- +title: "Create the application using the electron framework" + +weight: 2 + +layout: "learningpathall" +--- + +## Introduction +Electron is an open-source framework to develop cross-platform desktop applications using web technologies such as HTML, CSS, and JavaScript. Developed and maintained by GitHub, Electron provides a seamless way to build native-like applications for Windows, macOS, and Linux, all from a single codebase. This capability has made Electron a popular choice to develop cross-platform desktop applications. + +In this learning path you will learn how to create a Desktop application for Windows on Arm64. The application will implement a common functionality of fetching and displaying the data from the REST API. You will use `JSONPlaceholder` as the API. + +`JSONPlaceholder` is a free online REST API service that serves as a mock server for testing and prototyping web applications. Created and maintained by Typicode, `JSONPlaceholder` provides a set of HTTP endpoints that mimic the behavior of a typical backend server, allowing developers to simulate interactions with a RESTful API without the need for a real backend. + +Here, you will use the posts endpoint of the `JSONPlaceholder`. This endpoint enables you to retrieve the list of hypothetical posts. + +You can find the the complete code used in the learning path [here](https://github.com/dawidborycki/electron-sample-app.git) + +## Before you begin +Before you begin, install Node.JS for Arm64. You can find the installer [here](https://nodejs.org/en/download). In this learning path, you will use version 20.10.0. The installation process is automatic. However, make sure to check the "Automatically install the necessary tools" checkbox so that it automatically installs the build tools for the NPM packages: + +![fig1](Figures/01.png) + +## Initialize the project +Start by initializing the project. To do this, open the command prompt or terminal and type the following commands: + +```console +mkdir electron-sample-app +cd electron-sample-app +npm init -y +``` + +The output will be similar to: + +```output +Wrote to C:\Users\db\electron-sample-app\package.json: + +{ + "name": "electron-sample-app", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC" +} +``` + +Next, install the dependencies: Electron framework, axios for making API requests, and jQuery for DOM manipulation: + +```console +npm install electron axios jquery --save +``` + +The output will be similar to: + +``` +added 85 packages, and audited 86 packages in 13s + +21 packages are looking for funding + run `npm fund` for details + +found 0 vulnerabilities +npm notice +npm notice New patch version of npm available! 10.2.3 -> 10.2.5 +npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.2.5 +npm notice Run npm install -g npm@10.2.5 to update! +npm notice +``` + +## View +You will now create the `index.html` file, which will act as the application view. Inside the `electron-sample-app` project folder create a new file, `index.html` with the contents below: + +```html + + + + Electron sample app + + + +

A list of posts

+ + + + + + + + + +
IDTitleBody
+ + + +``` + +This code will render the table comprised of three columns. Each column will display the ID, Title and Body parts of the post, which you will retrieve from the rest API. + +## Logic +You will now implement the logic, which is responsible for creating the application window and retrieving a collection of posts from the posts API of the [jsonplaceholder](https://jsonplaceholder.typicode.com/posts). + +Under the `electron-sample-app` project folder create a new file, `main.js` with the contents below: + +```JavaScript +const { app, BrowserWindow } = require('electron'); + +function createWindow() { + // Create the browser window + const win = new BrowserWindow({ + width: 1200, + height: 600, + webPreferences: { + nodeIntegration: true, + contextIsolation: false, + }, + }); + + // Load the index.html file + win.loadFile('index.html'); +} + +app.whenReady().then(createWindow); + +// Quit the app when all windows are closed (except on macOS) +app.on('window-all-closed', () => { + if (process.platform !== 'darwin') { + app.quit(); + } +}); + +app.on('activate', () => { + // Create a window when the app is activated (on macOS) + if (BrowserWindow.getAllWindows().length === 0) { + createWindow(); + } +}); +``` + +In the same directory, create a file named `renderer.js` with the contents below: + +```JavaScript +const axios = require('axios'); +const $ = require('jquery'); + +const apiUrl = 'https://jsonplaceholder.typicode.com/posts'; + +function fetchData() { + axios.get(apiUrl) + .then((response) => { + const data = response.data; + + // Clear the existing table data + $('#data-table tbody').empty(); + + // Append new data to the table + data.forEach((item) => { + $('#data-table tbody').append(` + + ${item.id} + ${item.title} + ${item.body} + + `); + }); + }) + .catch((error) => { + console.error('Error fetching data:', error); + }); +} + +// Add click event listener to the fetch button +$('#fetch-button').click(() => { + fetchData(); +}); +``` + +This file sends the request to the API to retrieve the list of posts. This list will be rendered in the view. + +## Package.json +Finally, update the `package.json` in your project folder with the code shown below: + +```JSON +{ + "name": "electron-sample-app", + "version": "1.0.0", + "description": "Electron application to retrieve data from API and display it in a table.", + "main": "main.js", + "scripts": { + "start": "electron ." + }, + "author": "Learning Path", + "license": "MIT", + "dependencies": { + "axios": "^0.21.4", + "electron": "^16.0.5", + "jquery": "^3.6.0" + } +} +``` + +This code does the following: +1. Sets the application entry point to `main.js` +2. Adds a start script which will invoke the **electron .** command to launch the electron app in a current directory +3. Specifies the license and dependencies +4. Configures the application name, description, and author + +## Run the application +To launch the application type the following command: + +```console +npm start +``` + +The application window appears. Then click the Fetch data button and you will see the list of posts: + +![fig2](Figures/02.png) + +## Styling an application +The application works fine. However, it uses default styles and does not look very pretty. To change this you can use cascading style sheets (CSS) as per web applications. To style the application, proceed as follows: + +1. In the application project folder, create a file named `styles.css` with the contents below: +```css +body { + font-family: Arial, sans-serif; + background-color: #f0f0f0; + margin: 0; + padding: 0; + } + + h1 { + text-align: center; + margin-top: 20px; + color: #333; + } + + table { + width: 80%; + margin: 20px auto; + border-collapse: collapse; + background-color: #fff; + } + + th, td { + padding: 10px; + text-align: left; + border-bottom: 1px solid #ddd; + } + + th { + background-color: #333; + color: #fff; + } + + button { + display: block; + margin: 20px auto; + padding: 10px 20px; + background-color: #333; + color: #fff; + border: none; + cursor: pointer; + } + + button:hover { + background-color: #555; + } +``` + +2. Update your `index.html` file to use `styles.css` as shown below: + +```html + + + + Electron sample app + + + + +

A list of posts

+ + + + + + + + + +
IDTitleBody
+ + + +``` + +3. Run the application **npm start** + +After the application launches, click the **Fetch data** button and you will see the following result: + +![fig3](Figures/03.png) + +## Checkpoint +You now have the application up and running. By default, it runs using the Arm64 architecture because we used Node.js for Arm64. To confirm this, open the Task Manager, click the Details tab and look for **electron.exe** processes: + +![fig4](Figures/04.png) + +In the next step, you will configure your application such that you can explicitly build it for x64 and Arm64 platforms. diff --git a/content/learning-paths/laptops-and-desktops/electron/how-to-2.md b/content/learning-paths/laptops-and-desktops/electron/how-to-2.md new file mode 100644 index 000000000..a6086da87 --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/electron/how-to-2.md @@ -0,0 +1,105 @@ +--- +title: "Build the cross-platform application" + +weight: 3 + +layout: "learningpathall" +--- + +## Objective +In this section you will build your application to run on both Arm64 and x64. + +## Electron Builder +Start by installing the Electron Builder: + +```console +npm install electron-builder --save-dev +``` + +The output will look similar to: +```output +added 191 packages, removed 12 packages, changed 18 packages, and audited 265 packages in 23s + +28 packages are looking for funding + run `npm fund` for details + +4 vulnerabilities (3 moderate, 1 high) + +To address all issues (including breaking changes), run: + npm audit fix --force + +Run `npm audit` for details. +``` + +Modify the `package.json` file in your project folder with the content shown below: + +```JSON +{ + "name": "electron-sample-app", + "version": "1.0.0", + "description": "Electron application to retrieve data from API and display it in a table.", + "main": "main.js", + "scripts": { + "start": "electron .", + "build": "electron-builder" + }, + "author": "Learning Path", + "license": "MIT", + "dependencies": { + "axios": "^0.21.4", + "jquery": "^3.6.0" + }, + "devDependencies": { + "electron-builder": "^22.12.0", + "electron": "^16.0.5" + }, + "build": { + "appId": "com.example.electron-sample-app", + "productName": "Electron Sample Application", + "directories": { + "output": "dist" + }, + "win": { + "target": [ + "nsis", + "nsis:x64" + ] + } + } +} +``` + +## Build the application +Finally, you can build the application using the following command: + +```console +npm run build +``` + +The above command generates the following output: + +```output +> electron-sample-app@1.0.0 build +> electron-builder + + • electron-builder version=24.9.1 os=10.0.22631 + • loaded configuration file=package.json ("build" field) + • writing effective config file=dist\builder-effective-config.yaml + • packaging platform=win32 arch=arm64 electron=16.2.8 appOutDir=dist\win-arm64-unpacked + • default Electron icon is used reason=application icon is not set + • packaging platform=win32 arch=x64 electron=16.2.8 appOutDir=dist\win-unpacked + • downloading url=https://github.com/electron/electron/releases/download/v16.2.8/electron-v16.2.8-win32-x64.zip size=85 MB parts=8 + • downloaded url=https://github.com/electron/electron/releases/download/v16.2.8/electron-v16.2.8-win32-x64.zip duration=3.87s + • building target=nsis file=dist\Electron Sample Application Setup 1.0.0.exe archs=arm64, x64 oneClick=true perMachine=false + • output file is locked for writing (maybe by virus scanner) => waiting for unlock... + • building block map blockMapFile=dist\Electron Sample Application Setup 1.0.0.exe.blockmap + ``` + + The Electron Builder will generate distributables of the application for Windows using two architectures x64 and Arm64. You will find them in the following folders: + * x64: \dist\win-unpacked + * Arm64: \dist\win-arm64-unpacked + + Each folder contains the executable `Electron Sample Application.exe`. Launch this executable from both folders. Then, open the Task Manager to check that both executables run as either x64 or Arm64 processes. + +## Summary +In this learning path, you created the Electron application designed to retrieve and display data from a mock API in a user-friendly table format. Developed using web technologies such as HTML, CSS, and JavaScript, this application leverages the Electron framework to seamlessly run on Windows. With added support for both x64 and Arm64 architectures on Windows, this application demonstrates the flexibility and adaptability of Electron in building robust desktop solutions for a wide range of use cases. diff --git a/content/learning-paths/laptops-and-desktops/win_cef/Figures/01.png b/content/learning-paths/laptops-and-desktops/win_cef/Figures/01.png new file mode 100644 index 000000000..fd7a4af01 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_cef/Figures/01.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_cef/Figures/02.png b/content/learning-paths/laptops-and-desktops/win_cef/Figures/02.png new file mode 100644 index 000000000..2c49159cf Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_cef/Figures/02.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_cef/Figures/03.png b/content/learning-paths/laptops-and-desktops/win_cef/Figures/03.png new file mode 100644 index 000000000..5911c6a03 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_cef/Figures/03.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_cef/Figures/04.png b/content/learning-paths/laptops-and-desktops/win_cef/Figures/04.png new file mode 100644 index 000000000..84dd548df Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_cef/Figures/04.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_cef/_index.md b/content/learning-paths/laptops-and-desktops/win_cef/_index.md new file mode 100644 index 000000000..e46991058 --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/win_cef/_index.md @@ -0,0 +1,37 @@ +--- +title: Develop desktop applications with Chromium Embedded Framework on Windows on Arm + +minutes_to_complete: 30 + +who_is_this_for: This learning path is for developers who want to learn how to use web technologies for developing Desktop apps on Windows on Arm (WoA). + +learning_objectives: + - Create and build a Chromium Embedded Framework project using CMake + - Modify and style the application + +prerequisites: + - A Windows on Arm computer such as [Windows Dev Kit 2023](https://learn.microsoft.com/en-us/windows/arm/dev-kit), Lenovo Thinkpad X13s running Windows 11 or a Windows on Arm[virtual machine](/learning-paths/cross-platform/woa_azure/). + - Visual Studio 2022. + +author_primary: Dawid Borycki + +### Tags +skilllevels: Introductory +subjects: Migration to Arm +armips: + - Cortex-A +operatingsystems: + - Windows +tools_software_languages: + - C++ + - CMake + - HTML + - JavaScript + - CSS + +### 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/laptops-and-desktops/win_cef/_next-steps.md b/content/learning-paths/laptops-and-desktops/win_cef/_next-steps.md new file mode 100644 index 000000000..164011a9a --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/win_cef/_next-steps.md @@ -0,0 +1,35 @@ +--- +# ================================================================================ +# Edit +# ================================================================================ + +next_step_guidance: > + You have learned how to implement desktop applications with the Chromium Embedded Framework (CEF). You might be interested in learning how to use web technologies for creating cross-platform desktop apps. +# 1-3 sentence recommendation outlining how the reader can generally keep learning about these topics, and a specific explanation of why the next step is being recommended. + +recommended_path: "/learning-paths/laptops-and-desktops/electron" +# Link to the next learning path being recommended(For example this could be /learning-paths/servers-and-cloud-computing/mongodb). + + +# further_reading links to references related to this path. Can be: + # Manuals for a tool / software mentioned (type: documentation) + # Blog about related topics (type: blog) + # General online references (type: website) + +further_reading: + - resource: + title: CEF GitHub Repository + link: https://github.com/chromiumembedded/cef + type: documentation + - resource: + title: Chromium Embedded Framework + link: https://en.wikipedia.org/wiki/Chromium_Embedded_Framework + type: website + +# ================================================================================ +# FIXED, DO NOT MODIFY +# ================================================================================ +weight: 21 # set to always be larger than the content in this path, and one more than 'review' +title: "Next Steps" # Always the same +layout: "learningpathall" # All files under learning paths have this same wrapper +--- diff --git a/content/learning-paths/laptops-and-desktops/win_cef/_review.md b/content/learning-paths/laptops-and-desktops/win_cef/_review.md new file mode 100644 index 000000000..3a1720a87 --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/win_cef/_review.md @@ -0,0 +1,42 @@ +--- +# ================================================================================ +# Edit +# ================================================================================ + +# Always 3 questions. Should try to test the reader's knowledge, and reinforce the key points you want them to remember. + # question: A one sentence question + # answers: The correct answers (from 2-4 answer options only). Should be surrounded by quotes. + # correct_answer: An integer indicating what answer is correct (index starts from 0) + # explanation: A short (1-3 sentence) explanation of why the correct answer is correct. Can add additional context if desired + + +review: + - questions: + question: > + Do you need to rebuild the CEF application if you modify the page to be rendered? + answers: + - "Yes" + - "No" + correct_answer: 2 + explanation: > + CEF application will render an updated page without the need of rebuilding the CEF application + + - questions: + question: > + What is the `CefBrowserProcessHandler`? + answers: + - "It is an interface exclusive to the browser process" + - "It is an interface for downloading Chrome Web Browser" + - "It is a class to download CEF" + correct_answer: 1 + explanation: > + CefBrowserProcessHandler is an interface exclusive to the browser process, invoked only within that context. + + +# ================================================================================ +# FIXED, DO NOT MODIFY +# ================================================================================ +title: "Review" # Always the same title +weight: 20 # Set to always be larger than the content in this path +layout: "learningpathall" # All files under learning paths have this same wrapper +--- diff --git a/content/learning-paths/laptops-and-desktops/win_cef/how-to-1.md b/content/learning-paths/laptops-and-desktops/win_cef/how-to-1.md new file mode 100644 index 000000000..47156388f --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/win_cef/how-to-1.md @@ -0,0 +1,302 @@ +--- +title: "Create a Chromium Embedded Framework Project" + +weight: 2 + +layout: "learningpathall" +--- + +## Introduction +The Chromium Embedded Framework (CEF) is a robust and versatile open-source framework that simplifies the embedding of Chromium-based web browsers into other applications. Primarily written in C++, CEF enables developers to seamlessly integrate web functionalities into desktop programs. It leverages modern web technologies, enriching user interfaces with dynamic web content and utilizing a familiar web development stack in desktop application development. CEF's widespread adoption is attributed to its high performance, extensive features, and ability to deliver consistent, cross-platform web experiences in native applications. + +In this learning path, you will learn how to create a desktop application for Windows on Arm64. This application will fetch and display data from `JSONPlaceholder`, a mock REST API for demonstration purposes. Fetching and displaying data from an API is a standard functionality in web applications, and through this process, you will learn how to effectively utilize web technologies in a desktop app. + +## Before you begin +Before you begin, install the following: +1. CMake for Arm64 [link](https://github.com/Kitware/CMake/releases/download/v3.28.1/cmake-3.28.1-windows-arm64.msi). During an installation check **Add CMake to the system PATH for the current user** as shown below + +![fig1](Figures/01.png) + +2. Visual Studio 2022 with Desktop development with C++ workload + +## Prepare the project +Start by downloading the Standard Distribution of the CEF binary for [Windows on Arm64](https://cef-builds.spotifycdn.com/index.html#windowsarm64). In this learning path, you will use the following CEF version: +120.1.10+g3ce3184+chromium-120.0.6099.129 / Chromium 120.0.6099.129. + +Extract the downloaded file to a folder. Right-click the downloaded file, select 'Extract all...', and name the folder 'cef-binary'. Once the extraction process completes, you will find a folder named 'cef_binary_120.1.10+g3ce3184+chromium-120.0.6099.129_windowsarm64' within 'cef-binary'. Note that the exact name might differ if you have downloaded a different CEF version. + +Next, rename the folder `cef_binary_120.1.10+g3ce3184+chromium-120.0.6099.129_windowsarm64` to `windowsarm64` for simplicity. + +Now, use CMake to prepare the build files for Visual Studio 2022 and the Arm64 architecture. Open the Command Prompt or a Terminal, and proceed with the following steps: + +```console +cd +cd windowsarm64 + +cmake -G "Visual Studio 17" -A arm64 -B build +``` +Replace in the command above to the directory path on your machine where you downloaded the CEF binary. + +The output of this command will look like: + +```output +C:\cef_binary\windowsarm64>cmake -G "Visual Studio 17" -A arm64 -B build +-- Selecting Windows SDK version 10.0.22621.0 to target Windows 10.0.22631. +-- The C compiler identification is MSVC 19.38.33133.0 +-- The CXX compiler identification is MSVC 19.38.33133.0 +-- Detecting C compiler ABI info +-- Detecting C compiler ABI info - done +-- Check for working C compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.38.33130/bin/Hostarm64/arm64/cl.exe - skipped +-- Detecting C compile features +-- Detecting C compile features - done +-- Detecting CXX compiler ABI info +-- Detecting CXX compiler ABI info - done +-- Check for working CXX compiler: C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.38.33130/bin/Hostarm64/arm64/cl.exe - skipped +-- Detecting CXX compile features +-- Detecting CXX compile features - done +-- *** CEF CONFIGURATION SETTINGS *** +-- Generator: Visual Studio 17 2022 +-- Platform: Windows +-- Project architecture: arm64 +-- Binary distribution root: C:/cef_binary/windowsarm64 +-- Visual Studio ATL support: ON +-- CEF sandbox: ON +-- Standard libraries: comctl32.lib;gdi32.lib;rpcrt4.lib;shlwapi.lib;ws2_32.lib;Advapi32.lib;dbghelp.lib;Delayimp.lib;ntdll.lib;OleAut32.lib;PowrProf.lib;Propsys.lib;psapi.lib;SetupAPI.lib;Shell32.lib;Shcore.lib;Userenv.lib;version.lib;wbemuuid.lib;WindowsApp.lib;winmm.lib +-- Compile defines: __STDC_CONSTANT_MACROS;__STDC_FORMAT_MACROS;WIN32;_WIN32;_WINDOWS;UNICODE;_UNICODE;WINVER=0x0A00;_WIN32_WINNT=0x0A00;NTDDI_VERSION=NTDDI_WIN10_FE;NOMINMAX;WIN32_LEAN_AND_MEAN;_HAS_EXCEPTIONS=0;PSAPI_VERSION=1;CEF_USE_SANDBOX;CEF_USE_ATL +-- Compile defines (Debug): _HAS_ITERATOR_DEBUGGING=0 +-- Compile defines (Release): NDEBUG;_NDEBUG +-- C compile flags: /MP;/Gy;/GR-;/W4;/WX;/wd4100;/wd4127;/wd4244;/wd4324;/wd4481;/wd4512;/wd4701;/wd4702;/wd4996;/Zi +-- C compile flags (Debug): /MTd;/RTC1;/Od +-- C compile flags (Release): /MT;/O2;/Ob2;/GF +-- C++ compile flags: /MP;/Gy;/GR-;/W4;/WX;/wd4100;/wd4127;/wd4244;/wd4324;/wd4481;/wd4512;/wd4701;/wd4702;/wd4996;/Zi /std:c++17 +-- C++ compile flags (Debug): /MTd;/RTC1;/Od +-- C++ compile flags (Release): /MT;/O2;/Ob2;/GF +-- Exe link flags: /MANIFEST:NO;/LARGEADDRESSAWARE;/DELAYLOAD:api-ms-win-core-winrt-error-l1-1-0.dll;/DELAYLOAD:api-ms-win-core-winrt-l1-1-0.dll;/DELAYLOAD:api-ms-win-core-winrt-string-l1-1-0.dll;/DELAYLOAD:advapi32.dll;/DELAYLOAD:comctl32.dll;/DELAYLOAD:comdlg32.dll;/DELAYLOAD:credui.dll;/DELAYLOAD:cryptui.dll;/DELAYLOAD:d3d11.dll;/DELAYLOAD:d3d9.dll;/DELAYLOAD:dwmapi.dll;/DELAYLOAD:dxgi.dll;/DELAYLOAD:dxva2.dll;/DELAYLOAD:esent.dll;/DELAYLOAD:gdi32.dll;/DELAYLOAD:hid.dll;/DELAYLOAD:imagehlp.dll;/DELAYLOAD:imm32.dll;/DELAYLOAD:msi.dll;/DELAYLOAD:netapi32.dll;/DELAYLOAD:ncrypt.dll;/DELAYLOAD:ole32.dll;/DELAYLOAD:oleacc.dll;/DELAYLOAD:propsys.dll;/DELAYLOAD:psapi.dll;/DELAYLOAD:rpcrt4.dll;/DELAYLOAD:rstrtmgr.dll;/DELAYLOAD:setupapi.dll;/DELAYLOAD:shell32.dll;/DELAYLOAD:shlwapi.dll;/DELAYLOAD:uiautomationcore.dll;/DELAYLOAD:urlmon.dll;/DELAYLOAD:user32.dll;/DELAYLOAD:usp10.dll;/DELAYLOAD:uxtheme.dll;/DELAYLOAD:wer.dll;/DELAYLOAD:wevtapi.dll;/DELAYLOAD:wininet.dll;/DELAYLOAD:winusb.dll;/DELAYLOAD:wsock32.dll;/DELAYLOAD:wtsapi32.dll;/STACK:0x800000 +-- Exe link flags (Debug): /DEBUG +-- Exe link flags (Release): +-- Shared link flags: +-- Shared link flags (Debug): /DEBUG +-- Shared link flags (Release): +-- CEF Binary files: chrome_elf.dll;d3dcompiler_47.dll;libcef.dll;libEGL.dll;libGLESv2.dll;snapshot_blob.bin;v8_context_snapshot.bin;vk_swiftshader.dll;vk_swiftshader_icd.json;vulkan-1.dll +-- CEF Resource files: chrome_100_percent.pak;chrome_200_percent.pak;resources.pak;icudtl.dat;locales +-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE) +CMake Warning at CMakeLists.txt:254 (message): + Doxygen must be installed to generate API documentation. + + +-- Configuring done (3.1s) +-- Generating done (0.0s) +-- Build files have been written to: C:/cef_binary/windowsarm64/build +``` + +## Build the project +The previous command has generated the build files in the 'build' subfolder within 'cef_binary/windowsarm64'. To build the project, use the following CMake command in the console: + +```console +cmake --build build +``` + +This command compiles the project, including sample applications such as `cefsimple`. This particular application creates a browser window and renders an HTML website. It is composed of several components, including the `SimpleApp` class, which is crucial for managing process-level callbacks in a CEF-based application. `SimpleApp` offers a variety of interfaces and methods crucial for multiple processes, along with some that are specific to certain process types. For example, the `CefBrowserProcessHandler interface` is unique to the browser process. The `GetBrowserProcessHandler()` method in `SimpleApp` must return a reference to `SimpleApp` itself since it implements both `CefApp` and `CefBrowserProcessHandler`. This ensures that appropriate handlers are accessible in the correct process context. For more detailed information about this application, visit the CEF project's [website](https://bitbucket.org/chromiumembedded/cef/wiki/GeneralUsage.md#markdown-header-sample-application). + +## Launching the application +Let's run the `cefsimple` application. The binaries can be found under the `build\tests\cefsimple\Debug` folder. For example, the path might be something like `C:\cef_binary\windowsarm64\build\tests\cefsimple\Debug` but this could vary based on your specific setup. + +By default, the application renders the Google homepage: + +![fig2](Figures/02.png) + +## Modify the application +You will now modify the `cefsimple` application to render a custom page. This page will fetch data from `JSONPlaceholder` and display it in a table. + +First, close the `cefsimple` application if it's running. Then, locate and open the `simple_app.cc` file, under the `cef_binary\windowsarm64\tests\cefsimple` folder. Scroll down to the definition of the `SimpleApp` class, and modify the `OnContextInitialized` method. Change the URL from https://www.google.com to `file://c:\web\index.html`. (**note**: replace this path with the actual location of your custom HTML file.): + +```cpp +void SimpleApp::OnContextInitialized() { + CEF_REQUIRE_UI_THREAD(); + + CefRefPtr command_line = + CefCommandLine::GetGlobalCommandLine(); + + // Create the browser using the Views framework if "--use-views" is specified + // via the command-line. Otherwise, create the browser using the native + // platform framework. + const bool use_views = command_line->HasSwitch("use-views"); + + // SimpleHandler implements browser-level callbacks. + CefRefPtr handler(new SimpleHandler(use_views)); + + // Specify CEF browser settings here. + CefBrowserSettings browser_settings; + + std::string url; + + // Check if a "--url=" value was provided via the command-line. If so, use + // that instead of the default URL. + url = command_line->GetSwitchValue("url"); + if (url.empty()) { + //url = "http://www.google.com"; + url = "file://c:\\web\\index.html"; + } + + if (use_views) { + // Create the BrowserView. + CefRefPtr browser_view = CefBrowserView::CreateBrowserView( + handler, url, browser_settings, nullptr, nullptr, + new SimpleBrowserViewDelegate()); + + // Create the Window. It will show itself after creation. + CefWindow::CreateTopLevelWindow(new SimpleWindowDelegate(browser_view)); + } else { + // Information used when creating the native window. + CefWindowInfo window_info; + +#if defined(OS_WIN) + // On Windows we need to specify certain flags that will be passed to + // CreateWindowEx(). + window_info.SetAsPopup(nullptr, "cefsimple"); +#endif + + // Create the first browser window. + CefBrowserHost::CreateBrowser(window_info, handler, url, browser_settings, + nullptr, nullptr); + } +} + +CefRefPtr SimpleApp::GetDefaultClient() { + // Called when a new browser window is created via the Chrome runtime UI. + return SimpleHandler::GetInstance(); +} +``` + +Make sure to save the `simple_app.cc` file after making your changes. Then, to rebuild the project, open your Command Prompt or Terminal, navigate to your build directory, and type the following command: + +```console +cmake --build build +``` + +This command will compile the updated code and rebuild the `cefsimple` application with your modifications. Remember, it's important to be in the directory where your CMake build files are located when executing this command. + +### Custom webpage +You will now create a custom index.html file to fetch the data from the JSONPlaceholder: +1. Create the new folder `C:\web`. +2. Under `C:\web` create a new file `index.html` and modify it as follows: + +```HTML + + + + CEF JSONPlaceholder Viewer + + + +

Posts from JSONPlaceholder

+ + + + + + + + + + + + +
IDTitleBody
+ + +``` + +Re-run the application and you will see the following: + +![fig3](Figures/03.png) + +This example demonstrates the versatility and power of CEF applications. One of their key strengths is the ability to modify the rendered content dynamically. This means you can change what's displayed in the application, like updating the HTML or CSS, without having to rebuild the entire application each time. This feature significantly streamlines the development process, making it quicker and more efficient. + +Let's leverage this capability to enhance our application. You will focus on styling the application by updating the HTML and CSS, providing a more engaging and visually appealing user interface. This step will show how easily you can improve the look and feel of your CEF application with just a few modifications to the web content. + +### Style the application +Add `styles.css` file to modify the appearance of the application: +1. In the `C:\web\` folder create a new file `styles.css` with the content below: + +```CSS +body { + font-family: Arial, sans-serif; + margin: 20px; + background-color: #f4f4f4; + color: #333; +} + +h1 { + color: #007bff; +} + +table { + width: 100%; + border-collapse: collapse; +} + +table, th, td { + border: 1px solid #ddd; +} + +th, td { + padding: 10px; + text-align: left; +} + +th { + background-color: #007bff; + color: white; +} + +tr:nth-child(even) { + background-color: #f2f2f2; +} + +button { + background-color: #007bff; + color: white; + padding: 10px 20px; + border: none; + border-radius: 5px; + cursor: pointer; + font-size: 16px; + margin: 10px 0; +} + +button:hover { + background-color: #0056b3; +} +``` + +2. Modify `index.html` to reference `styles.css` as shown below: + +```HTML + + + + CEF JSONPlaceholder Viewer + + + +``` + +After re-running the application you will see the following: + +![fig4](Figures/04.png) + +## Summary +CEF is a powerful tool for integrating web browser functionalities into desktop applications, utilizing modern web technologies. You have learned how to setup a project, create a basic application, and use CMake for CEF projects. Additionally, you have explored more advanced features like fetching and displaying data from JSONPlaceholder, adding and styling HTML elements like tables and buttons through separate CSS files all on your Windows on Arm machine. diff --git a/content/learning-paths/laptops-and-desktops/win_forms/Figures/01.png b/content/learning-paths/laptops-and-desktops/win_forms/Figures/01.png new file mode 100644 index 000000000..eb3d7362b Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_forms/Figures/01.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_forms/Figures/02.png b/content/learning-paths/laptops-and-desktops/win_forms/Figures/02.png new file mode 100644 index 000000000..994f52ee1 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_forms/Figures/02.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_forms/Figures/03.png b/content/learning-paths/laptops-and-desktops/win_forms/Figures/03.png new file mode 100644 index 000000000..705eb92f8 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_forms/Figures/03.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_forms/Figures/04.png b/content/learning-paths/laptops-and-desktops/win_forms/Figures/04.png new file mode 100644 index 000000000..5853ed94d Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_forms/Figures/04.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_forms/Figures/05.png b/content/learning-paths/laptops-and-desktops/win_forms/Figures/05.png new file mode 100644 index 000000000..6e409c20f Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_forms/Figures/05.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_forms/Figures/06.png b/content/learning-paths/laptops-and-desktops/win_forms/Figures/06.png new file mode 100644 index 000000000..d6ef4aa56 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_forms/Figures/06.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_forms/Figures/07.png b/content/learning-paths/laptops-and-desktops/win_forms/Figures/07.png new file mode 100644 index 000000000..c2d4b1cb5 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_forms/Figures/07.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_forms/Figures/08.png b/content/learning-paths/laptops-and-desktops/win_forms/Figures/08.png new file mode 100644 index 000000000..dd46bdc18 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_forms/Figures/08.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_forms/Figures/09.png b/content/learning-paths/laptops-and-desktops/win_forms/Figures/09.png new file mode 100644 index 000000000..a2829e321 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_forms/Figures/09.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_forms/Figures/10.png b/content/learning-paths/laptops-and-desktops/win_forms/Figures/10.png new file mode 100644 index 000000000..591b05bc2 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_forms/Figures/10.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_forms/Figures/11.png b/content/learning-paths/laptops-and-desktops/win_forms/Figures/11.png new file mode 100644 index 000000000..c1f586d6e Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_forms/Figures/11.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_forms/Figures/12.png b/content/learning-paths/laptops-and-desktops/win_forms/Figures/12.png new file mode 100644 index 000000000..021e80f28 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_forms/Figures/12.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_forms/Figures/13.png b/content/learning-paths/laptops-and-desktops/win_forms/Figures/13.png new file mode 100644 index 000000000..8e7f58657 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_forms/Figures/13.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_forms/_index.md b/content/learning-paths/laptops-and-desktops/win_forms/_index.md new file mode 100644 index 000000000..98727ee3e --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/win_forms/_index.md @@ -0,0 +1,35 @@ +--- +title: Develop desktop applications with Windows Forms on Windows on Arm + +minutes_to_complete: 30 + +who_is_this_for: This learning path is for developers who want to learn how to create Windows Forms applications on Windows on Arm (WoA). + +learning_objectives: + - Create and build a Windows Forms application + - Measure code execution performance on Arm64 + +prerequisites: + - A Windows on Arm computer such as [Windows Dev Kit 2023](https://learn.microsoft.com/en-us/windows/arm/dev-kit), Lenovo Thinkpad X13s running Windows 11 or a Windows on Arm[virtual machine](/learning-paths/cross-platform/woa_azure/). + - Visual Studio 2022 with .NET Desktop Development workload + +author_primary: Dawid Borycki + +### Tags +skilllevels: Introductory +subjects: Migration to Arm +armips: + - Cortex-A +operatingsystems: + - Windows +tools_software_languages: + - Windows Forms + - C# + - .NET + +### 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/laptops-and-desktops/win_forms/_next-steps.md b/content/learning-paths/laptops-and-desktops/win_forms/_next-steps.md new file mode 100644 index 000000000..93e6bc859 --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/win_forms/_next-steps.md @@ -0,0 +1,35 @@ +--- +# ================================================================================ +# Edit +# ================================================================================ + +next_step_guidance: > + You have learned how to implement desktop applications with Windows Forms. You might be interested in learning how to use web technologies for creating cross-platform desktop apps. +# 1-3 sentence recommendation outlining how the reader can generally keep learning about these topics, and a specific explanation of why the next step is being recommended. + +recommended_path: "/learning-paths/laptops-and-desktops/electron" +# Link to the next learning path being recommended(For example this could be /learning-paths/servers-and-cloud-computing/mongodb). + + +# further_reading links to references related to this path. Can be: + # Manuals for a tool / software mentioned (type: documentation) + # Blog about related topics (type: blog) + # General online references (type: website) + +further_reading: + - resource: + title: Windows Forms on .NET 8 + link: https://learn.microsoft.com/en-us/dotnet/desktop/winforms/?view=netdesktop-8.0 + type: documentation + - resource: + title: Arm64 Performance Improvements in .NET 8 + link: https://devblogs.microsoft.com/dotnet/this-arm64-performance-in-dotnet-8/ + type: blog + +# ================================================================================ +# FIXED, DO NOT MODIFY +# ================================================================================ +weight: 21 # set to always be larger than the content in this path, and one more than 'review' +title: "Next Steps" # Always the same +layout: "learningpathall" # All files under learning paths have this same wrapper +--- diff --git a/content/learning-paths/laptops-and-desktops/win_forms/_review.md b/content/learning-paths/laptops-and-desktops/win_forms/_review.md new file mode 100644 index 000000000..27f1b1c1c --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/win_forms/_review.md @@ -0,0 +1,42 @@ +--- +# ================================================================================ +# Edit +# ================================================================================ + +# Always 3 questions. Should try to test the reader's knowledge, and reinforce the key points you want them to remember. + # question: A one sentence question + # answers: The correct answers (from 2-4 answer options only). Should be surrounded by quotes. + # correct_answer: An integer indicating what answer is correct (index starts from 0) + # explanation: A short (1-3 sentence) explanation of why the correct answer is correct. Can add additional context if desired + + +review: + - questions: + question: > + What is the NumericUpDown control for? + answers: + - "It enables the user to provide a numeric input of a given range in specific steps" + - "For creating a dropdown list" + - "For creating a text box with scrollable input" + correct_answer: 1 + explanation: > + NumericUpDown control enables the user to provide a numeric input + + - questions: + question: > + Can you use Windows Forms on .NET or do you need .NET Framework? + answers: + - "Yes, Windows Forms is available on .NET" + - "No, Windows Forms is available in .NET Framework only" + correct_answer: 1 + explanation: > + Microsoft provides a port of Windows Forms for .NET + + +# ================================================================================ +# FIXED, DO NOT MODIFY +# ================================================================================ +title: "Review" # Always the same title +weight: 20 # Set to always be larger than the content in this path +layout: "learningpathall" # All files under learning paths have this same wrapper +--- diff --git a/content/learning-paths/laptops-and-desktops/win_forms/how-to-1.md b/content/learning-paths/laptops-and-desktops/win_forms/how-to-1.md new file mode 100644 index 000000000..60890595c --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/win_forms/how-to-1.md @@ -0,0 +1,226 @@ +--- +title: "Create an application using Windows Forms" + +weight: 2 + +layout: "learningpathall" +--- + +## Introduction +Windows Forms, often referred to as WinForms, is a graphical (GUI) class library included as part of Microsoft's .NET Framework. It provides a rich set of controls and components that enable developers to create desktop applications for Windows operating systems with ease. Windows Forms applications are event-driven, meaning they respond to various events such as user actions (like mouse clicks or key presses) and system-generated notifications. This platform offers a robust drag-and-drop environment in Visual Studio, simplifying UI design without requiring extensive manual coding. Its versatility and integration with the .NET Framework make Windows Forms a popular choice for building feature-rich Windows applications with a familiar look and feel. + +In addition to being a part of the Microsoft .NET Framework, Windows Forms (WinForms) is also available in .NET, which is the open-source, cross-platform successor to the .NET Framework. This inclusion ensures that developers can utilize WinForms not only in the traditional .NET Framework environment but also in the modern, more flexible .NET ecosystem. This availability broadens the scope for building desktop applications for Windows, allowing developers to leverage the rich GUI capabilities of WinForms along with the advanced features and improvements found in the .NET platform. + +In this learning path, you will learn how to use WinForms to create a desktop application. The application will perform computation-intensive operations, such as matrix multiplication. Then, you will explore how Windows on Arm can be used to accelerate the application by comparing the computation time with that of x64 systems. + +You can find the complete code used in this learning path in [this repository](https://github.com/dawidborycki/Arm64.DesktopApp.WindowsForms.git). + +## Before you begin +Before you begin, install Visual Studio 2022 with .NET Desktop Development workload. + +## Create the project +Start by creating the project. Open Visual Studio and then click 'Create a new project'. + +![fig1](Figures/01.png) + +In the 'Create a new project' window, select the 'Windows Forms App' template. + +![fig2](Figures/02.png) + +This will open the 'Configure your new project' view, in which you should configure the project as follows (refer to the figure below): + +1. Project name: **Arm64.DesktopApp.WindowsForms** +2. Location: Select the project location on your drive (example: **C:\Users\db\source\repos**) +3. Check the option **Place solution and project in the same directory** +4. Click the **Next** button + +![fig3](Figures/03.png) + +In the final step, 'Additional Information', select **.NET 8.0 (Long-Term Support)** from the 'Framework' dropdown list. Then, click the **Create** button. + +![fig4](Figures/04.png) + +Your project is now ready. Next, you will create the user interface and then implement the application logic. + +## User interface +To create the user interface proceed as follows: +1. In Visual Studio click, View > Toolbox. A Toolbox will appear on the left. +2. From the toolbox, drag the following controls onto the **Form1** window: +* three labels +* two NumericUpDown controls +* one Button +* one ListBox +3. Position the controls as shown in the figure below: + +![fig5](Figures/05.png) + +4. Right-click the first label and select the Properties from the context menu +5. In the Properties window, change the (Name) property to **labelArchitecture**: + +![fig6](Figures/06.png) + +6. Similarly, rename the ListBox from **listBox1** to **listBoxResults** +7. Modify the properties of the first NumericUpDown control as follows: +* (Name): numericUpDownMatrixSize +* Increment: 100 +* Minimum: 100 +* Maximum: 1000 + +8. Modify the properties of the second NumericUpDown control as follows: +* (Name): numericUpDownExecutionCount +* Increment: 10 +* Minimum: 10 +* Maximum: 100 + +9. Change the Text property of the button to **Start** + +{{% notice Tip %}} You can use the TableLayoutPanel control to host other controls. By doing so, the controls will automatically resize and reposition when the user changes the size of the window.{{% /notice %}} + +## Application logic + +You will now implement the application logic. + +1. Start by opening the Solution Explorer (click View > Solution Explorer) +2. In Solution Explorer window, right-click Arm64.DesktopApp.WindowsForms and select Add -> New Folder from the context menu +3. Rename the new folder to Helpers +4. Right-click the Helpers folder and select Add -> Class. This will open the Add New Item window. Type `MatrixHelper.cs` in the Name text box and then click the **Add** button. +5. A file named `MatrixHelper.cs` will be added to the solution. Modify this file as follows: + +```cs +namespace Arm64.DesktopApp.WindowsForms.Helpers +{ + public static class MatrixHelper + { + private static readonly Random random = new(); + + private static double[,] GenerateRandomMatrix(int matrixSize) + { + var matrix = new double[matrixSize, matrixSize]; + + for (int i = 0; i < matrixSize; i++) + { + for (int j = 0; j < matrixSize; j++) + { + matrix[i, j] = random.NextDouble(); + } + } + + return matrix; + } + + private static double[,] MatrixMultiplication(double[,] matrix1, double[,] matrix2) + { + if (matrix1.Length != matrix2.Length) + { + throw new ArgumentException("The matrices must be of equal size"); + } + + if (matrix1.GetLength(0) != matrix1.GetLength(1) || matrix2.GetLength(0) != matrix2.GetLength(1)) + { + throw new ArgumentException("The matrices must be square"); + } + + int matrixSize = matrix2.GetLength(0); + + var result = new double[matrixSize, matrixSize]; + + for (int i = 0; i < matrixSize; i++) + { + for (int j = 0; j < matrixSize; j++) + { + result[i, j] = 0; + + for (int k = 0; k < matrixSize; k++) + { + result[i, j] += matrix1[i, k] * matrix2[k, j]; + } + } + } + + return result; + } + + public static void SquareMatrixMultiplication(int matrixSize) + { + var matrix1 = GenerateRandomMatrix(matrixSize); + var matrix2 = GenerateRandomMatrix(matrixSize); + + MatrixMultiplication(matrix1, matrix2); + } + } +} +``` + +6. Similarly, under the 'Helpers' folder, create a file named `PerformanceHelper.cs`: + +```cs +using System.Diagnostics; + +namespace Arm64.DesktopApp.WindowsForms.Helpers +{ + public static class PerformanceHelper + { + private static readonly Stopwatch stopwatch = new(); + + public static double MeasurePerformance(Action method, int executionCount) + { + stopwatch.Restart(); + + for (int i = 0; i < executionCount; i++) + { + method(); + } + + stopwatch.Stop(); + + return stopwatch.ElapsedMilliseconds; + } + } +} +``` + +The above code implements two classes: `MatrixHelper` and `PerformanceHelper`. The `MatrixHelper` class implements two private methods: `MatrixMultiplication` and `GenerateRandomMatrix`. The `MatrixMultiplication` method takes two square matrices as input and calculates their product using the mathematical formula explained [here](https://en.wikipedia.org/wiki/Matrix_multiplication). Three 'for' loops are used and the result of the matrix multiplication is stored in the variable result, which is returned by the `MatrixMultiplication` method. The `GenerateRandomMatrix` method is used to generate a square matrix with elements pseudo-randomly generated using the `NextDouble` method of the Random class. Finally, the `MatrixHelper` class also implements the `SquareMatrixMultiplication` method, which generates two matrices of a given size and then calculates their product. + +The `PerformanceHelper` class has one method, MeasurePerformance. This method works by invoking a function using the Action delegate, passed as the first parameter of the MeasurePerformance method. The function is invoked several times (as specified by the second parameter, executionCount). After that, the MeasurePerformance method returns the time taken to execute the specific code. To measure the execution time, you will use the System.Diagnostics.Stopwatch class. Specifically, an instance of this class has two useful methods: Restart and Stop. Restart resets and starts the stopwatch, while Stop halts the stopwatch, allowing us to read the time elapsed since the last restart. + +You will now use the previously implemented classes to create the event handler for the button. Proceed as follows: +1. Open 'Form1.cs' in Visual Studio, and then double-click the Start button. Visual Studio will automatically generate the buttonStart_Click method, which you will need to modify as follows: + +```cs +private void buttonStart_Click(object sender, EventArgs e) +{ + int matrixSize = Convert.ToInt32(numericUpDownMatrixSize.Value); + int executionCount = Convert.ToInt32(numericUpDownExecutionCount.Value); + + var executionTime = PerformanceHelper.MeasurePerformance( + () => MatrixHelper.SquareMatrixMultiplication(matrixSize), + executionCount); + + listBoxResults.Items.Add($"Size: {matrixSize}, Count: {executionCount}, " + + $"Time: {executionTime} ms"); +} +``` + +2. Modify the Form1 constructor as shown below: + +```cs +public Form1() +{ + InitializeComponent(); + + labelArchitecture.Text = $"Processor architecture: {Environment.GetEnvironmentVariable("PROCESSOR_ARCHITECTURE")}"; + + Text = "ARM"; +} +``` + +The above changes will do the following: When the application starts, the first label will display the processor architecture. To obtain the processor architecture, use the PROCESSOR_ARCHITECTURE environment variable, which is set by the .NET runtime. Then, update the caption of the window to 'ARM'. + +When the application is running and the user clicks the Start button, the application will read the values from the `NumericUpDown` controls. These values will be used to set the matrix size and the execution count. Given these values, the application will invoke the MeasurePerformance static method of the PerformanceHelper class to measure the time needed to perform matrix multiplication for the given matrix size and execution time. The computation time will then be added to the list box. + +## Run the application +The application is now ready to run. To do this, click 'Debug' > 'Start Debugging'. Visual Studio will then build and launch the application. Afterwards, click 'Start'. Then, change the matrix size to 200 and click the 'Start' button again. Repeat this process for matrix sizes of 300, 400, and 500. The results should appear as shown in the following figure: + +![fig7](Figures/07.png) + +By default, the application uses the Arm64 configuration. For each matrix size, you will observe the computation time. In the next step, you will learn how to change the build configuration to x64. This will allow you to compare the results with those obtained using x64. diff --git a/content/learning-paths/laptops-and-desktops/win_forms/how-to-2.md b/content/learning-paths/laptops-and-desktops/win_forms/how-to-2.md new file mode 100644 index 000000000..60c985f32 --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/win_forms/how-to-2.md @@ -0,0 +1,46 @@ +--- +title: "Compare the performance results" + +weight: 3 + +layout: "learningpathall" +--- +## Objective +In this section, you will change the build configuration of the application and then launch it using various settings to compare the matrix multiplication computation times. + +## Creating new build configurations +To change the build configuration, click the target platform dropdown (by default, it displays 'Any CPU') and select 'Configuration Manager...': + +![fig8](Figures/08.png) + +In the Configuration Manager, select '' from the Active solution platform dropdown: + +![fig9](Figures/09.png) + +This will open the 'New Solution Platform' window, where you should select ARM64 from the 'Type or select the new platform' dropdown: + +![fig10](Figures/10.png) + +Then, click the OK button. Similarly, create the x64 solution platform + +## Comparing the performance +You will now compare the computation performance on x64 and Arm64 platforms. First, start the application in Release mode and architecture set to x64: + +![fig11](Figures/11.png) + +Once the application has started, run calculations for the following matrix sizes: 100, 200, 300, 400, and 500. You should see results similar to those in the following figure. + +![fig12](Figures/12.png) + +Next, launch the application for the Arm64 platform. Run the matrix multiplication for the same matrix sizes as above and observe the computation times: + +![fig13](Figures/13.png) + +By comparing the execution times, we observe that, on average, Arm64 provides almost a 30% performance improvement over x64. + +## Summary +In this learning path, you have learned how to develop and optimize a desktop application using Windows Forms in .NET on Arm64, particularly for matrix multiplication operations. + +You started with an overview of Windows Forms, a GUI class library in .NET, and its role in developing desktop applications. Then, you created a new Windows Forms project in Visual Studio, including setting up the project environment and selecting the appropriate .NET Framework version. You created both the user interface for this application and implemented the application logic. + +The application was configured and run in different modes (x64 and Arm64) to compare the performance in matrix multiplication tasks. This comparison is essential to understand the efficiency and speed of execution in different architectural settings. The Arm64 platform showed a significant improvement in computation times compared to the x64 platform, highlighting the effectiveness of the application's design and optimization. diff --git a/content/learning-paths/laptops-and-desktops/win_winui3/Figures/01.png b/content/learning-paths/laptops-and-desktops/win_winui3/Figures/01.png new file mode 100644 index 000000000..5136f7d79 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_winui3/Figures/01.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_winui3/Figures/02.png b/content/learning-paths/laptops-and-desktops/win_winui3/Figures/02.png new file mode 100644 index 000000000..667e50196 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_winui3/Figures/02.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_winui3/Figures/03.png b/content/learning-paths/laptops-and-desktops/win_winui3/Figures/03.png new file mode 100644 index 000000000..5d536b606 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_winui3/Figures/03.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_winui3/Figures/04.png b/content/learning-paths/laptops-and-desktops/win_winui3/Figures/04.png new file mode 100644 index 000000000..952467fb0 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_winui3/Figures/04.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_winui3/Figures/05.png b/content/learning-paths/laptops-and-desktops/win_winui3/Figures/05.png new file mode 100644 index 000000000..437de248c Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_winui3/Figures/05.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_winui3/Figures/06.png b/content/learning-paths/laptops-and-desktops/win_winui3/Figures/06.png new file mode 100644 index 000000000..b39837539 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_winui3/Figures/06.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_winui3/Figures/07.png b/content/learning-paths/laptops-and-desktops/win_winui3/Figures/07.png new file mode 100644 index 000000000..78fdc8391 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_winui3/Figures/07.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_winui3/Figures/08.png b/content/learning-paths/laptops-and-desktops/win_winui3/Figures/08.png new file mode 100644 index 000000000..8f5b49e0e Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_winui3/Figures/08.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_winui3/Figures/09.png b/content/learning-paths/laptops-and-desktops/win_winui3/Figures/09.png new file mode 100644 index 000000000..a108ed218 Binary files /dev/null and b/content/learning-paths/laptops-and-desktops/win_winui3/Figures/09.png differ diff --git a/content/learning-paths/laptops-and-desktops/win_winui3/_index.md b/content/learning-paths/laptops-and-desktops/win_winui3/_index.md new file mode 100644 index 000000000..f1a60261d --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/win_winui3/_index.md @@ -0,0 +1,36 @@ +--- +title: Develop Windows applications with WinUI3 on Windows on Arm + +minutes_to_complete: 30 + +who_is_this_for: This learning path is for developers who want to learn how to create cross-platform applications and leverage performance improvements on Arm64. + +learning_objectives: + - Create and build a Windows UI Library (WinUI) application + - Measure code execution performance on Arm64 + +prerequisites: + - A Windows on Arm computer such as [Windows Dev Kit 2023](https://learn.microsoft.com/en-us/windows/arm/dev-kit), Lenovo Thinkpad X13s running Windows 11 or a Windows on Arm[virtual machine](/learning-paths/cross-platform/woa_azure/). + - "Visual Studio 2022 with two workloads: .NET desktop development and Universal Windows Platform development" + +author_primary: Dawid Borycki + +### Tags +skilllevels: Introductory +subjects: Migration to Arm +armips: + - Cortex-A +operatingsystems: + - Windows +tools_software_languages: + - WinUI 3 + - C# + - .NET + - Visual Studio + +### 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/laptops-and-desktops/win_winui3/_next-steps.md b/content/learning-paths/laptops-and-desktops/win_winui3/_next-steps.md new file mode 100644 index 000000000..f4f66f7b6 --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/win_winui3/_next-steps.md @@ -0,0 +1,35 @@ +--- +# ================================================================================ +# Edit +# ================================================================================ + +next_step_guidance: > + You have learned how to implement desktop applications with WinUI 3. You might be interested in learning how to use web technologies for creating cross-platform desktop apps. +# 1-3 sentence recommendation outlining how the reader can generally keep learning about these topics, and a specific explanation of why the next step is being recommended. + +recommended_path: "/learning-paths/laptops-and-desktops/electron" +# Link to the next learning path being recommended(For example this could be /learning-paths/servers-and-cloud-computing/mongodb). + + +# further_reading links to references related to this path. Can be: + # Manuals for a tool / software mentioned (type: documentation) + # Blog about related topics (type: blog) + # General online references (type: website) + +further_reading: + - resource: + title: Microsoft's Official WinUI 3 Documentation + link: https://learn.microsoft.com/en-us/windows/apps/winui/winui3/ + type: documentation + - resource: + title: Example Applications and Code for WinUI + link: https://github.com/Microsoft/WinUI-Gallery + type: website + +# ================================================================================ +# FIXED, DO NOT MODIFY +# ================================================================================ +weight: 21 # set to always be larger than the content in this path, and one more than 'review' +title: "Next Steps" # Always the same +layout: "learningpathall" # All files under learning paths have this same wrapper +--- diff --git a/content/learning-paths/laptops-and-desktops/win_winui3/_review.md b/content/learning-paths/laptops-and-desktops/win_winui3/_review.md new file mode 100644 index 000000000..5482e1207 --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/win_winui3/_review.md @@ -0,0 +1,42 @@ +--- +# ================================================================================ +# Edit +# ================================================================================ + +# Always 3 questions. Should try to test the reader's knowledge, and reinforce the key points you want them to remember. + # question: A one sentence question + # answers: The correct answers (from 2-4 answer options only). Should be surrounded by quotes. + # correct_answer: An integer indicating what answer is correct (index starts from 0) + # explanation: A short (1-3 sentence) explanation of why the correct answer is correct. Can add additional context if desired + + +review: + - questions: + question: > + What is XAML for? + answers: + - "To declare views in various UI frameworks (WPF, WinUI 3, Xamarin Forms)" + - "To accelerate applications" + - "To implement logic of the application" + correct_answer: 1 + explanation: > + XAML, which stands for Extensible Application Markup Language, is a declarative XML-based language used primarily for defining graphical user interfaces in various Microsoft frameworks and technologies, including WPF (Windows Presentation Foundation), UWP (Universal Windows Platform), Xamarin.Forms, and WinUI. + + - questions: + question: > + Can you use C++ to implement WinUI apps? + answers: + - "Yes" + - "No" + correct_answer: 1 + explanation: > + Yes, you can use C++ to implement WinUI 3 apps. WinUI 3, being a part of the Windows App SDK, supports development in both C++ and C# + + +# ================================================================================ +# FIXED, DO NOT MODIFY +# ================================================================================ +title: "Review" # Always the same title +weight: 20 # Set to always be larger than the content in this path +layout: "learningpathall" # All files under learning paths have this same wrapper +--- diff --git a/content/learning-paths/laptops-and-desktops/win_winui3/how-to-1.md b/content/learning-paths/laptops-and-desktops/win_winui3/how-to-1.md new file mode 100644 index 000000000..77022c040 --- /dev/null +++ b/content/learning-paths/laptops-and-desktops/win_winui3/how-to-1.md @@ -0,0 +1,452 @@ +--- +title: "Creating an application" + +weight: 2 + +layout: "learningpathall" +--- + +## Introduction +Windows UI Library 3 (WinUI 3) is a modern, native UI platform available as part of the Windows App SDK. It represents the latest evolution in the Windows user interface development, offering a comprehensive set of tools and APIs for building Windows apps. + +WinUI 3 incorporates Microsoft's Fluent Design System, which emphasizes intuitive, visually appealing interfaces. It provides a wide range of controls, styles, and input features that enable developers to create both elegant and functional user experiences. + +It supports the development of both Desktop and UWP (Universal Windows Platform) applications, enabling developers to create versatile apps that can run across a wide range of Windows devices, from IoT devices to PCs. Built with performance and reliability in mind, WinUI 3 apps are optimized for smooth and efficient operation, ensuring a responsive user experience. + +WinUI 3 is an open-source project, offering backwards compatibility with existing UWP and Windows Forms applications and allowing developers to gradually migrate and modernize their applications. Additionally, WinUI 3 is extensible, supporting custom controls and third-party libraries. + +In this learning path you will implement a Win UI 3 application, which will perform square matrix multiplication. The idea is to reproduce the same functionality used in [Windows Forms learning path](/learning-paths/laptops-and-desktops/win_forms). You will also be able to measure performance improvements on Arm64 architecture. + +You can find the complete code used in this learning path [here](https://github.com/dawidborycki/Arm64.WinUIApp.git). + +## Before you begin +Before you begin the implementation, install Visual Studio 2022 with the following workloads: +1. .NET desktop development +2. Universal Windows Platform development +3. After selecting these workloads, expand the .NET desktop development group under the Installation details and ensure that the 'Windows App SDK C# Templates' option is selected. + +![fig1](Figures/01.png) + +Then, click the 'Individual components' tab and check '.NET 6.0 Runtime (Long Term Support)'. + +![fig2](Figures/02.png) + +## Create the project +Open Visual Studio and click 'Create a new project'. + +![fig3](Figures/03.png) + +In the next window, search for the 'Blank App, Packaged (WinUI 3 in Desktop)' template. Select this template and click the 'Next' button. + +![fig4](Figures/04.png) + +This action opens the 'Configure your new project' window. Here, you should: + +1. Change the project name to 'Arm64.WinUIApp' +2. Select the location for your project, e.g., 'C:\Users\db\source\repos' +3. Ensure the 'Place solution and project in the same directory' option is checked +4. Click the 'Create' button + +![fig5](Figures/05.png) + +Your project should now be ready. Next, you will design the view using XAML declarations and implement the logic using the C# code. + +## User Interface +First, you will create four anonymous styles. These styles will control the margins, font size, and font weights of texts displayed in the following controls: TextBlock, NumberBox, Button, and ListBox. + +In a WinUI 3 application, you define the styles in the `App.xaml` file. Open this file and modify it as shown in the following code snippet: + +```XML + + + + + + + + + + + + + + + + + + + + +``` + +There are four style declarations, which differ by the 'TargetType' attribute. This attribute indicates the controls to which the style will be applied. For the TextBlock controls, which represents labels, modify three properties: +* Margin: you will use a uniform margin of 10, meaning that the control will have the same margin on all four sides (left, top, right, bottom) +* FontSize: change the font size to 16 +* FontWeight: set the fonts displayed in the TextBlock to be semi-bold + +Next, you will declare the following user interface: + +![fig6](Figures/06.png) + +This view uses a tabular layout, comprising five rows and two columns. To create such a layout using XAML, you can use the Grid control. Open the `MainWindow.xaml` file and modify it as follows: + +```XML + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +