Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable RISC-V cross build and test #1477

Merged
merged 1 commit into from
May 12, 2023
Merged

Enable RISC-V cross build and test #1477

merged 1 commit into from
May 12, 2023

Conversation

alexsifivetw
Copy link
Contributor

Add supporting RISC-V cross compilation workflows.
Add riscv cpu info detection.

README.md Outdated Show resolved Hide resolved
cmake --build ./build-riscv --target install
```

## Enable RISC-V Extensions at Runtime ##
Copy link
Member

Choose a reason for hiding this comment

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

We don't have enabling of extensions at runtime for any other architecture. Perhaps this should be done in a different PR for all architectures.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I apologize for using a misleading name. The feature is designed to get risc-v cpu info, because we can't use hwcap to detect risc-v extensions at runtime in linux. We may find better solution in the future.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Enabling auto-vectorization in compiler and run-time checking of vector instruction support are kind of mutually exclusive, so I would like to see manually (optimized by hand) vectorized functions along with run-time checking.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, the USE_AUTO_VECTORIZER option is turned off by default, but users can still enable it, if they know what they are doing.

option(USE_AUTO_VECTORIZER "Enable riscv auto vectorizer or not." OFF)

arch/riscv/riscv_features.c Outdated Show resolved Hide resolved
arch/riscv/riscv_features.c Outdated Show resolved Hide resolved
.github/workflows/riscv.yml Outdated Show resolved Hide resolved
CMakeLists.txt Outdated Show resolved Hide resolved
@codecov
Copy link

codecov bot commented Apr 27, 2023

Codecov Report

Patch coverage has no change and project coverage change: +0.04 🎉

Comparison is base (045a278) 83.15% compared to head (05e1dac) 83.20%.

Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #1477      +/-   ##
===========================================
+ Coverage    83.15%   83.20%   +0.04%     
===========================================
  Files          130      130              
  Lines        10765    10761       -4     
  Branches      2765     2767       +2     
===========================================
+ Hits          8952     8954       +2     
+ Misses        1139     1133       -6     
  Partials       674      674              
Flag Coverage Δ
macos_clang 42.97% <ø> (ø)
macos_gcc 73.03% <ø> (+0.05%) ⬆️
ubuntu_clang 82.39% <ø> (+0.11%) ⬆️
ubuntu_clang_debug 82.05% <ø> (+0.10%) ⬆️
ubuntu_clang_inflate_allow_invalid_dist 82.05% <ø> (+0.11%) ⬆️
ubuntu_clang_inflate_strict 82.38% <ø> (+0.11%) ⬆️
ubuntu_clang_mmap 82.72% <ø> (+0.11%) ⬆️
ubuntu_clang_pigz 14.16% <ø> (+0.01%) ⬆️
ubuntu_clang_pigz_no_optim 11.54% <ø> (-0.01%) ⬇️
ubuntu_clang_pigz_no_threads 13.93% <ø> (+0.01%) ⬆️
ubuntu_clang_reduced_mem 82.89% <ø> (+0.11%) ⬆️
ubuntu_clang_toolchain_riscv ∅ <ø> (?)
ubuntu_gcc 74.57% <ø> (+0.05%) ⬆️
ubuntu_gcc_aarch64 76.66% <ø> (-0.02%) ⬇️
ubuntu_gcc_aarch64_compat_no_opt 74.97% <ø> (-0.03%) ⬇️
ubuntu_gcc_aarch64_no_acle 75.54% <ø> (-0.02%) ⬇️
ubuntu_gcc_aarch64_no_neon 75.52% <ø> (-0.02%) ⬇️
ubuntu_gcc_armhf 76.74% <ø> (-0.02%) ⬇️
ubuntu_gcc_armhf_compat_no_opt 74.95% <ø> (-0.02%) ⬇️
ubuntu_gcc_armhf_no_acle 76.69% <ø> (-0.02%) ⬇️
ubuntu_gcc_armhf_no_neon 76.57% <ø> (-0.02%) ⬇️
ubuntu_gcc_armsf 74.07% <ø> (-0.01%) ⬇️
ubuntu_gcc_armsf_compat_no_opt 73.53% <ø> (-0.01%) ⬇️
ubuntu_gcc_benchmark 73.19% <ø> (-0.01%) ⬇️
ubuntu_gcc_compat_no_opt 76.08% <ø> (-0.02%) ⬇️
ubuntu_gcc_compat_sprefix 73.05% <ø> (-0.01%) ⬇️
ubuntu_gcc_m32 72.70% <ø> (-0.01%) ⬇️
ubuntu_gcc_mingw_i686 72.94% <ø> (-0.01%) ⬇️
ubuntu_gcc_mingw_x86_64 73.10% <ø> (+0.14%) ⬆️
ubuntu_gcc_no_avx2 73.71% <ø> (+0.05%) ⬆️
ubuntu_gcc_no_ctz 74.11% <ø> (-0.01%) ⬇️
ubuntu_gcc_no_ctzll 74.13% <ø> (-0.01%) ⬇️
ubuntu_gcc_no_pclmulqdq 73.63% <ø> (-0.02%) ⬇️
ubuntu_gcc_no_sse2 73.92% <ø> (+0.05%) ⬆️
ubuntu_gcc_no_sse42 74.12% <ø> (+0.54%) ⬆️
ubuntu_gcc_o1 73.54% <ø> (+0.05%) ⬆️
ubuntu_gcc_osb ∅ <ø> (∅)
ubuntu_gcc_pigz 38.34% <ø> (+<0.01%) ⬆️
ubuntu_gcc_pigz_aarch64 39.25% <ø> (+0.03%) ⬆️
ubuntu_gcc_ppc 73.34% <ø> (-0.01%) ⬇️
ubuntu_gcc_ppc64 73.81% <ø> (-0.01%) ⬇️
ubuntu_gcc_ppc64le 73.89% <ø> (-0.01%) ⬇️
ubuntu_gcc_ppc_no_power8 74.03% <ø> (-0.01%) ⬇️
ubuntu_gcc_s390x 74.21% <ø> (-0.01%) ⬇️
ubuntu_gcc_s390x_dfltcc 71.42% <ø> (-0.01%) ⬇️
ubuntu_gcc_s390x_dfltcc_compat 73.27% <ø> (-0.02%) ⬇️
ubuntu_gcc_s390x_no_crc32 74.00% <ø> (-0.01%) ⬇️
ubuntu_gcc_sparc64 74.25% <ø> (-0.01%) ⬇️
ubuntu_gcc_sprefix 72.71% <ø> (-0.01%) ⬇️
win64_gcc 73.35% <ø> (-0.06%) ⬇️
win64_gcc_compat_no_opt 74.18% <ø> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
cpu_features.c 100.00% <ø> (ø)

... and 5 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@Dead2
Copy link
Member

Dead2 commented Apr 29, 2023

This looks good for the most part, but there are two things I am not happy about being introduced.
One of those is the use of getenv(), a similar approach was proposed years ago both here and in zlib upstream as well, and was rejected because it opens up a new potential attack vector onto any application that uses zlib or uses a library that uses zlib.
The fopen() call is another such, although it is a much smaller risk, but it is still something that the library otherwise has never done.

I really hope it is possible to work around this somehow, although that might need hwcap updates to the kernel if I understand correctly?

An alternative is of course to force enable/disable this during compile, that would move the burden onto packagers instead, they could for example compile for multiple variations and only select the correct one during install. For testing or manual compile one could compile for the correct variation directly.

@alexsifivetw
Copy link
Contributor Author

An alternative is of course to force enable/disable this during compile, that would move the burden onto packagers instead, they could for example compile for multiple variations and only select the correct one during install. For testing or manual compile one could compile for the correct variation directly.

I believe that it's reasonable to determine RVV supporting during compile time, and to implement a more graceful solution when the kernel updates hwcaps or hwprobe for risc-v in the features.

@mtl1979
Copy link
Collaborator

mtl1979 commented May 1, 2023

An alternative is of course to force enable/disable this during compile, that would move the burden onto packagers instead, they could for example compile for multiple variations and only select the correct one during install. For testing or manual compile one could compile for the correct variation directly.

"Force enable" during configuring or compiling is a lot better compromise than relying on user input being sane or some kernel provided text file keeping predictable formatting.

set(CMAKE_C_FLAGS "${RISCV_COMPILER_FLAGS} ${CMAKE_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${RISCV_COMPILER_FLAGS} ${CMAKE_CXX_FLAGS}")

set(RISCV_LINKER_FLAGS "-lstdc++ -lpthread -lm -ldl")
Copy link
Collaborator

@mtl1979 mtl1979 May 1, 2023

Choose a reason for hiding this comment

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

Unconditionally adding -lstdc++ and -lpthread might need a comment to explain the reason... zlib-ng library itself is C code, so shouldn't link against C++ standard library.

Usually used C++ library is specified in CMAKE_CXX_FLAGS_INIT using -stdlib=libc++or -stdlib=libstdc++ before setting CMAKE_CXX_FLAGS when there is multiple choices.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, we should allow users to choose the options based on their conditions.

@alexsifivetw
Copy link
Contributor Author

"Force enable" during configuring or compiling is a lot better compromise than relying on user input being sane or some kernel provided text file keeping predictable formatting.

Thanks, it's done.

@alexsifivetw alexsifivetw requested a review from mtl1979 May 1, 2023 14:09
@mtl1979
Copy link
Collaborator

mtl1979 commented May 2, 2023

There is clearly issue with building the dependencies taking too long. It would be a lot easier if there would be official deb packages for the dependencies instead of needing to rebuild them every single time.

@alexsifivetw
Copy link
Contributor Author

There is clearly issue with building the dependencies taking too long. It would be a lot easier if there would be official deb packages for the dependencies instead of needing to rebuild them every single time.

Thank you for your feedback. It is indeed a big issue, especially for modern platforms like RISC-V, which has not yet been widely used in the world.

We are working on solving this problem, and I will update the message thread with any progress.

@Dead2
Copy link
Member

Dead2 commented May 3, 2023

Getting qemu and other packages into the repos is the best solution, but that will take time.
I am not really a Docker fan myself, but in this case I think that a QEMU-RISC-V docker image containing all dependencies (pre-compiled) could be a good solution. Just a suggestion for the RISC-V community to consier, I think it would probably be useful for other projects as well.

@mtl1979
Copy link
Collaborator

mtl1979 commented May 3, 2023

Getting qemu and other packages into the repos is the best solution, but that will take time. I am not really a Docker fan myself, but in this case I think that a QEMU-RISC-V docker image containing all dependencies (pre-compiled) could be a good solution. Just a suggestion for the RISC-V community to consier, I think it would probably be useful for other projects as well.

Docker is just wrapper around qemu, so using Docker to run qemu is like using qemu to run itself. You can essentially achieve same result by making disk image and boot it using qemu directly.

In special cases it might be enough to compile the binaries once, use tar to archive the directory structure and then compress the resulting tarball with gzip. Then all is needed to download and decompress the archive in CI instance.

@Dead2
Copy link
Member

Dead2 commented May 3, 2023

Docker does not use qemu emulation to run applications on their native architecture.
But it looks like it can use qemu emulation to run on non-native arches, I didn't know that, that is interesting but does not really matter in this case.

A docker can be just that, a tar download containing a prebuilt environment and any scripts to set things up correctly.
It can just be a little cleaner and easier than maintaining it all directly in our workflows, when you can download and run an externally maintained docker file, but I'll leave the implementation details to the RISC-V people.

Copy link
Member

@nmoinvaz nmoinvaz left a comment

Choose a reason for hiding this comment

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

Have a few CMake comments.

@@ -720,6 +725,24 @@ if(WITH_OPTIM)
set(WITH_POWER9 OFF)
endif()
endif()
elseif(BASEARCH_RISCV_FOUND)
if(WITH_RVV)
Copy link
Member

Choose a reason for hiding this comment

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

There should be check_rvv_intrinics function that checks if the compiler supports -march=rv64gcv. And then that flag can be removed from the toolchain file.

Copy link
Member

Choose a reason for hiding this comment

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

Perhaps the next line check_c_source_compiles should be moved into a check_rvv_intrinics with the CMAKE_REQUIRED_FLAGS = -march=rv64gcv

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, it's done. We will use set_property to add compiler flags "-march=rv64gcv" to the files for rvv optimized kernel in the related pr.

cmake --build ./build-riscv
```

Disable the option if there is no RVV support:
Copy link
Member

Choose a reason for hiding this comment

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

CMake should determine if the compiler supports RVV. WITH_RVV should only be there to person compiling it, to be able to easily enable/disable the feature.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because we cannot detect rvv support at runtime, running the rvv code on a no-rvv target is a risk. Users could disable the rvv when the target don't support rvv.

We will have a better solution when the kernel updates hwcap or hwprobe for riscv.

Copy link
Member

Choose a reason for hiding this comment

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

Perhaps at the top of this readme, below, Building RISC-V Target with Cmake it should indicate that there is no support for runtime detection atm.

tools/riscv/README_RISCV.md Outdated Show resolved Hide resolved
@alexsifivetw
Copy link
Contributor Author

alexsifivetw commented May 6, 2023

In special cases it might be enough to compile the binaries once, use tar to archive the directory structure and then compress the resulting tarball with gzip. Then all is needed to download and decompress the archive in CI instance.

Thank you for your suggestions.

I have created an automated release workflow for the prebuilt toolchain. Users can now download the prebuilt toolchain and enjoy using it.

Users can also use the script to download and build the toolchain based on their environment.

Apologies for the Docker plan, we cannot provide the RISC-V Docker in the short term. However, I will continue working on implementing this feature.

