Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[on hold] Draft/demo: Use Boost.PFR to reflect record dimension #148

Draft
wants to merge 7 commits into
base: develop
Choose a base branch
from

Conversation

bernhardmgruber
Copy link
Member

Do not merge this PR! For now this is just a demo.

Using Boost.PFR we can reflect existing structures and explores the possibilities:

  • Create LLAMA's datum domain without the need of these unwieldy typelists, just by reflection an existing struct.
  • This existing struct is also used to represent data on the stack, so llama::One<T> should also no longer be needed.
  • Use your overloaded operators on your struct instead of the ones LLAMA provides.
  • Navigate on your data structure using view(x, y)->pos.x instead of view(x, y)(tag::Pos{}, tag::X{}) during reading.

Datum domain definition before:

using Particle = llama::DS<
    llama::DE<tag::Pos, llama::DS<
        llama::DE<tag::X, FP>,
        llama::DE<tag::Y, FP>,
        llama::DE<tag::Z, FP>
    >>,
    llama::DE<tag::Vel, llama::DS<
        llama::DE<tag::X, FP>,
        llama::DE<tag::Y, FP>,
        llama::DE<tag::Z, FP>
    >>,
    llama::DE<tag::Mass, FP>
>;

After:

struct Vec
    FP x;
    FP y;
    FP z;
    // ... operators
};

struct Particle {
    Vec pos;
    Vec vel;
    FP mass;
};

Compare the change of the n-body pPInteraction function from:

void pPInteraction(VirtualParticleI&& pi, VirtualParticleJ pj) {
    auto dist = pi(tag::Pos{}) - pj(tag::Pos{});
    dist *= dist;
    const FP distSqr = EPS2 + dist(tag::X{}) + dist(tag::Y{}) + dist(tag::Z{});
    const FP distSixth = distSqr * distSqr * distSqr;
    const FP invDistCube = 1.0f / std::sqrt(distSixth);
    const FP sts = pj(tag::Mass{}) * invDistCube * TIMESTEP;
    pi(tag::Vel{}) += dist * sts;
}

to:

void pPInteraction(VirtualParticleI&& pi, VirtualParticleJ pj) {
    Particle dist = pi->pos - pj->pos; // your struct, your operators
    dist *= dist;
    const FP distSqr = EPS2 + dist.x + dist.y + dist.z;
    const FP distSixth = distSqr * distSqr * distSqr;
    const FP invDistCube = 1.0f / std::sqrt(distSixth);
    const FP sts = pj->mass * invDistCube * TIMESTEP;
    pi(1_DC) = pi->vel + dist * sts; // 1_DC == llama::DatumCoord<1>
}

Also consider the particle creation loop changed from:

Particle p = particles(i);
p(tag::Pos{}, tag::X{}) = dist(engine);
p(tag::Pos{}, tag::Y{}) = dist(engine);
p(tag::Pos{}, tag::Z{}) = dist(engine);
p(tag::Vel{}, tag::X{}) = dist(engine) / FP(10);
p(tag::Vel{}, tag::Y{}) = dist(engine) / FP(10);
p(tag::Vel{}, tag::Z{}) = dist(engine) / FP(10);
p(tag::Mass{}) = dist(engine) / FP(100);

to:

Particle p;
p.pos.x = dist(engine);
p.pos.y = dist(engine);
p.pos.z = dist(engine);
p.vel.x = dist(engine) / FP(10);
p.vel.y = dist(engine) / FP(10);
p.vel.z = dist(engine) / FP(10);
p.mass = dist(engine) / FP(100);
particles(i) = p;

This prototype has a drawback, because it invokes the mapping function unnecessarily. During each datum access view(x, y)->, a full datum is fetched which is used for navigation. The compiler discards the unused loads and computations in the mapping function. But this still leads to wrong results if the mapping function is stateful.

@bernhardmgruber bernhardmgruber force-pushed the pfr branch 2 times, most recently from de0bb6c to c7d1336 Compare February 3, 2021 17:54
@bernhardmgruber bernhardmgruber changed the title Draft/demo: Use Boost.PFR to reflect datum domain Draft/demo: Use Boost.PFR to reflect record dimension Jul 6, 2021
@bernhardmgruber bernhardmgruber changed the title Draft/demo: Use Boost.PFR to reflect record dimension [on hold] Draft/demo: Use Boost.PFR to reflect record dimension Dec 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant