The road to OCaml 5.0

With the convergence between the multicore and standard runtime across OCaml 4.10.0 to 4.13.0 [6], the development of OCaml multicore has reached a point where further integration into OCaml’s main branch requires fully committing to a switch to OCaml multicore.

The OCaml team has decided that the time has come for such a commitment. The new major version, OCaml 5, will be a multicore version of OCaml. Moreover, OCaml 4.14 will be the last minor release of the 4.x series of OCaml.

Multicore Minimum Viable Product

The first version of OCaml multicore, code-named OCaml 5.0, will be a Minimum Viable Product focused on:

  • x86-64
  • Linux, MacOS, Windows mingw-w64
  • Parallelism through Domains [1]
  • Concurrency through Effect Handlers [2] (without syntactic support and exposed as functions from the standard library [5])

Our plan is to integrate the multicore branch into the main branch during the next 6 months. Hopefully, OCaml 5.0 will then be released between March and April 2022.

Note that OCaml 5.0 focuses on minimal (solid) support for the multicore runtime system, and will not provide stable user-facing concurrency and parallelism libraries. There has been a lot of experimentation [3,4,6] in the last few years, and some work remains to offer long-term, user-facing concurrent and parallel programming abstractions. OCaml 5.0 will be a great time to start adding concurrency and parallelism to your OCaml programs, but the libraries will still be in flux.

Long term support for OCaml 4.14

While OCaml 5 is stabilising, we plan to extend the support period for OCaml 4.14 by publishing minor bugfix releases whenever needed. In particular, OCaml 4.14 will be supported until all tier-1 architectures and operating systems are available in OCaml 5, and OCaml 5 sequential performance is close enough to that of OCaml 4.

The sequential glaciation

To ensure that maintainers can concentrate on Multicore integration, and avoid any rebase work for the Multicore developers, the trunk branch will be feature-frozen starting from November 2021. All non-bugfix non-multicore contributions will be delayed to after the Multicore integration. We are calling this period the “sequential glaciation”.

We understand that this may be frustrating for our contributors, and apologize for the delay in getting your nice work reviewed and merged into the codebase. We hope that the sequential glaciation will be a good opportunity to help with the Multicore integration, review and testing, and/or focus on non-core-compiler efforts and the rest of the OCaml ecosystem.

With this early feature-freeze, we also plan to release OCaml 4.14.0 in advance, between January and February 2022, reducing the concurrency between the OCaml 5.0 and OCaml 4.14.0 releases.

References

[1] “Retrofitting Parallelism onto OCaml”, ICFP 2020, [2004.11663] Retrofitting Parallelism onto OCaml
[2] “Retrofitting Concurrency onto OCaml”, PLDI 2021, [2104.00250] Retrofitting Effect Handlers onto OCaml
[3] Domainslib – Parallel Programming over Multicore OCaml, GitHub - ocaml-multicore/domainslib: Parallel Programming over Domains
[4] eio – Effects-based Parallel IO for OCaml, GitHub - ocaml-multicore/eio: Effects-based direct-style IO for multicore OCaml
[5] Effect handlers in OCaml 5.0: https://discuss.ocaml.org/t/multicore-ocaml-september-2021-effect-handlers-will-be-in-ocaml-5-0
[6] Multicore monthly, Topics tagged multicore-monthly

62 Likes

How does flambda 2 fit in this plan?

I greatly appreciate all the updates regarding multicore and it would be great to know about the status of flambda 2 and when it looks to get merged to the trunk…How impacted is it, if at all, by the upcoming glaciation? When does warming begin for it? :wink:

Flambda 2 is in the situation that Multicore was in a few years back: it’s being developed on the side, and it’s not ready for serious discussion about upstreaming yet. You can track our progress here:

For now, this work is being done with Jane Street developers as willing experimental subjects. We intend to turn to upstreaming this work when we’ve had more experience and have more confidence about the broad applicability of the results of those efforts.

None of that amounts to a timeline, but I wouldn’t hold my breath. I’d expect at least a couple more years of us working on this on the side before talking seriously about upstreaming. I hope that Jane Street will be using Flambda 2 pervasively by this time next year.

y

18 Likes

And, I should add: Jane Street’s intent to upstream our work is not the same as upstream’s intent to accept it. None of what I’ve said is an announcement on behalf of the core OCaml team, nor am I in any position to make such an announcement!

7 Likes

Is that reasonable? Especially as ARM64 is a major platform now for macOS. At work we’re using OCaml Multicore to offloading some heavy data which cannot be just serialized and not having support for ARM64 is by far the biggest developer problem that we end up having.

3 Likes

A minimum viable product is just that – the minimum needed to get going, and the set of [x86_64] is smaller than the set of [x86_64|aarch64]. Having said that, several developers have expressed a desire to support aarch64 as soon as possible, so I wouldn’t be surprised if that gets into 5.0. It’s just not a guarantee at this stage of the release planning process.

14 Likes

Great news :slightly_smiling_face:
What decision has been made about the read-barrier (yes or not) for mutable record fields ?

Your response makes sense. However, adding x86-64 and aarch64 simultaneously may ensure that the specific implementation strategy (and performance numbers you get) are not the artifact of special techniques or tricks available only on the intel platform but generalize on all mainstream hardware platforms.

From my limited understanding, there are a lot of tricks you are using to make sure multicore GC and continuations are performant for legacy and future code. I had a quick read of the retrofitting effect handlers paper sometime ago and can only imagine that there are a lot of considerations at play here that go down to the deep machine architecture level.

It’s possible that the multicore team has already throught this through and has come to the conclusion that implementation details while important are not super peculiar to x86-64 and its just a matter of time and effort to work this out for aarch64…

2 Likes

Forgive me for any possibly misplaced concerns, I’m speaking the first thought that came to my mind while reading this:
How does upstream plan to prevent a Python 2/3 Perl5/6 situation with that?

I understand that our case is already quite distinct nowadays; comparing it to Perl is already really pushing it, and Python is still far off… as in our case OCaml 4/5 would be very much compatible languages (down to the majority of internal runtime function names and the stub API, and aside from the use of multicore-specific libs or unexposed internals)… so there should be less stubbornness making the switch from the community’s side…

but without a clear deprecation date, and as OCaml 5 evolves and collects more features, I worry about that gap growing, and having to eventually ask “Are you on OCaml 4 or 5? Is this library compatible with OCaml 5? etc…”, more importantly the possible divide, doesn’t sound like an attractive idea.

Reassurance, It’s very likely the maintainers have already thought about the implications of this, so I wonder if you’d like to comment on whether a plan exists to prevent that situation… If it’s not desirable to begin with… Or on how many more ways we’re distinct from those languages back in their time of flux. Of course with the sequential glaciation and the release of 4.14.0 in advance help alleviate this, but Python 2 was feature-frozen for 10 years too.

1 Like

How does upstream plan to prevent a Python 2/3 Perl5/6 situation with that?

I don’t think this situation is comparable with Python 2/3. This is somewhat similar to the Scala 2.x/Scala 3 debate that is going on on the internet – people are seeing shades of the Python 2/3 debacle in that too. If fact you can check out this presentation by Martin Odersky the creator of scala where he gives a reason why Scala 2.x/3 is not going to suffer the debacle of Python 2/3 Scala 3 has landed - Martin Odersky - YouTube at 0:55:30 – the reasons are quite similar to why Ocaml 4.x/5.0 wont suffer the debacle of Python 2/3 !!

The reasons why Python 2/3 was a big issue but will not be an issue for OCaml 4.x/5.x is that:

  • Python is not statically typed. So you may have a code base of thousands of lines and you will need to inspect it manually or with regexes or other imperfect tools to port it to Python 3. Even then you’re not fully sure due to the dynamic nature of the language. With Ocaml 4.x/5.0 the strong static typing should inform you about any incompatibility easily. If there are any new syntactic constructs they will not compile in Ocaml 4.x. If there any stdlib features required for effects those sub-modules will not be available in a OCaml 4.x compiler e.g. the Obj.Effect_handlers module is not there in Ocaml 4.x – you get the picture – Your compiler will prevent problems if you were to inadvertently mix OCaml 5.x and OCaml 4.x code
  • Another reason that came up in the Scala 3 presentation linked above was that for a long time Python 2 and Python 3 were more or less equivalent and there was no compelling reason to shift to Python 3. Apart from some annoying incompatibilities and “cleanups” Python 3 didn’t provide anything compelling. Only a few versions into Python 3, did Python 3 provide a real reason to shift over. This is not the case with OCaml 5.0 – it provides a compelling reason to migrate – multicore and effects! So again, Ocaml 4.x/5 will be a different situation than Python 2/3

My understanding is that any code written for a recent OCaml 4.x will work without any changes on OCaml 5.0 down to the FFI which should provide a smooth upgradation path.

I’m not a OCaml compiler contributor or part of the compiler team but my understanding is that there is no plan to make any change to 4.14 that would render your code incompatible with OCaml 5.0. So you will always be able to move “up” without any changes (of course if you’re doing some really low level things in C that guarantee may not hold true).

These are not promises or assurances Python 2 gave or could give.

6 Likes

What decision has been made about the read-barrier (yes or not) for mutable record fields ?

Multicore now uses a parallel minor collector rather than the older concurrent minor collector. One of the main reasons for this change is that it doesn’t need a read barrier and so preserves the C API.

The “Retrofitting Parallelism” that is linked in the main post goes in to the difference between the two collectors in a lot of depth.

9 Likes

This is correct. We’ve also put a lot of effort in to compatibility testing. @kit-ty-kate has done some great work with opam health check: http://check.ocamllabs.io:8082/ where we build and test every package on opam against multicore and other variants (like the naked pointer checker).

11 Likes

One of the main difference is that OCaml 5.0 will be strongly compatible with OCaml 4.14.x . In fact, the compatibility of every package on the opam ecosystem with multicore is already being tested right now.
The only exceptions in term of compatibility would be some uses of the internal runtime API. And for those use cases the transition to the multicore runtime has started since OCaml 4.10 .

Really the aim is for OCaml 5 to be just another version of OCaml in term of backward compatibility.
And like any new version, if you want to use the new features, you will need to upgrade. However, the core language will still be the same, and any new code written for older version of OCaml , from 3.12 to 4.14.57, will be compatible with OCaml 5.

19 Likes

The most difficult part of adding parallelism into the language at a “low level” is precisely defining the memory model. This required some original research to come up with a model we were happy with, as Java and C++ weren’t satisfactory precedents.

Our paper on “Bounding Data Races in Space and Time” from PLDI 2018 describes the OCaml memory model and the guarantees it provides in the presence of data races (that is, concurrent non-read accesses to non-atomic storage locations). This memory model covers x86_64, aarch64 and powerpc (and by extension, risc-v). There has also existed an aarch64 multicore backend in the past which has bitrotted, so we’re reasonably sure there won’t be any nasty surprises when re-implementing it. The TL;DR from the paper abstract is:

Our evaluation demonstrates that it is possible to balance a comprehensible memory model with a reasonable (no overhead on x86, ~0.6% on ARM) sequential performance trade-off in a mainstream programming language.

Really solid native code support for non-x86 architectures is a very important goal for OCaml, and one we’ve sunk a fair bit of effort into over the years. When you submit an opam package to the central repository, it’s even tested on a big-endian S390x mainframe virtual machine these days :wink:

5 Likes

So cool to see Windows Mingw-64 support at the very beginning :smiley:

Cool! Are there other changes planned for 5.0 beyond multicore?

Having the compiler support quite standard stuff such as [@@deriving ] would be a great addition IMVHO.

No, the aim is to keep 5.0 small and focused on the multicore runtime.

We might remove some deprecated API, in particular in the internal runtime API, but that’s all the planned changes.

5 Likes