@nmoinvaz
Copy link
Member

nmoinvaz commented May 6, 2023

Actually you can use GitHub CLI to download GH releases.

https://cli.github.com/manual/gh_release_download

GH cli is already installed on all GH runners.

@alexsifivetw alexsifivetw requested a review from nmoinvaz May 6, 2023 19:21
@mtl1979
Copy link
Collaborator

mtl1979 commented May 7, 2023

The RISC-V toolchain doesn't seem to support coverage...

@@ -347,6 +347,19 @@ macro(check_power8_intrinsics)
set(CMAKE_REQUIRED_FLAGS)
endmacro()

macro(check_rvv_intrinsics)
# Check whether compiler supports RVV
set(CMAKE_REQUIRED_FLAGS "-march=rv64gcv")
Copy link
Member

Choose a reason for hiding this comment

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

This should be similar to check_power9_intrinsics where it would do:

   if(CMAKE_C_COMPILER_ID MATCHES "GNU" OR CMAKE_C_COMPILER_ID MATCHES "Clang")
        if(NOT NATIVEFLAG)
            set(RVVFLAG "-march=rv64gcv")
        endif()
    endif()
    # Check if we have what we need for RISCV optimizations
    set(CMAKE_REQUIRED_FLAGS "${RVVFLAG} ${NATIVEFLAG}")
    ...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, it's done.

