Nesrinekh / OpenPME

ISC License
4 stars 0 forks source link

Particle/Mesh Loop fusion #79

Open lschuetze opened 3 years ago

lschuetze commented 3 years ago

In the mesh/Gray Scott example there are two consecutive accesses to properties of the mesh New which result in two consecutive mesh loops in the generated C++ code.

If there is no remashing, ghost get etc. in between those two expressions, the mesh loops should be fused (as the domain is the same mesh).

OpenPME code Screen Shot 2021-02-05 at 07 38 44

Resulting generated code for that expressions

    // Mesh loop
    auto mloop_iterator_a01a0 = New.getDomainIterator();
    while (mloop_iterator_a01a0.isNext())
    {
      auto loopNodeM = mloop_iterator_a01a0.get();
      New.template get<Un>(loopNodeM) = (Old.template get<Uo>(loopNodeM) + (dt * ((du * (((((Old.template get<Uo>(loopNodeM.move(0, 1)) + Old.template get<Uo>(loopNodeM.move(0, -1))) / (pow(Old.spacing(0), 2))) + ((Old.template get<Uo>(loopNodeM.move(1, 1)) + Old.template get<Uo>(loopNodeM.move(1, -1))) / (pow(Old.spacing(1), 2)))) + ((Old.template get<Uo>(loopNodeM.move(2, 1)) + Old.template get<Uo>(loopNodeM.move(2, -1))) / (pow(Old.spacing(2), 2)))) - (2 * (Old.template get<Uo>(loopNodeM) * (((1 / (pow(Old.spacing(0), 2))) + (1 / (pow(Old.spacing(1), 2)))) + (1 / (pow(Old.spacing(2), 2)))))))) - ((Old.template get<Uo>(loopNodeM) * (pow(Old.template get<Vo>(loopNodeM), 2))) - (F * (1.0 - Old.template get<Uo>(loopNodeM)))))));
      ++mloop_iterator_a01a0;
    }

    // Mesh loop
    auto mloop_iterator_b01a0 = New.getDomainIterator();
    while (mloop_iterator_b01a0.isNext())
    {
      auto loopNodeM = mloop_iterator_b01a0.get();
      New.template get<Vn>(loopNodeM) = (Old.template get<Vo>(loopNodeM) + (dt * ((dv * (((((Old.template get<Vo>(loopNodeM.move(0, 1)) + Old.template get<Vo>(loopNodeM.move(0, -1))) / (pow(Old.spacing(0), 2))) + ((Old.template get<Vo>(loopNodeM.move(1, 1)) + Old.template get<Vo>(loopNodeM.move(1, -1))) / (pow(Old.spacing(1), 2)))) + ((Old.template get<Vo>(loopNodeM.move(2, 1)) + Old.template get<Vo>(loopNodeM.move(2, -1))) / (pow(Old.spacing(2), 2)))) - (2 * (Old.template get<Vo>(loopNodeM) * (((1 / (pow(Old.spacing(0), 2))) + (1 / (pow(Old.spacing(1), 2)))) + (1 / (pow(Old.spacing(2), 2)))))))) + ((Old.template get<Uo>(loopNodeM) * (pow(Old.template get<Vo>(loopNodeM), 2))) - ((F + K) * Old.template get<Vo>(loopNodeM))))));
      ++mloop_iterator_b01a0;
    }
    Old.copy(New);
    Old.template ghost_get<Uo, Vo>();