Skip to content

Commit 60a2873

Browse files
authored
Merge pull request #1590 from madeline-underwood/sme_maddy_review
SME2_Andy to check
2 parents 69c9cfa + 0bed429 commit 60a2873

File tree

15 files changed

+1470
-0
lines changed

15 files changed

+1470
-0
lines changed
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
---
2+
title: Set up your Environment
3+
weight: 3
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
## Installing software for this Learning Path
10+
11+
To follow this Learning Path, you will need to set up an environment to develop with SME2.
12+
13+
You will require:
14+
15+
- A compiler with support for SME2 instructions. You can use [Clang](https://www.llvm.org/)
16+
version 18 or later, or [GCC](https://gcc.gnu.org/) version 14, or later. This Learning
17+
Path uses ``Clang``.
18+
19+
- An emulator to execute code with the SME2 instructions. This Learning
20+
Path uses [Arm's Fixed Virtual Platform (FVP) model](https://developer.arm.com/Tools%20and%20Software/Fixed%20Virtual%20Platforms).
21+
22+
You will also require Git and Docker installed on your machine.
23+
24+
### Set up Git
25+
26+
To check if Git is already installed on your machine, use the following command line in a terminal:
27+
28+
```BASH { output_lines=2 }
29+
git --version
30+
git version 2.47.1
31+
```
32+
33+
If the above command line fails with a message similar to "``git: command not found``", then install Git following the steps for your machine's OS.
34+
35+
{{< tabpane code=true >}}
36+
{{< tab header="Linux/Ubuntu" language="bash">}}
37+
sudo apt install git
38+
{{< /tab >}}
39+
{{< tab header="macOS" language="bash">}}
40+
brew install git
41+
{{< /tab >}}
42+
{{< /tabpane >}}
43+
44+
### Docker
45+
46+
To enable you to get started easily and with the tools that you need, you can fetch a Docker container with the required compiler and FVP. Alternatively, if you do wish to build the container yourself, the ``Dockerfile`` is also available.
47+
48+
49+
{{% notice Note %}}
50+
This Learning Path works without ``docker``, but the compiler and the FVP must be available in your search path.
51+
{{% /notice %}}
52+
53+
Start by checking that ``docker`` is installed on your machine by typing the following
54+
command line in a terminal:
55+
56+
```BASH { output_lines="2" }
57+
docker --version
58+
Docker version 27.3.1, build ce12230
59+
```
60+
61+
If the above command fails with a message similar to "``docker: command not found``"
62+
then follow the steps from the [Docker Install Guide](https://learn.arm.com/install-guides/docker/).
63+
64+
{{% notice Note %}}
65+
You might need to login again or restart your machine for the changes to take effect.
66+
{{% /notice %}}
67+
68+
Once you have confirmed that Docker is installed on your machine, you can check that it is operating normally with the following:
69+
70+
```BASH { output_lines="2-27" }
71+
docker run hello-world
72+
Unable to find image 'hello-world:latest' locally
73+
latest: Pulling from library/hello-world
74+
478afc919002: Pull complete
75+
Digest: sha256:305243c734571da2d100c8c8b3c3167a098cab6049c9a5b066b6021a60fcb966
76+
Status: Downloaded newer image for hello-world:latest
77+
78+
Hello from Docker!
79+
This message shows that your installation appears to be working correctly.
80+
81+
To generate this message, Docker followed these steps:
82+
83+
1. The Docker client contacted the Docker daemon.
84+
85+
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
86+
(arm64v8)
87+
88+
3. The Docker daemon created a new container from that image which runs the
89+
executable that produces the output you are currently reading.
90+
91+
4. The Docker daemon streamed that output to the Docker client, which sent it
92+
to your terminal.
93+
94+
To try something more ambitious, you can run an Ubuntu container with:
95+
$ docker run -it ubuntu bash
96+
97+
Share images, automate workflows, and more with a free Docker ID:
98+
https://hub.docker.com/
99+
100+
For more examples and ideas, visit:
101+
https://docs.docker.com/get-started/
102+
```
103+
104+
## Environment
105+
106+
Now, using Git, clone the environment for experimenting with SME2 to a directory
107+
named ``SME2.git``:
108+
109+
```BASH
110+
git clone https://gitlab.arm.com/learning-code-examples/TODO_SOME_PATH SME2-learning-path.git
111+
```
112+
113+
This list of content in the repository should look like this :
114+
115+
```TXT
116+
SME2-learning-path.git/
117+
├── .clang-format
118+
├── .devcontainer/
119+
│ └── devcontainer.json
120+
├── .git/
121+
├── .gitignore
122+
├── Makefile
123+
├── README.rst
124+
├── docker/
125+
│ ├── assets.source_me
126+
│ ├── build-all-containers.sh
127+
│ ├── build-my-container.sh
128+
│   └── sme2-environment.docker
129+
├── hello.c
130+
├── main.c
131+
├── matmul.h
132+
├── matmul_asm.c
133+
├── matmul_asm_impl.S
134+
├── matmul_intr.c
135+
├── matmul_vanilla.c
136+
├── misc.c
137+
├── misc.h
138+
├── preprocess_l_asm.S
139+
├── preprocess_vanilla.c
140+
├── run-fvp.sh
141+
└── sme2_check.c
142+
```
143+
144+
It contains:
145+
- Code examples.
146+
- A ``Makefile`` that builds the code examples.
147+
- A shell script called ``run-fvp.sh`` that runs the FVP.
148+
- A directory called ``docker`` that contains materials related to Docker, which are:
149+
- A script called ``assets.source_me`` that provides the FVP and compiler toolchain references.
150+
- A Docker recipe called ``sme2-environment.docker`` to build the container that
151+
you will use.
152+
- A shell script called ``build-my-container.sh`` that you can use if you want to build the Docker container. This is not essential however, as ready-made images are made available for you.
153+
- A script called ``build-all-containers.sh`` that was used to create the image for you to download to provide multi-architecture support for both x86_64 and AArch64.
154+
- A configuration script for VS Code to be able to use the container from the IDE called ``.devcontainer/devcontainer.json``.
155+
156+
The next step is to change directory to your checkout:
157+
158+
```BASH
159+
cd SME2-learning-path.git
160+
```
161+
{{% notice Note %}}
162+
From this point in the Learning Path, all instructions assume that your current
163+
directory is ``SME2-learning-path.git``.{{% /notice %}}
164+
165+
166+
## Using the environment
167+
168+
Docker containers provide you with the functionality to execute commands in an isolated environment, where you have all the necessary tools that you require without having to clutter your machine. The containers runs independently, which means that they do not interfere with other containers on the same machine or server.
169+
170+
You can use Docker in the following ways:
171+
- Directly from the command line. For example, when you are working from a terminal on your local machine.
172+
- Within a containerized environment. Configure VS Code to execute run all the commands inside a Docker container, allowing you to work seamlessly within the Docker environment.
173+
174+
### Working from a terminal
175+
176+
When a command is executed in the Docker container environment, you must prepend it with instructions on the command line so that your shell executes it within the container.
177+
178+
For example, to execute ``COMMAND ARGUMENTS`` in the SME2 Docker container, the command line looks like this:
179+
180+
```SH
181+
docker run --rm -v "$PWD:/work" -w /work armswdev/sme2-learning-path:sme2-environment-v1 COMMAND ARGUMENTS
182+
```
183+
184+
This invokes Docker, using the
185+
``armswdev/sme2-learning-path:sme2-environment-v1``container
186+
image, and mounts the current working directory (the ``SME2-learning-path.git``)
187+
inside the container to ``/work``, then sets ``/work`` as the
188+
working directory and runs ``COMMAND ARGUMENTS`` in this environment.
189+
190+
For example, to run ``make``, you need to enter:
191+
192+
```SH
193+
docker run --rm -v "$PWD:/work" -w /work armswdev/sme2-learning-path:sme2-environment-v1 make
194+
```
195+
196+
### Working from within the Docker container
197+
198+
Make sure you have the [Microsoft Dev
199+
Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers)
200+
extension installed.
201+
202+
Then select the **Reopen in Container** menu entry as Figure 1 shows.
203+
204+
It automatically finds and uses ``.devcontainer/devcontainer.json``:
205+
206+
![example image alt-text#center](VSCode.png "Figure 1: Setting up the Docker Container.")
207+
208+
All your commands now run within the container, so there is no need to prepend them with a Docker invocation, as VS Code handles all this seamlessly for you.
209+
210+
{{% notice Note %}}
211+
For the rest of this Learning Path, shell commands include the full Docker invocation so that users not using VS Code can copy the complete command line. However, if you are using VS Code, you only need to use the `COMMAND ARGUMENTS` part.
212+
{{% /notice %}}
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
---
2+
title: Test your environment
3+
weight: 4
4+
5+
### FIXED, DO NOT MODIFY
6+
layout: learningpathall
7+
---
8+
9+
In this section, you will check that your environment is all set up and ready to develop with SME2. This will be your first hands-on experience with the environment.
10+
11+
## Compile the examples
12+
13+
First, compile the example code with Clang:
14+
15+
```BASH { output_lines="2-19" }
16+
docker run --rm -v "$PWD:/work" -w /work armswdev/sme2-learning-path:sme2-environment-v1 make
17+
clang --target=aarch64-none-elf -march=armv9.4-a+sme2 -fno-exceptions -fno-rtti -mno-unaligned-access -O2 -Wall -std=c99 -nostartfiles -lcrt0-semihost -lsemihost -Wl,--defsym=__boot_flash=0x80000000 -Wl,--defsym=__flash=0x80001000 -Wl,--defsym=__ram=0x81000000 -T picolibc.ld -o hello hello.c
18+
clang --target=aarch64-none-elf -march=armv9.4-a+sme2 -fno-exceptions -fno-rtti -mno-unaligned-access -O2 -Wall -std=c99 -c -o sme2_check.o sme2_check.c
19+
clang --target=aarch64-none-elf -march=armv9.4-a+sme2 -fno-exceptions -fno-rtti -mno-unaligned-access -O2 -Wall -std=c99 -c -o misc.o misc.c
20+
clang --target=aarch64-none-elf -march=armv9.4-a+sme2 -fno-exceptions -fno-rtti -mno-unaligned-access -O2 -Wall -std=c99 -nostartfiles -lcrt0-semihost -lsemihost -Wl,--defsym=__boot_flash=0x80000000 -Wl,--defsym=__flash=0x80001000 -Wl,--defsym=__ram=0x81000000 -T picolibc.ld -o sme2_check sme2_check.o misc.o
21+
clang --target=aarch64-none-elf -march=armv9.4-a+sme2 -fno-exceptions -fno-rtti -mno-unaligned-access -O2 -Wall -std=c99 -DIMPL=asm -c -o main_asm.o main.c
22+
clang --target=aarch64-none-elf -march=armv9.4-a+sme2 -fno-exceptions -fno-rtti -mno-unaligned-access -O2 -Wall -std=c99 -c -o matmul_asm.o matmul_asm.c
23+
clang --target=aarch64-none-elf -march=armv9.4-a+sme2 -fno-exceptions -fno-rtti -mno-unaligned-access -O2 -Wall -std=c99 -c -o matmul_asm_impl.o matmul_asm_impl.S
24+
clang --target=aarch64-none-elf -march=armv9.4-a+sme2 -fno-exceptions -fno-rtti -mno-unaligned-access -O2 -Wall -std=c99 -c -o preprocess_l_asm.o preprocess_l_asm.S
25+
clang --target=aarch64-none-elf -fno-exceptions -fno-rtti -mno-unaligned-access -O2 -Wall -std=c99 -c -o matmul_vanilla.o matmul_vanilla.c
26+
clang --target=aarch64-none-elf -fno-exceptions -fno-rtti -mno-unaligned-access -O2 -Wall -std=c99 -c -o preprocess_vanilla.o preprocess_vanilla.c
27+
clang --target=aarch64-none-elf -march=armv9.4-a+sme2 -fno-exceptions -fno-rtti -mno-unaligned-access -O2 -Wall -std=c99 -nostartfiles -lcrt0-semihost -lsemihost -Wl,--defsym=__boot_flash=0x80000000 -Wl,--defsym=__flash=0x80001000 -Wl,--defsym=__ram=0x81000000 -T picolibc.ld -o sme2_matmul_asm main_asm.o matmul_asm.o matmul_asm_impl.o preprocess_l_asm.o matmul_vanilla.o preprocess_vanilla.o misc.o
28+
clang --target=aarch64-none-elf -march=armv9.4-a+sme2 -fno-exceptions -fno-rtti -mno-unaligned-access -O2 -Wall -std=c99 -DIMPL=intr -c -o main_intr.o main.c
29+
clang --target=aarch64-none-elf -march=armv9.4-a+sme2 -fno-exceptions -fno-rtti -mno-unaligned-access -O2 -Wall -std=c99 -c -o matmul_intr.o matmul_intr.c
30+
clang --target=aarch64-none-elf -march=armv9.4-a+sme2 -fno-exceptions -fno-rtti -mno-unaligned-access -O2 -Wall -std=c99 -nostartfiles -lcrt0-semihost -lsemihost -Wl,--defsym=__boot_flash=0x80000000 -Wl,--defsym=__flash=0x80001000 -Wl,--defsym=__ram=0x81000000 -T picolibc.ld -o sme2_matmul_intr main_intr.o matmul_intr.o matmul_vanilla.o preprocess_vanilla.o misc.o
31+
llvm-objdump --demangle -d hello > hello.lst
32+
llvm-objdump --demangle -d sme2_check > sme2_check.lst
33+
llvm-objdump --demangle -d sme2_matmul_asm > sme2_matmul_asm.lst
34+
llvm-objdump --demangle -d sme2_matmul_intr > sme2_matmul_intr.lst
35+
```
36+
37+
Executed within the docker ``armswdev/sme2-learning-path:sme2-environment-v1`` environment, the ``make`` command performs the following tasks:
38+
39+
- It builds four executables: ``hello``, ``sme2_check``, ``sme2_matmul_asm``, and ``sme2_matmul_intr``.
40+
- It creates the assembly listings for the four executables: ``hello.lst``, ``sme2_check.lst``, ``sme2_matmul_asm.lst``, and ``sme2_matmul_intr.lst``.
41+
42+
{{% notice Note %}}
43+
At any point, you can clean the directory of all the files that have been built by invoking the ``make clean`` target:
44+
45+
```BASH
46+
$ docker run --rm -v "$PWD:/work" -w /work armswdev/sme2-learning-path:sme2-environment-v1 make clean
47+
```
48+
{{% /notice %}}
49+
50+
## Basic checks
51+
52+
The very first program that you should run is the famous "Hello, world !" example that
53+
will tell you if your environment is set up correctly.
54+
55+
The source code is contained in ``hello.c`` and looks like this:
56+
57+
```C
58+
#include <stdio.h>
59+
#include <stdlib.h>
60+
61+
int main(int argc, char *argv[]) {
62+
printf("Hello, world !\n");
63+
return EXIT_SUCCESS;
64+
}
65+
```
66+
67+
Run the FVP simulation of the ``hello`` program with:
68+
69+
```BASH { output_lines="2-4" }
70+
docker run --rm -v "$PWD:/work" -w /work armswdev/sme2-learning-path:sme2-environment-v1 ./run-fvp.sh hello
71+
Hello, world !
72+
73+
Info: /OSCI/SystemC: Simulation stopped by user.
74+
```
75+
76+
The important line here is "``Hello, world !``" as it demonstrates that the generic code
77+
can be compiled and run on the FVP.
78+
79+
## SME2 checks
80+
81+
You will now run the ``sme2_check`` program, which checks that SME2 works as
82+
expected, in both the compiler and in the FVP.
83+
84+
The source code is found in
85+
``sme2_check.c``:
86+
87+
```C
88+
#include <stdio.h>
89+
#include <stdlib.h>
90+
91+
#include "misc.h"
92+
93+
#ifdef __ARM_FEATURE_SME2
94+
#include <arm_sme.h>
95+
#else
96+
#error __ARM_FEATURE_SME2 is not defined
97+
#endif
98+
99+
#define get_cpu_ftr(regId, feat, msb, lsb) \
100+
({ \
101+
unsigned long __val; \
102+
__asm__("mrs %0, " #regId : "=r"(__val)); \
103+
printf("%-20s: 0x%016lx\n", #regId, __val); \
104+
printf(" - %-10s: 0x%08lx\n", #feat, \
105+
(__val >> lsb) & ((1 << (msb - lsb)) - 1)); \
106+
})
107+
108+
int main(int argc, char *argv[]) {
109+
get_cpu_ftr(ID_AA64PFR0_EL1, SVE, 35, 32);
110+
get_cpu_ftr(ID_AA64PFR1_EL1, SME, 27, 24);
111+
112+
int n = 0;
113+
#ifdef __ARM_FEATURE_SME2
114+
setup_sme();
115+
n = svcntb() * 8;
116+
#endif
117+
if (n) {
118+
printf("SVE is available with length %d\n", n);
119+
} else {
120+
printf("SVE is unavailable.\n");
121+
exit(EXIT_FAILURE);
122+
}
123+
124+
printf("Checking has_sme: %d\n", __arm_has_sme());
125+
printf("Checking in_streaming_mode: %d\n", __arm_in_streaming_mode());
126+
127+
printf("Starting streaming mode...\n");
128+
__asm__("smstart");
129+
130+
printf("Checking in_streaming_mode: %d\n", __arm_in_streaming_mode());
131+
132+
printf("Stopping streaming mode...\n");
133+
__asm__("smstop");
134+
135+
printf("Checking in_streaming_mode: %d\n", __arm_in_streaming_mode());
136+
137+
return EXIT_SUCCESS;
138+
}
139+
```
140+
141+
The ``sme2_check`` program displays the SVE field of the ``ID_AA64PFR0_EL1`` system register and the SME field of the ``ID_AA64PFR1_EL1`` system register. It will then check if SVE and SME are available, then finally will switch into streaming mode and back from streaming mode.
142+
143+
The ``__ARM_FEATURE_SME2`` macro is provided by the compiler when it targets an SME-capable target, which is specified with the ``-march=armv9.4-a+sme2`` command line option to ``clang`` in
144+
file ``Makefile``.
145+
146+
The ``arm_sme.h`` include file is part of the Arm C Library
147+
Extension ([ACLE](https://arm-software.github.io/acle/main/)).
148+
149+
The ACLE provides types and function declarations to enable C/C++ programmers to make the best possible use of the Arm architecture. You can use the SME-related part of the library, but it does also provide support for Neon or other Arm architectural extensions.
150+
151+
```BASH
152+
docker run --rm -v "$PWD:/work" -w /work armswdev/sme2-learning-path:sme2-environment-v1 ./run-fvp.sh sme2_check
153+
```
154+
155+
The output should be similar to:
156+
157+
```TXT
158+
ID_AA64PFR0_EL1 : 0x1101101131111112
159+
- SVE : 0x00000001
160+
ID_AA64PFR1_EL1 : 0x0000101002000001
161+
- SME : 0x00000002
162+
SVE is available with length 512
163+
Checking has_sme: 1
164+
Checking in_streaming_mode: 0
165+
Starting streaming mode...
166+
Checking in_streaming_mode: 1
167+
Stopping streaming mode...
168+
Checking in_streaming_mode: 0
169+
170+
Info: /OSCI/SystemC: Simulation stopped by user.
171+
```
172+
173+
You have now checked that the code can be compiled and run with full SME2 support, and are all set to move to the next section.

0 commit comments

Comments
 (0)