set(CMAKE_OBJCOPY "${TOOLCHAIN_PATH}/bin/llvm-objcopy")

# compile options
set(RISCV_COMPILER_FLAGS "" CACHE STRING "The riscv compiler flags.")
Copy link
Member

Choose a reason for hiding this comment

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

Not necessary any more.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks, the cmake file was over-designed, let’s remove the unused parts.

# disable auto-vectorizer
add_compile_options(-fno-vectorize -fno-slp-vectorize)

set(CMAKE_C_FLAGS "${RISCV_COMPILER_FLAGS} ${CMAKE_C_FLAGS}")
Copy link
Member

Choose a reason for hiding this comment

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

Not necessary any more.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's done.

set(CMAKE_CXX_FLAGS "${RISCV_COMPILER_FLAGS} ${CMAKE_CXX_FLAGS}")

# link options
set(RISCV_LINKER_FLAGS "" CACHE STRING "The riscv specific link options.")
Copy link
Member

Choose a reason for hiding this comment

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

No need for thse linkers flags either? Let's not do them until they are used...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's done.

cmake --build ./build-riscv
```

Disable the option if there is no RVV support:
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps at the top of this readme, below, Building RISC-V Target with Cmake it should indicate that there is no support for runtime detection atm.

@alexsifivetw alexsifivetw requested a review from nmoinvaz May 8, 2023 12:42
@alexsifivetw
Copy link
Contributor Author

The RISC-V toolchain doesn't seem to support coverage...

Do you mean the codecov report?

@mtl1979
Copy link
Collaborator

mtl1979 commented May 8, 2023

The RISC-V toolchain doesn't seem to support coverage...

Do you mean the codecov report?

I mean generating coverage information during compilation... First step of cmake gives warning that the relevant compiler command-line options are not supported.

@@ -0,0 +1,45 @@
# Building RISC-V Target with Cmake #
Copy link
Member

Choose a reason for hiding this comment

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

Can you rename tools/riscv/README_RISCV.md to arch/riscv/README.md similar to s390?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, it's done.

Copy link
Member

@nmoinvaz nmoinvaz left a comment

Choose a reason for hiding this comment

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

Besides renaming the README, everything else lgtm.

@nmoinvaz nmoinvaz added the Architecture Architecture specific label May 9, 2023
@Dead2
Copy link
Member

Dead2 commented May 11, 2023

This currently fails CI due to a missing github access token. Strangely the downloader doesn't fall back to just using the default access token created for each CI job. https://github.com/zlib-ng/zlib-ng/actions/runs/4930653399/jobs/8855048977?pr=1477

According to this: https://docs.github.com/en/actions/security-guides/automatic-token-authentication
you should be able to fix this by adding:

env:
    GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Add RISC-V cross-compilation test
Enable RVV support at compile time
@alexsifivetw
Copy link
Contributor Author

According to this: https://docs.github.com/en/actions/security-guides/automatic-token-authentication you should be able to fix this by adding:

env:
    GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Thanks, it's done.

Copy link
Member

@Dead2 Dead2 left a comment

Choose a reason for hiding this comment

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

LGTM

@Dead2 Dead2 merged commit c3cdf43 into zlib-ng:develop May 12, 2023
119 of 125 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Architecture Architecture specific
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants