CAA Workshop 1 Benchmark Category 3 using Rust and Python

2 minute read

Scientific computing means and implies that the targeted applications are solvable on the fastest computer system available now and possibly tomorrow. In the field of computational fluid dynamics (CFD) the simulation on HPC (high-performance computing) systems easily uses the numerical domain consisting of billions of meshes. The demands of multi-physics multi-scale solutions increases complexity of governing equations and their numerical models. With rising of new paradigms in IT (information technologies) the scientific simulations have adopted artificial intelligence (AI) in its prior tools for analysis, e.g., AI-based analysis towards flow control and design optimization.

For a long time, however, the code implementation in CFD tools has been done with FORTRAN or C languages. It is also on-going truth in the most of the CFD engineering. Of course, the fundamental development of the CFD solvers must be built on the robust and accurate numerical methods formulated with the stable libraries. However, at the beginning of the software engineering (at least for the CFD) far more enthusiastic efforts were the main thrust to realize the current advancement in the various fluid dynamic technologies. Furthermore, the seamless coupling of new software libraries could be realized with the new concepts in the modern programming languages. Rust is the one designed for performance, memory safety, and concurrency. An couple of hours effort shows that the Rust programming can achieve a good performance in the numerical simulation of a real world application.

CAA Workshop 1 benchmark problem (category 3)

  • Python: Flux calculation

    def CalculateRHS(self):
        ...
        self.DQ[0,:,:,3:-3] =
              self.ACoeff[1]*self.E[:,:,4:-2]
            + self.ACoeff[2]*self.E[:,:,5:-1]
            + self.ACoeff[3]*self.E[:,:,6:  ]
            - self.ACoeff[1]*self.E[:,:,2:-4]
            - self.ACoeff[2]*self.E[:,:,1:-5]
            - self.ACoeff[3]*self.E[:,:, :-6]
        ...
    

    and the main time-step loop.

    def Solver(self, IterationMax):
        for iteration in range(IterationMax):
            self.time = self.time + self.dt
            self.CalculateRHS()
            self.TimeIntegration()
            self.SaveDQ()
    
  • Rust: Flux calculation

    fn spatial_discretization (dom: &mut Domain) -> String {
        let message: String = format!("calculate flux");
        ...
        dom.fielddata[ii+_dq] =
              dom.fielddata[ii-3+_eflux] *acoeff_array[0]
            + dom.fielddata[ii-2+_eflux] *acoeff_array[1]
            + dom.fielddata[ii-1+_eflux] *acoeff_array[2]
            + dom.fielddata[ii+1+_eflux] *acoeff_array[3]
            + dom.fielddata[ii+2+_eflux] *acoeff_array[4]
            + dom.fielddata[ii+3+_eflux] *acoeff_array[5];
        ...
    

    and the Main loop advancing time steps.

    pub fn wave_propagation (max_iteration: usize, dom: &mut Domain) {
        ...
        let mut message = domain_initial_condition(dom);
        let computing_time = std::time::SystemTime::now();
        while iteration <= max_iteration {
            message = save_formerstep_qvar(dom);
            message.push_str(&calculate_fluxes(dom));
            message.push_str(&spatial_discretization(dom));
            println!("CAArust: finished functions {}", message);
            residual_error = time_integration(dom);
            iteration += 1;
        }
        println!("CAArust: elapsed time {:?}", computing_time.elapsed());
    }
    

The Python code has no implementation of Residual calculation which again visits all numerical meshes at the end of time integration. Nevertheless, the runtime is 2 times longer than that of Rust. But, to get the same result Rust consumes a lot of code lines in the current raw implementation. Using ndarray it could be enhanced in the main project.

  • Comparison of runtime for 1000 iterations (2D domain size 501$\times$501)

    Language Code lines (main kernel) Run-time
    Rust 363 21.8 s
    Python 149 44.0 s

Tags:

Updated: