{"action":"created","issue":{"url":"https://api.github.com/repos/mit-crpg/openmc/issues/603","repository_url":"https://api.github.com/repos/mit-crpg/openmc","labels_url":"https://api.github.com/repos/mit-crpg/openmc/issues/603/labels{/name}","comments_url":"https://api.github.com/repos/mit-crpg/openmc/issues/603/comments","events_url":"https://api.github.com/repos/mit-crpg/openmc/issues/603/events","html_url":"https://github.com/mit-crpg/openmc/issues/603","id":137971388,"number":603,"title":"Proposal: rewrite core codebase in C++","user":{"login":"paulromano","id":743095,"avatar_url":"https://avatars1.githubusercontent.com/u/743095?v=4","gravatar_id":"","url":"https://api.github.com/users/paulromano","html_url":"https://github.com/paulromano","followers_url":"https://api.github.com/users/paulromano/followers","following_url":"https://api.github.com/users/paulromano/following{/other_user}","gists_url":"https://api.github.com/users/paulromano/gists{/gist_id}","starred_url":"https://api.github.com/users/paulromano/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paulromano/subscriptions","organizations_url":"https://api.github.com/users/paulromano/orgs","repos_url":"https://api.github.com/users/paulromano/repos","events_url":"https://api.github.com/users/paulromano/events{/privacy}","received_events_url":"https://api.github.com/users/paulromano/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":16,"created_at":"2016-03-02T19:41:15Z","updated_at":"2018-05-14T12:56:20Z","closed_at":null,"author_association":"OWNER","body":"I often get asked why OpenMC is written in Fortran instead of C or C++ or another language. When I started the code, @bforget and I were interested primarily in developing and studying parallel algorithms for MC transport aimed at overcoming some of the traditional limitations on scalability. As such, we were naturally very interested in Fortran co-arrays, which had recently been added to the language in the 2008 standard and offered the promise of expressing parallelism through RDMA. I started playing around with co-arrays during the summer of 2011 and quickly discovered that there were a number of major shortcomings:\n- There was really only one implementation at the time (Intel), and it wasn't just standard in their compiler; you also had to buy their cluster software (can't remember the name). That would be pretty much in diametric opposition to the idea of OpenMC being free and open if you have to buy software just to run in parallel.\n- In F2008, co-array functionality lacks collective operations which is a major problem for scalability (supposedly will be fixed in F2015).\n\nThat was pretty much the end of our experiments with co-arrays. However, we had a considerable amount of functionality in OpenMC already built on Fortran, and I didn't want to \"waste time\" as a PhD student just rewriting what I already had. Anyone who has done a thesis knows that expediency often wins.\n\nFast forward to present day. OpenMC is still in Fortran and has grown from about 14k lines of code (version 0.4.0) to now 40k lines of code. That may sound like a lot, but by most standards 40k lines of code is actually quite small. MCNP 6.1 is something like ~300k, Serpent2 is ~240k, and Geant4 is something like 1M. I believe there are a number of compelling reasons that we should now consider rewriting the core codebase in C++ while the it is still relatively small:\n- **Use of external libraries**: Right now if you want to use a library from OpenMC, you better hope that it has a Fortran API. If not, you better hope that whatever you want to do can be done in a C interoperable manner. Anyone who hasn't been living under a rock knows that most libraries are written in C or C++. Let's take, for example, parallelism, which has been a primary driver in the development of OpenMC. Some of the available options for parallelism in C++ include standard-library features (threads, mutexes, locks, futures, etc.), C++ AMP, Intel TBB, Cilk Plus, Vc library, etc., and that's on top of the usual MPI and OpenMP C interfaces. For Fortran, you really only have MPI and OpenMP. This is not to say that we should be using any of these fancy options, but just merely to point out that we don't have the option even if we wanted to, especially for R&D purposes.\n- **Rich standard-library**: Ever looked at dict_header.F90, list_header.F90, or stl_vector.F90 in OpenMC? All are naive attempts to make up for what the Fortran language is missing -- a standard library with containers. Not to mention that string handling in Fortran is unsatisfying.\n- **Ability to get closer to hardware**: Since OpenMC is primarily a code intended for advanced R&D, a rewrite in C or C++ would allow researchers to study ideas that require leveraging hardware-specific features, which almost certainly means using some C API or otherwise calling a C function. Again, you might be able to do this with Fortran and the C interoperability module, but it may be painful/limited.\n- **Interoperating with other community codes**: There is already interest in collaboration with the INL/[MOOSE](https://github.com/idaholab/moose), ORNL/Shift, and FermiLab/[Geant](http://geant.cern.ch/) teams. All of these projects are C++-based, so there may be benefits to operating in the same language. [PyNE](https://github.com/pyne/pyne), an open-source NE toolkit, also has a substantial amount of C++ code.\n- **Moving towards libopenmc**: The development team has had a number of discussions recently about moving OpenMC in the direction of a library that could be called by other software. Again, you could do this in Fortran, but it is a lot more error-prone.\n- **Compiler issues**: Now that we are more heavily utilizing F2003 and F2008 issues, we are often running up against compiler bugs and limitations. I've probably reported somewhere around 20 bugs between the gfortran, Intel, PGI, and IBM compilers. A rewrite in C++ won't necessarily mean all problems are gone, especially because I would advocate that we adopt C++11, but some of the more esoteric issues specific to Fortran could be avoided.\n- **Talent pool available**: There are obviously many more C++ developers than Fortran developers, and, depending on who you ask, C++ is usually among the top 5 most popular programming languages. Add to this the fact that Fortran, justly or unjustly, conjures negative feelings for many people.\n\nIn terms of the mechanics of a rewrite, some code could immediately be removed (all those containers I mentioned, maybe ~3k lines of code), a sizable chunk could easily be rewritten (recent additions to the code that are already OO-style), and then another sizable chunk will require deeper thought. That being said, a few of the modules that fit in that last category are things we are already targeting a refactor for anyway, e.g., geometry and tallies. I don't want to understate the level of effort and time required, but I do think that it might not be as bad as one might naturally think, especially if we're able to get a few people involved.\n\nSome of the risks involved:\n- C++ is a large and complex language. There is no doubt about that. When I think about students looking to use OpenMC for their research, they will certainly have to go through a steep learning curve if they haven't used C++ before. But, I think that their time will be better spent learning C++ than learning Fortran and they will end up with a language skill that is beneficial outside of just scientific computing.\n- Another language pops up that is way better than C++ and satisfies most of our desires. For example, there are good arguments that Julia, young as it is, is a better language for scientific computing. However, rewriting in Julia would be a lot riskier than C++ in my opinion. The same is likely to be true of other new languages as well.\n"},"comment":{"url":"https://api.github.com/repos/mit-crpg/openmc/issues/comments/388806720","html_url":"https://github.com/mit-crpg/openmc/issues/603#issuecomment-388806720","issue_url":"https://api.github.com/repos/mit-crpg/openmc/issues/603","id":388806720,"user":{"login":"paulromano","id":743095,"avatar_url":"https://avatars1.githubusercontent.com/u/743095?v=4","gravatar_id":"","url":"https://api.github.com/users/paulromano","html_url":"https://github.com/paulromano","followers_url":"https://api.github.com/users/paulromano/followers","following_url":"https://api.github.com/users/paulromano/following{/other_user}","gists_url":"https://api.github.com/users/paulromano/gists{/gist_id}","starred_url":"https://api.github.com/users/paulromano/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/paulromano/subscriptions","organizations_url":"https://api.github.com/users/paulromano/orgs","repos_url":"https://api.github.com/users/paulromano/repos","events_url":"https://api.github.com/users/paulromano/events{/privacy}","received_events_url":"https://api.github.com/users/paulromano/received_events","type":"User","site_admin":false},"created_at":"2018-05-14T12:56:20Z","updated_at":"2018-05-14T12:56:20Z","author_association":"OWNER","body":"Thanks for the heads up @smharper. I also have a [branch](https://github.com/paulromano/openmc/tree/cpp-particle) where I've made the `Particle` derived type interoperable with a C struct so that it is possible to pass a particle back and forth between C and Fortran. I'll put in a PR for that one soon."}}
{"actor":{"display_login":"paulromano"}}