dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
14.81k stars 4.61k forks source link

RISC-V support #36748

Open mattgenious opened 4 years ago

mattgenious commented 4 years ago

Posting because I cannot find mention anywhere

I have seen that mono supports the RISC-V architecture but cannot find anything relating to .NET 5 support for RISC-V. Are there any plans to support said architecture on future releases of .NET like ARM64 has been added?

joperezr commented 4 years ago

cc: @marek-safar

DavidBurela commented 3 years ago

SiFive just announced a new powerful RISC-V development board coming out this year. Will be a number of new developers using the hardware. Might be worth looking at RISC-V support again, especially in IoT scenarios.

https://www.sifive.com/blog/the-heart-of-risc-v-development-is-unmatched https://www.sifive.com/boards/hifive-unmatched

logicethos commented 3 years ago

The First Affordable RISC-V Computer Designed to Run Linux https://beaglev.seeed.cc/

Also the Allwinner RISC-V chip to set to debut on $13 Linux hacker board soon.

broudy3 commented 3 years ago

I assume that libunwind needs to be ported first to RISC-V, as coreclr depends on this library. Is this statement true? There is a closed port request libunwind/libunwind#99

0xStuart commented 3 years ago

The BL602 is gaining popularity. It's an alternative to the hugely popular ESP32 which is everywhere. RISC-V with Wifi and Bluetooth

archanox commented 3 years ago

I assume that libunwind needs to be ported first to RISC-V, as coreclr depends on this library. Is this statement true? There is a closed port request libunwind/libunwind#99

It looks like the support has been merged in upstream now.

alexrp commented 3 years ago

Just noticed this issue and wanted to clarify something:

I have seen that mono supports the RISC-V architecture

For the record, "supports" is an overstatement here. IIRC, you can just barely run 'hello world' with the interpreter, and not much more. The JIT backend for RISC-V is like 10% done at most. There's a lot of work to be done for Mono's RISC-V support to actually be usable.

archanox commented 3 years ago

You're definitely right @alexrp. I've been trying to build mono on my RISC-V hardware for a little while now with no success. I've noticed that there is a bit of a to do list here mono:mono/docs/riscv.md

If I can get it to build, I'd be very keen to contribute to getting the mono support working, which if I understand correctly is the first step in getting .net vanilla support?

advancedwebdeveloper commented 2 years ago

I shall give a try

archanox commented 2 years ago

I've thrown this up on gitpay to try and attract developers to perform this work https://gitpay.me/#/task/607

archanox commented 2 years ago

And bountysource https://app.bountysource.com/issues/98479258-risc-v-support

crozone commented 1 year ago

The JIT backend for RISC-V is like 10% done at most. There's a lot of work to be done for Mono's RISC-V support to actually be usable.

Given that there are several ISA bases, with many optional extensions, which represent many, many permutations of potentially available instructions (not even considering RISC-V subsets), isn't implementing the JIT (nay any efficient RISC-V compiler) an absolutely colossal task? Especially the J extension.

Even ignoring the extensions and only targeting the bases, that's RV32I, RV32E, and RV64I. (lets pretend that RV128I doesn't exist).

alexrp commented 1 year ago

A functional .NET runtime just needs the base ISA and the A extension. Extensions like M, F, D, V, etc are nice-to-haves for performance but can all be emulated in software as needed.

Implementing a compiler for RISC-V is no more complicated than implementing a compiler for e.g. Arm where there is also considerable fragmentation of ISA features and software ABIs. In fact, you're pretty much dealing with fragmentation of the exact same features (atomics support, mul/div support, float support, vector support, etc).

RV32I vs RV64I support is not particularly difficult. Something like 95% of the backend code would be shared between the two due to the design of the ISA. RV32E just reduces the number of registers so it's just a fairly easy ABI difference that needs to be handled (though it should be noted that it's unlikely that mainline .NET would ever care about RV32E).

So I wouldn't call it a colossal task. It should be about the same level of complexity as implementing a backend for any other architecture - which is still considerable, to be fair.

tannergooding commented 1 year ago

Opened a discussion thread around an Interop ABI consideration that is going to have to be resolved for RISC-V: https://github.com/dotnet/runtime/discussions/75619

am11 commented 1 year ago

I assume that libunwind needs to be ported first to RISC-V

Thanks to @zhaofengli, we have RISC-V support implemented in v1.6.2 which we build as part of coreclr. For coreclr PAL specific port, I have opened: https://github.com/dotnet/runtime/issues/75749.

brucehoult commented 1 year ago

Given that there are several ISA bases, with many optional extensions, which represent many, many permutations of potentially available instructions (not even considering RISC-V subsets), isn't implementing the JIT (nay any efficient RISC-V compiler) an absolutely colossal task? Especially the J extension.

That's kind of ridiculous.

Just do RV64GC and 95% of potential users will be very happy.

RV32IMAC will pick up 4.9% of the remaining 5% of potential users.

tannergooding commented 1 year ago

For those unfamiliar, almost all ISAs for RISC-V are optional and are not guaranteed to be present.

RV64GC is a grouping of three specific specs:

The various other letters/monikers implied by G are then:

Also ratified but not part of that set are:

There are also two frozen ISAs (expected to be ratified soon):

And several open ISAs (still being designed):

am11 commented 1 year ago

Linux and distros initially targeted, the general-purpose, riscv64gc.

From packaging / RID perspective, I think riscv64gc is the right set to be implied by linux-riscv64. Down the road, we can catch up with vector extensions and check their availability at run time (as we do on other architectures).

From code perspective, I think we should start with Base Integer as a baseline. Then with feature detection at run time using capabilities flags (PAL_GetJitCpuCapabilityFlags / getauxval et al.), introduce appropriate software fallbacks. Implementing too many software fallbacks could be tedious, so issuing unsupported platforms may be appropriate for elementary stuff (availability of float, double, atomics without assuming that their availability is guaranteed).

brucehoult commented 1 year ago

For those unfamiliar, almost all ISAs for RISC-V are optional and are not guaranteed to be present.

Not guaranteed to be present if you find yourself running on a project a student designed in class or on some customised deeply embedded microcontroller.

In practice, I have never seen a commercially-produced stand alone RISC-V microcontroller that does not implement at least RV32IMAC. And If you are running on a shrink-wrapped Linux such as Debian or Fedora then you are guaranteed of RV64GC.

I'm somewhat familiar. You'll find my name in the credits in the base ISA spec and the B and V extensions.

tannergooding commented 1 year ago

Not guaranteed to be present if you find yourself running on a project a student designed in class or on some customised deeply embedded microcontroller.

Yes, but still something that has to be discussed and decided upon. I'd agree that targeting RV32GC/RV64GC would be a good baseline expectation and should in general fit the expectations most users have.

It's worth noting a good bit of the BCL uses functionality that would be provided by B and V/P to provide algorithm acceleration. Notably we more rely on what would be provided by P (Packed SIMD) than V. V is "closer" to what we provide as Vector<T> or what ARM provides with SVE (as a very loose comparison).

brucehoult commented 1 year ago

I'd agree that targeting RV32GC/RV64GC would be a good baseline expectation

Not RV32GC. RV32IMAC. Almost no 32 bit hardware has floating point. And it won't be running Linux-like OSes anyway. It's embedded stuff. Probably just ignore 32 bit until 64 bit is well-supported

It's worth noting a good bit of the BCL uses functionality that would be provided by B and V/P to provide algorithm acceleration. Notably we more rely on what would be provided by P (Packed SIMD) than V

B and V have only recently been ratified. B is easy and is starting to appear on some upcoming hardware (e.g. VisionFive 2, Star64) but the installed base does not have it, it would be unwise to depend on it.

Probably no one will have V-capable 1.0 hardware until mid 2023. A lot of people have got the somewhat different V draft 0.7.1 from mid 2019 now (mostly in Allwinner D1 boards)

P is not even scheduled for potential ratification until the end of 2023 at LEAST, with hardware following maybe 12-18 months after that.

None of these are necessary. They increase performance, of course, but depending on them just means no one can or will use the software for several years to come, which would make dotnet very much irrelevant on RISC-V. JDK 19 has full support, including hotspot, now. v8 has full support now, and people are running node. It is much much more useful to support RV64GC as soon as possible. Support for other extensions -- that most people won't have for a year or two yet -- can come later.

PhilParisot commented 1 year ago

Sorry this will probably sound like the most noob comment here but have we considered targeting something like LLVM instead? Which already runs on RISC-V.

Or on the flip side the Bytecode Alliance (of which Microsoft is a member, probably making it easier for us to secure funding) just released Wasmtime 1.0 and we could work on implementing a RISC-V backend for it as .NET can already target WASM.

I know this is probably not the ideal solution in terms of performance, but at the same time it could be? Judging by Rust's performance on LLVM at least.

Anyways, food for thought.

alexrp commented 1 year ago

Sorry this will probably sound like the most noob comment here but have we considered targeting something like LLVM instead?

For a variety of reasons (chief among them being compilation speed) LLVM is not really suited for the kind of JIT compilation that a .NET runtime needs to do. Even with Mono theoretically supporting LLVM JIT in addition to AOT, the JIT support is rarely used in practice.

PhilParisot commented 1 year ago

I'm honestly leaning more towards Wasmtime with their release of 1.0, Microsoft has even been using it in production with Azure, we can avoid some serious work duplication here.

In any case, work towards implementing a RISC-V backend for Wasmtime should be a priority in my opinion (which would enable not only .NET but many other frameworks to run on RISC-V) and we can then judge if there is a need for direct one-to-one implementation.

We would also get a lot more support from different communities, shortening the time we'd be able to see .NET run on RISC-V infrastructure.

PhilParisot commented 1 year ago

This would also mitigate the compilation time woes seen on LLVM, however I'm not sure about runtime performance on WASM.

tannergooding commented 1 year ago

Not RV32GC. RV32IMAC. Almost no 32 bit hardware has floating point. And it won't be running Linux-like OSes anyway. It's embedded stuff.

That is an overall limiting factor for IMO. Floating-point types and data are fairly central to many operations in .NET and while emulating is possible it will be very slow.

Probably just ignore 32 bit until 64 bit is well-supported

That sounds like a reasonable compromise, especially given the diminishing amount of software and operating systems that target 32-bit at all now.

None of these are necessary. They increase performance, of course, but depending on them just means no one can or will use the software for several years to come, which would make dotnet very much irrelevant on RISC-V. JDK 19 has full support, including hotspot, now. v8 has full support now, and people are running node. It is much much more useful to support RV64GC as soon as possible. Support for other extensions -- that most people won't have for a year or two yet -- can come later.

I was calling them out because having a functioning but non-performant implementation may ultimately be just as limiting.

That is, if devs can target RISC-V, but it ultimately runs 2-16x slower than Arm64 or x64 then the reasons to support, test, and otherwise target the platform diminish. Not having these instructions as part of the "baseline" also impacts NAOT targets where the increased cost of dynamic CPU support checks (even if cached) can negatively impact many scenarios.

Of course that shouldn't be a reason to not support RISC-V or to require these extensions as part of the target baseline. It is just a consideration on the impact and perception that RISC-V will ultimately have as a target for many scenarios, especially in the enterprise, development, or gaming markets.

Xinlong-Wu commented 1 year ago

Hi, I'm tring to port Mono JIT on RISCV arch now. Just commenting here to let people know that someone is working on this.

as @alexrp said, Current JIT support for RISCV has been done for less than ten percent ( actually, I think it looks like it only defines RISCV instructions). so I plan implement RV64I firstly to make sure it can be as simple as possible for me.

Also, I think that would be helpful if I can get some information or reference (e.g. Mono JIT API documentation or other software RISCV JIT implementations)

Xinlong-Wu commented 1 year ago

and which repo should I contribute to https://github.com/mono/mono or https://github.com/dotnet/runtime

am11 commented 1 year ago

@Xinlong-Wu, you can start in either one. We have cross toolchain set up in this repo for riscv64, that can be used to port mono. https://github.com/dotnet/runtime/issues/74071 is tracking mono JIT progress.

jkotas commented 1 year ago

and which repo should I contribute to

mono/mono accepts bug-fix level changes only. dotnet/runtime is the place to contribute.

a1phyr commented 1 year ago

@PhilParisot a new RISC-V backend has just been merged to Cranelift: https://github.com/bytecodealliance/wasmtime/pull/4271 !

PhilParisot commented 1 year ago

Oh wow @a1phyr even better!!!

Does this mean we could in theory compile C# to WASM binaries and run on Cranelift targeting RISC-V?

I looked online for a RISC-V VM so that I can try it out myself, there's quite a few options, anyone have any recommendations?

Xinlong-Wu commented 1 year ago

I looked online for a RISC-V VM so that I can try it out myself, there's quite a few options, anyone have any recommendations?

QEMU should be one of the best choice

DavidBurela commented 1 year ago

When I was validating other OS's projects on RISC-V, I created my own Docker container that auto hosts a RISC-V VM, to save on all the manual CPU emulation setup of QEMU. You just need to run the container and SSH in.

I haven't updated the image on Docker Hub for a while, so if it is too out of date clone from Github and run Docker Build.

https://blog.davidburela.com/2021/12/31/risc-v-turnkey-dev-environment/

ssh-riscv-cpu

0xStuart commented 1 year ago

Raspberry Pi has some competition coming, and it's a $10 RISC-V device. https://www.techradar.com/news/theres-a-fearsome-new-raspberry-pi-competitor-in-town

iAmBipinPaul commented 1 year ago

World's First Laptop with RISC-V Processor Now Available

https://www.tomshardware.com/news/risc-v-laptop-world-first

0xStuart commented 1 year ago

Raspberry Pi has some competition coming, and it's a $10 RISC-V device. https://www.techradar.com/news/theres-a-fearsome-new-raspberry-pi-competitor-in-town

Having looked into this some more, this would make the bases of a very interesting .NET solution to the problem where you need both real-time event driven functionality (RTOS on one core), and all the benefits of a high level language (.NET/Linux on the other core). All in a low cost IC that can be added to your circuits like any other MCU.

https://wiki.pine64.org/wiki/Ox64

egdeeno commented 1 year ago

there are RISC-V profiles https://github.com/riscv/riscv-profiles (The profile document is in the "Frozen" state) An architecture profile has a mandatory base instruction set (RV32I or RV64I). In addition, the profile groups all ratified ISA extensions for that base ISA into two categories: 1.Mandatory, 2.Optional

archanox commented 1 year ago

I don't think it's worthwhile targetting anything lower than rv64gc as you'd be hard pressed to run Linux on it. Anything lower would be nanoframework territory.

NKnusperer commented 1 year ago

Following the discussion it looks like there should be already some partial support for RISC-V right? I just received my StarFive VisionFive 2 board and would like to test this, is there some kind of documentation about how to actually build for RISC-V ?

am11 commented 1 year ago

@NKnusperer, for CoreCLR: https://github.com/dotnet/runtime/issues/75749, and for Mono: https://github.com/dotnet/runtime/issues/74071 have the build steps: we have a dedicated docker image tag with the required prerequisites for cross compilation from linux-x64 to linux-riscv64. You can clone runtime repo locally on RISC-V system and run the docker command; it has volume mount so build artifacts won't be lost after the docker command is completed. Building natively on RISC-V system is also possible, but that route is bit involved as you would need to invoke internal scripts manually with loads of arguments.

i-argentinski commented 1 year ago

Android will run on RISC-V:

https://www.xda-developers.com/google-officially-supports-risc-v/

0xStuart commented 1 year ago

The naysayers that said RISC-V would never come close to ARM are looking a bit sheepish right now. SoftBank (ARM's owner) are sure doing their best to pave the way for RISC-V dominance. China is wary of trade sanctions, and also investing heavily.

clamp03 commented 1 year ago

Hello, I am writing to share my progress in porting coreclr to RISC-V. Although there is still much work to be done, I can run a very simple application "hello world" on RISC-V docker image (I don't have any devices to test now.). I based my work on LOONGARCH64 codes and only implemented the necessary codes to run the application. There are currently so many errors and unimplemented codes.

To @jkotas @wscho77 @HJLeee @JongHeonChoi @alpencolt @gbalykov and other members. I am not an expert in either RISCV-V or .NET runtime. However, I think this requires expertise in both RISC-V and .NET runtime and will need a significant amount of work and collaboration. I would greatly appreciate your feedback, reviews, suggestions, and any assistance that you may be able to provide. Please share your thoughts and opinions with me.

I have currently stored codes in my git repo and I am unsure of how to contribute such a large amount of code. https://github.com/clamp03/runtime/tree/riscv64

I tested like below.

// ROOTFS
$ sudo ROOTFS_DIR=<riscv64 rootfs> ./eng/common/cross/build-rootfs.sh riscv64
// BUILD
$ ROOTFS_DIR=<riscv64 rootfs> ./build.sh -clang -cross -arch riscv64 -c Release -s clr+libs

// RUN DOCKER
$ docker run -ti -v <server dir>:<docker dir> --name riscv64 --privileged riscv64/ubuntu:22.10
// IN DOCKER
$ apt update
$ apt install libatomic1 libicu-dev
$ ./corerun helloworld.dll

Thank you.

clamp03 commented 1 year ago

Pushed splitted 4 PRs. https://github.com/dotnet/runtime/pull/82379 (merged) https://github.com/dotnet/runtime/pull/82380 (merged) https://github.com/dotnet/runtime/pull/82381 https://github.com/dotnet/runtime/pull/82382 (merged)

Xinlong-Wu commented 1 year ago

Hi All,

Mono for RISC-V is able to output Hello World to the command line now, the code is available at the repo https://github.com/Xinlong-Wu/runtime/tree/Milestone_Hello_World.

image

And I'm preparing the patch for pr, so I'm wondering if runtime has specific requirements for the format of the submitted code?

Every one can run the code by following commands

# Install qemu
sudo apt install qemu-riscv64

# build rootfs
sudo  ./eng/common/cross/build-rootfs.sh riscv64 sid
export ROOTFS_DIR=<path to project>/.tools/rootfs/riscv64

# build runtime
./build.sh mono+libs+host -c Debug --cross --arch riscv64 --build

# run example
cd src/mono/sample/TestRun
make run
marek-safar commented 1 year ago

And I'm preparing the patch for pr, so I'm wondering if runtime has specific requirements for the format of the submitted code?

No specific requirements just match existing code style in the PR.

Xyncgas commented 9 months ago

When can I run dotnet on RISC-V server

gbalykov commented 9 months ago

@Xyncgas CoreCLR runtime RISC-V architecture porting is still in progress and tracked in https://github.com/dotnet/runtime/issues/84834. We still continue runtime fixing on libraries tests, and I'll try to share current CLR/Libs tests results soon. Now you already can build clr and libraries yourself and try to run some apps using corerun host, but note that porting is not finished.

JaneX8 commented 8 months ago

I don't know why it's not mentioned here but for those interested there is a $ 500,- bounty on this issue. https://gitpay.me/#/task/607/risc-v-support