diff --git a/CMakeLists.txt b/CMakeLists.txt index 1dd92aa8..79c616bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -531,7 +531,8 @@ elseif( AND NOT APPLE AND NOT MSVC AND NOT WIN32 - AND NOT MGE_WITH_LARGE_ARCHIVE) + AND NOT MGE_WITH_LARGE_ARCHIVE + AND NOT ${MGE_ARCH} STREQUAL "riscv64") message(STATUS "Using GNU gold linker.") set(MGE_COMMON_LINKER_FLAGS "-fuse-ld=gold") endif() @@ -1070,6 +1071,16 @@ if(APPLE) set(MGE_WITH_JIT_MLIR OFF) endif() +# riscv64 +if(${MGE_ARCH} STREQUAL "riscv64") + set(CMAKE_THREAD_LIBS_INIT "-lpthread") + set(CMAKE_HAVE_THREADS_LIBRARY 1) + set(CMAKE_USE_WIN32_THREADS_INIT 0) + set(CMAKE_USE_PTHREADS_INIT 1) + set(THREADS_PREFER_PTHREAD_FLAG ON) + message(STATUS "force config thread when build riscv64, as CMAKE detect failed") +endif() + set(MGB_JIT ${MGE_WITH_JIT}) set(MGB_JIT_MLIR ${MGE_WITH_JIT_MLIR}) set(MGB_JIT_HALIDE ${MGE_WITH_HALIDE}) diff --git a/scripts/cmake-build/BUILD_README.md b/scripts/cmake-build/BUILD_README.md index cb42b616..ac132c8b 100755 --- a/scripts/cmake-build/BUILD_README.md +++ b/scripts/cmake-build/BUILD_README.md @@ -10,6 +10,7 @@ * Windows cross build ARM-Linux (ok) * Linux cross build ARM-Android (ok) * Linux cross build ARM-Linux (ok) +* Linux cross build RISCV(support [rvv](https://github.com/riscv/riscv-v-spec))-Linux (ok) * MacOS cross build ARM-Android (ok) * MacOS cross build ARM-Linux (ok but experimental) * MacOS cross build IOS (ok) @@ -139,6 +140,14 @@ Now we support ARM-Linux on Linux and Windows fully, also experimental on MacOS 2: download toolchains from https://github.com/thinkski/osx-arm-linux-toolchains if use MacOS ``` +### Cross build for RISCV-Linux +Now we support RISCV-Linux + +* commands: +``` +1: download toolchains from https://github.com/riscv-collab/riscv-gnu-toolchain +``` + ### Cross build for IOS Now we only support cross build to IOS from MACOS @@ -173,9 +182,20 @@ Now we only support cross build to IOS from MACOS ``` scripts/cmake-build/cross_build_linux_arm_inference.sh -h ``` +* cross build to RISCV-Linux: scripts/cmake-build/cross_build_linux_riscv_inference.sh + builds MegBrain(MegEngine) for inference on Linux-RISCV platforms. + The following command displays the usage: + + ``` + scripts/cmake-build/cross_build_linux_riscv_inference.sh -h + ``` + + * if board support RVV(at least 0.7), for example: nezha D1 , use -a rv64gcv0p7 + * if board do not support RVV, use -a rv64norvv * cross build to IOS: scripts/cmake-build/cross_build_ios_arm_inference.sh builds MegBrain(MegEngine) for inference on iOS (iPhone/iPad) platforms. The following command displays the usage: + ``` scripts/cmake-build/cross_build_ios_arm_inference.sh -h ``` diff --git a/scripts/cmake-build/cross_build_linux_riscv_inference.sh b/scripts/cmake-build/cross_build_linux_riscv_inference.sh new file mode 100755 index 00000000..35381662 --- /dev/null +++ b/scripts/cmake-build/cross_build_linux_riscv_inference.sh @@ -0,0 +1,149 @@ +#!/usr/bin/env bash +set -e + +ARCHS=("rv64gcv0p7" "rv64norvv") +BUILD_TYPE=Release +ARCH=rv64gcv0p7 +REMOVE_OLD_BUILD=false +NINJA_VERBOSE=OFF +NINJA_DRY_RUN=OFF +SPECIFIED_TARGET="install/strip" +READLINK=readlink +OS=$(uname -s) + +if [ $OS = "Darwin" ];then + READLINK=greadlink +fi + +SRC_DIR=$($READLINK -f "`dirname $0`/../../") +source $SRC_DIR/scripts/cmake-build/utils/utils.sh +config_ninja_default_max_jobs + +echo "EXTRA_CMAKE_ARGS: ${EXTRA_CMAKE_ARGS}" + +function usage() { + echo "$0 args1 args2 .." + echo "available args detail:" + echo "-d : Build with Debug mode, default Release mode" + echo "-a : config build arch available: ${ARCHS[@]}" + echo "-r : remove old build dir before make, default off" + echo "-v : ninja with verbose and explain, default off" + echo "-n : ninja with -n dry run (don't run commands but act like they succeeded)" + echo "-j : run N jobs in parallel for ninja, defaut is cpu_number + 2" + echo "-e : build a specified target (always for debug, NOTICE: do not do strip/install target when use -e)" + echo "-l : list CMakeLists.txt all options, can be use to config EXTRA_CMAKE_ARGS" + echo "-h : show usage" + echo "append other cmake config by config EXTRA_CMAKE_ARGS, for example, enable MGE_WITH_TEST and build with Debug mode:" + echo "EXTRA_CMAKE_ARGS=\"-DMGE_WITH_TEST=ON\" $0 -d" + exit -1 +} + +while getopts "lnvrhda:e:j:" arg +do + case $arg in + j) + NINJA_MAX_JOBS=$OPTARG + echo "config NINJA_MAX_JOBS to ${NINJA_MAX_JOBS}" + ;; + l) + echo "list CMakeLists.txt all options, can be used to config EXTRA_CMAKE_ARGS" + show_cmakelist_options + exit 0 + ;; + d) + echo "Build with Debug mode" + BUILD_TYPE=Debug + ;; + a) + tmp_arch=null + for arch in ${ARCHS[@]}; do + if [ "$arch" = "$OPTARG" ]; then + echo "CONFIG BUILD ARCH to : $OPTARG" + tmp_arch=$OPTARG + ARCH=$OPTARG + break + fi + done + if [ "$tmp_arch" = "null" ]; then + echo "ERR args for arch (-a)" + echo "available arch list: ${ARCHS[@]}" + usage + fi + ;; + h) + echo "show usage" + usage + ;; + r) + echo "config REMOVE_OLD_BUILD=true" + REMOVE_OLD_BUILD=true + ;; + v) + echo "config NINJA_VERBOSE=ON" + NINJA_VERBOSE=ON + ;; + n) + echo "config NINJA_DRY_RUN=ON" + NINJA_DRY_RUN=ON + ;; + e) + SPECIFIED_TARGET=$OPTARG + ;; + ?) + echo "unkonw argument" + usage + ;; + esac +done +echo "----------------------------------------------------" +echo "build config summary:" +echo "BUILD_TYPE: $BUILD_TYPE" +echo "SPECIFIED_TARGET: ${SPECIFIED_TARGET}" +echo "NINJA_MAX_JOBS: ${NINJA_MAX_JOBS}" +echo "ARCH: $ARCH" +echo "----------------------------------------------------" + +if [ ! $OS = "Linux" ];then + echo "cross build for riscv only support from Linux" + exit -1 +fi + +function cmake_build() { + BUILD_DIR=$SRC_DIR/build_dir/riscv-linux/$1/$BUILD_TYPE/build + INSTALL_DIR=$BUILD_DIR/../install + TOOLCHAIN=$SRC_DIR/toolchains/$2 + echo "build dir: $BUILD_DIR" + echo "install dir: $INSTALL_DIR" + echo "build type: $BUILD_TYPE" + echo "build toolchain: $TOOLCHAIN" + try_remove_old_build $REMOVE_OLD_BUILD $BUILD_DIR $INSTALL_DIR + + echo "create build dir" + mkdir -p $BUILD_DIR + mkdir -p $INSTALL_DIR + cd_real_build_dir $BUILD_DIR + bash -c "cmake -G Ninja \ + -DCMAKE_TOOLCHAIN_FILE=$TOOLCHAIN \ + -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ + -DMGE_INFERENCE_ONLY=ON \ + -DMGE_WITH_CUDA=OFF \ + -DCMAKE_INSTALL_PREFIX=$INSTALL_DIR \ + ${EXTRA_CMAKE_ARGS} \ + $SRC_DIR " + + config_ninja_target_cmd ${NINJA_VERBOSE} "OFF" "${SPECIFIED_TARGET}" ${NINJA_DRY_RUN} ${NINJA_MAX_JOBS} + bash -c "${NINJA_CMD}" +} + +build_flatc $SRC_DIR $REMOVE_OLD_BUILD + +toolchain=null +if [ "$ARCH" = "rv64gcv0p7" ]; then + toolchain="riscv64-rvv-linux-gnu.toolchain.cmake" +elif [ "$ARCH" = "rv64norvv" ]; then + toolchain="riscv64-linux-gnu.toolchain.cmake" +else + echo "ERR CONFIG ABORT NOW!!" + exit -1 +fi +cmake_build $ARCH $toolchain diff --git a/toolchains/riscv64-rvv-linux-gnu.toolchain.cmake b/toolchains/riscv64-rvv-linux-gnu.toolchain.cmake new file mode 100644 index 00000000..13079988 --- /dev/null +++ b/toolchains/riscv64-rvv-linux-gnu.toolchain.cmake @@ -0,0 +1,23 @@ +set(CMAKE_SYSTEM_NAME Linux) +set(CMAKE_SYSTEM_PROCESSOR riscv64) +set(RISCV_CROSS_BUILD_ARCH riscv64) + +if(DEFINED ENV{RISCV_TOOLCHAIN_ROOT}) + file(TO_CMAKE_PATH $ENV{RISCV_TOOLCHAIN_ROOT} RISCV_TOOLCHAIN_ROOT) +else() + message(FATAL_ERROR "RISCV_TOOLCHAIN_ROOT env must be defined") +endif() + +set(RISCV_TOOLCHAIN_ROOT + ${RISCV_TOOLCHAIN_ROOT} + CACHE STRING "root path to riscv toolchain") + +set(CMAKE_C_COMPILER "${RISCV_TOOLCHAIN_ROOT}/bin/riscv64-unknown-linux-gnu-gcc") +set(CMAKE_CXX_COMPILER "${RISCV_TOOLCHAIN_ROOT}/bin/riscv64-unknown-linux-gnu-g++") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=rv64gcv0p7 -mabi=lp64d") +set(CMAKE_CXX_FLAGS + "${CMAKE_CXX_FLAGS} -march=rv64gcv0p7 -mabi=lp64d -Wno-error=attributes") +set(CMAKE_FIND_ROOT_PATH "${RISCV_TOOLCHAIN_ROOT}/riscv64-unknown-linux-gnu") +set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) +set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) +set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)