Skip to content

Archdetect riscv update - #243

Open
hugomeiland wants to merge 8 commits into
EESSI:mainfrom
hugomeiland:archdetect-riscv
Open

Archdetect riscv update#243
hugomeiland wants to merge 8 commits into
EESSI:mainfrom
hugomeiland:archdetect-riscv

Conversation

@hugomeiland

Copy link
Copy Markdown

This update will treat the isa line from a riscv cpu (e.g. rv64imafdcv_zicbom_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zfhmin_zca_zcd_zba_zbb_zbc_zbs_zkt_zve32f_zve32x_zve64d_zve64f_zve64x_zvfh_zvfhmin_zvkt_sscofpmf_sstc_svinval_svnapot_svpbmt) and sed it into seperate flags which can be matched as relevant (!) features, the same way we do for x86_64. This should allow cpu's with the same relevant features, but from different vendors to be matched to the same cpu paths.

@julianmorillo

Copy link
Copy Markdown
Contributor

I think this update makes sense as it certainly gives more flexibility and would allow working with subsets of extensions instead of matching the whole ISA string. I suggest to change the comment in eessi_archdetect.sh to something like:

# RISC-V ISA strings use '_' as extension separators.
# Convert them to space-separated feature tokens so they
# can be matched like x86 CPU flags.

as it explains better why the replacement is done. The tokens here are just features/extensions and do not translate to compilation flags (in contrast with x86). At the end, when building we will need the ISA string (with underscores) anyway to pass it to the -march option.

Which makes me think... if we do:

bot: build repo:dev.eessi.io-riscv-2025.06-001 instance:eessi-bot-riscv for:arch=riscv64/sifive/p550

where/how is the ISA string to pass to -march determined? Doesn't it directly come from init/arch_specs/eessi_arch_riscv.spec ? I think this would require an update at some other script...

@riscv-eessi-io-bot

riscv-eessi-io-bot Bot commented Jun 3, 2026

Copy link
Copy Markdown

New job on instance eessi-bot-riscv for repository dev.eessi.io-riscv-2025.06-001
Building on: sifive-p550
Building for: riscv64/sifive/p550
Job dir: /home/eessibot/shared/jobs/2026.06/pr_243/309668

date job status comment
Jun 03 13:06:42 UTC 2026 submitted job id 309668 awaits release by job manager
Jun 03 13:07:07 UTC 2026 released job awaits launch by Slurm scheduler
Jun 03 13:08:15 UTC 2026 running job 309668 is running
Jun 03 13:09:22 UTC 2026 finished
🤷 UNKNOWN (click triangle for detailed information)
  • Job results file _bot_job309668.result does not exist in job directory, or parsing it failed.
  • No artefacts were found/reported.
Jun 03 13:09:22 UTC 2026 test result
🤷 UNKNOWN (click triangle for detailed information)
  • Job test file _bot_job309668.test does not exist in job directory, or parsing it failed.

@hugomeiland

hugomeiland commented Jun 10, 2026

Copy link
Copy Markdown
Author

At the end, when building we will need the ISA string (with underscores) anyway to pass it to the -march option.

Which makes me think... if we do:

bot: build repo:dev.eessi.io-riscv-2025.06-001 instance:eessi-bot-riscv for:arch=riscv64/sifive/p550

where/how is the ISA string to pass to -march determined? Doesn't it directly come from init/arch_specs/eessi_arch_riscv.spec ? I think this would require an update at some other script...

llvm: Supported profile names can be passed using -march instead of a standard ISA naming string. Currently supported profiles:
rvi20u32
rvi20u64
rva20u64
rva20s64
rva22u64
rva22s64
rva23u64
rva23s64
rvb23u64
rvb23s64

GCC: -march=[ISA|Profile|Profile_ISA|processor-string]

Generate code for given RISC-V ISA or profile or a combination of them (e.g. ‘rv64im’ ‘rvi20u64’ ‘rvi20u64_zbb’). The names of ISAs and profiles must be lower case. Examples include ‘rv64i’, ‘rv32g’, ‘rv32e’, ‘rv32imaf’, ‘rva22u64’ and ‘rva23u64’. 

so if we use the profile name as the naming of the cpu, it can directly be used in the compilers...

@casparvl

Copy link
Copy Markdown
Contributor

where/how is the ISA string to pass to -march determined? Doesn't it directly come from init/arch_specs/eessi_arch_riscv.spec ? I think this would require an update at some other script...

I'm not sure if I understand your question correctly, but: in principle, all our builds use the default value for EasyBuild's optarch setting - meaning they optimize for the current build host. GPU builds do take the GPU target passed to the bot and set that as EASYBUILD_CUDA_COMPUTE_CAPABILITIES argument for EasyBuild. I'm not 100% sure what our generic CPU builds though - they might just be native builds on the oldest target we have access to - or they might actually set some EASYBUILD_OPTARCH somewhere. You should check the build scripts for this.

So yeah, making archspec aware of these architectures is only the first step. For CPU builds, native building was never an issue - but the same might not apply to Risc-V... In that case the build scripts would need to start setting some EASYBUILD_OPTARCH I guess...

@hugomeiland

Copy link
Copy Markdown
Author

Folded the remaining useful bits from #234 into this PR:

  • Renamed riscv64/sifive/jh7110riscv64/sifive/u74-mc (matches /proc/cpuinfo uarch: sifive,u74-mc and GCC -mtune=sifive-u74)
  • Ported VisionFive 2 archdetect fixtures under tests/archdetect/riscv64/sifive/u74-mc/
  • Moved p550 fixtures to tests/archdetect/riscv64/sifive/p550/ and updated the CI matrix

Tokenized ISA matching from this PR is kept. Local RISC-V archdetect tests for p550, u74-mc, and both SpacemiT cases pass.

Closing #234 as superseded by this PR.

@hugomeiland

Copy link
Copy Markdown
Author

Build-time RISC-V optarch map

Added the complementary piece to archdetect (runtime selection):

  • init/arch_specs/eessi_riscv_optarch.mapsoftware_subdirEASYBUILD_OPTARCH (-march / -mtune / -mabi, or GENERIC)
  • init/eessi_riscv_optarch.sh — lookup + apply helpers
  • Wired into bot/build.sh and EESSI-install-software.sh (honours pre-set EASYBUILD_OPTARCH / --generic)
  • Copied via install_scripts.sh
  • CI: .github/workflows/tests_riscv_optarch.yml

Example: riscv64/sifive/u74-mc-march=rva20u64 -mtune=sifive-u74 -mabi=lp64d

@hugomeiland

Copy link
Copy Markdown
Author

GCC + Clang/LLVM optarch coverage

Map entries are now EasyBuild multi-compiler strings, e.g. u74-mc:

`GCC:-march=rva20u64 -mtune=sifive-u74 -mabi=lp64d;Clang:-mcpu=sifive-u74 -mabi=lp64d;LLVM:-mcpu=sifive-u74 -mabi=lp64d`

CI installs `gcc-riscv64-linux-gnu` + `clang` and runs acceptance checks for both toolchains (`EESSI_RISCV_OPTARCH_REQUIRE_COMPILERS=1`). Locally verified: all GCC and Clang/LLVM flag sets compile an empty C unit.

@hugomeiland

Copy link
Copy Markdown
Author

Design note: RISC-V archdetect vs build-time -march/-mtune

This PR does two related but intentionally separate things. That split is the main design point (also answering @julianmorillo / @casparvl about where -march comes from).

The problem with the x86-style path

On x86/ARM, EESSI can usually:

  1. set EESSI_SOFTWARE_SUBDIR_OVERRIDE to the target path, and
  2. leave EasyBuild optarch unset so the compiler uses host-native flags (-march=native / -mcpu=native).

That fails on RISC-V:

x86/ARM assumption RISC-V reality
-march=native exists It does not
Host ≈ EESSI target Breaks for profiles and cross-target bot jobs
Spec / ISA string ≈ compiler flag Feature tokens for matching ≠ a -march string
Native implies good tuning Need explicit -mtune / -mcpu

EasyBuild’s get_isa_riscv() (easybuild-framework#5029) only helps “build on this host for this host”. It does not know about EESSI paths like riscv64/sifive/u74-mc or riscv64/generic/rva22u64.

/proc/cpuinfo isa: is also a poor CPU identity: it varies by vendor, kernel, and board (e.g. same SiFive vendor for P550 vs U74; different X60 ISA strings across kernels). Matching the whole ISA string was brittle; tokenizing it (this PR) fixes detection, but then the spec column is no longer a ready-made -march= value — so builds need another source of flags.

Design: split runtime selection from build-time flags

  1. Runtime (archdetect)eessi_archdetect.sh + eessi_arch_riscv.spec
    Choose the software subdirectory via tokenized ISA features + vendor.
    Includes vendor targets (sifive/u74-mc, sifive/p550, spacemit/x60, …) and profile paths (riscv64/generic/rva20u64, rva22u64, rva23u64).

  2. Build time (optarch map)init/arch_specs/eessi_riscv_optarch.map + init/eessi_riscv_optarch.sh
    Map software_subdirEASYBUILD_OPTARCH (EasyBuild multi-compiler form: GCC:…;Clang:…;LLVM:…).
    Wired in bot/build.sh and EESSI-install-software.sh (honours pre-set EASYBUILD_OPTARCH / --generic).

Same idea as GPU builds: accel/nvidia/cc80 already maps to an explicit EasyBuild setting; RISC-V CPU targets need the same for -march/-mtune.

Flag roles

  • -march = legal instruction set (prefer RISC-V profiles where possible: rva20u64, …)
  • -mtune / -mcpu = microarchitecture (e.g. sifive-u74, sifive-p400-series; SpacemiT stays -mtune=generic until toolchains grow a name)
  • -mabi=lp64d = keep consistent with the EESSI RISC-V Linux userspace
  • GENERIC = EasyBuild’s compatibility floor (-march=rv64gc -mabi=lp64d), not an optimization strategy

Example (u74-mc):

GCC:-march=rva20u64 -mtune=sifive-u74 -mabi=lp64d;Clang:-mcpu=sifive-u74 -mabi=lp64d;LLVM:-mcpu=sifive-u74 -mabi=lp64d

What this PR lands

Piece Role
Tokenized RISC-V ISA matching Reliable archdetect
sifive/u74-mc + tests (from #234) VisionFive 2 / U74 detection
Profile + vendor specs Runtime paths
eessi_riscv_optarch.map Build-time flags for GCC + Clang/LLVM
CI for map + compiler acceptance Guard the mapping

Happy to adjust map entries (especially SpacemiT -march strings) based on review.

Comment thread bot/build.sh Outdated

@HaoZeke HaoZeke left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tokenization direction looks right to me and the vendored targets (p550, u74-mc, x60, x60-k6.6) are consistent between spec and map.

The generic profile entries are the problem: I don't think they can match at all under the vendor gate, one has a malformed token, and the specs are weaker than what the map compiles with; details inline.

On scope I'd split the optarch map + EESSI-extend Lua + its CI out, so the archdetect fix can merge while the optarch design gets its own discussion.
The map also has two parsers now, bash and Lua, which will drift.

Comment thread init/arch_specs/eessi_arch_riscv.spec Outdated
Comment thread init/arch_specs/eessi_riscv_optarch.map Outdated
Comment thread init/eessi_archdetect.sh
Comment thread EESSI-extend-easybuild.eb Outdated
Comment thread .github/workflows/tests_riscv_optarch.yml Outdated
Comment thread init/arch_specs/eessi_arch_riscv.spec Outdated
@hugomeiland

Copy link
Copy Markdown
Author

Thanks for the extensive and precise review — summary of how the points land after the split:

This PR (archdetect-only, tip 3d7f7e5)

  • Tokenization / riscv_expand_base: done (letter-wise match; see inline on eessi_archdetect.sh).
  • Malformed rv64imafdcivrv64imafdcv: fixed.
  • Empty vendor gate for generic/rva*: empty Vendor ID = any; floors aligned to detectable RVA*U64 mandates; synthetic generic/rva* fixtures + updated u74-mc .all (details on that thread).

Follow-up PR (local archdetect-riscv-optarch @ a4ce395 — not opened yet)

  • Optarch map + EESSI-extend Lua + CI: split out as you suggested.
  • Profile map vs floor mismatch: floors fixed here; map⊆spec test enforces alignment in the follow-up.
  • Missing map entry: warn + fall through (not hard fail).
  • Dual parsers: production is Lua-only in EESSI-extend; bash map readers are test-only.

Happy to resolve the archdetect threads once you’ve had a look at tip 3d7f7e5; optarch threads can stay until the follow-up PR.

Comment thread .github/workflows/tests_archdetect.yml Outdated
hugomeiland added a commit to hugomeiland/software-layer-scripts that referenced this pull request Aug 14, 2026
Drop the redundant generic/ nesting for RVA*U64 profile paths and the
synthetic fixture basename, keeping riscv64/generic as the hardcoded
rv64gc catch-all. Addresses Julian's path-shortening feedback on EESSI#243.

Co-authored-by: Cursor <cursoragent@cursor.com>
hugomeiland and others added 8 commits September 2, 2026 20:33
Split underscore-separated ISA strings and expand compact rv64*
base blobs into per-letter tokens so subset specs match supersets.
Treat an empty Vendor ID as matching any host vendor for profile
paths like riscv64/generic/rva*. Use portable [[:space:]] in sed
and get_cpuinfo so BSD and GNU tools agree.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add generic rva20/22/23u64 profile specs with userspace floors that
match after token expansion; fix rva23 base to rv64imafdcv. Rename
jh7110 to sifive/u74-mc and use space-separated ISA tokens.

Co-authored-by: Cursor <cursoragent@cursor.com>
Move HiFive Premier fixtures under sifive/p550, add VisionFive
u74-mc and synthetic generic/rva20/22/23 hosts, refresh .all
match lists, and extend the archdetect CI matrix.

Co-authored-by: Cursor <cursoragent@cursor.com>
Matching floors now track the detectable mandatory userspace ISA subset of
the ratified RVA20/22/23 U64 profiles (docs.riscv.org), including zicbo* and
V on rva23. Omit PMA/behaviour tokens that never appear in cpuinfo; update
synthetic and real fixture expectations accordingly.

Co-authored-by: Cursor <cursoragent@cursor.com>
Vendor required-token lists already match fixture cpuinfo isa lines
including S-mode tokens; clarify that full-ISA matching is intentional
and that SpacemiT custom bits stay out until fixtures advertise them.

Co-authored-by: Cursor <cursoragent@cursor.com>
Zifencei is a detectable mandatory RVA*U64 userspace extension; require it
alongside zicsr/zicntr in generic/rva20–23 floors.

Co-authored-by: Cursor <cursoragent@cursor.com>
Drop the redundant generic/ nesting for RVA*U64 profile paths and the
synthetic fixture basename, keeping riscv64/generic as the hardcoded
rv64gc catch-all. Addresses Julian's path-shortening feedback on EESSI#243.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants