-
Notifications
You must be signed in to change notification settings - Fork 20
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
Pic manager #240
Pic manager #240
Conversation
@srikrrish @matt-frey |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I am not wrong BumponTailInstability still has the old structure. I think it is better to change that as well to be conformant with the other two mini-apps.
Added. |
constexpr bool EnablePhaseDump = false; | ||
|
||
// define functions used in sampling particles | ||
struct CustomDistributionFunctions { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can't this be derived from the Distribution class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you mean. The struct "CustomDistributionFunctions" is gonna be used as the template argument to make an instance of Distribution class
using DistR_t = ippl::random::Distribution<double, Dim, 2 * Dim, CustomDistributionFunctions>;
...
DistR_t distR(parR);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok somehow this is very confusing to me.. In my opinion if a mini-app requires custom distribution it should derive from the base class Distribution and just implement their own PDF, CDF etc. The base class Distribution would then be an abstract class with PDF, CDF etc. as pure virtual functions. This has clear hierarchy in my opinion. Or what problems do you face if you implement in this way?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initially, we implemented cdf/pdf with function pointers, which wasn't working on GPUs (I was getting illegal memory access, calling host function from a host device function type of error). We had a discussion early on, and the conclusion was that the virtual functions probably won't work on GPUs neither. Since functors work, I ended up with this implementation.
If we want to change the Distribution class again, we should do it in another issue/merge-request I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah.. we could try to handle virtual functions on GPUs through https://kokkos.github.io/kokkos-core-wiki/usecases/VirtualFunctions.html , https://github.com/kokkos/kokkos/blob/master/example/virtual_functions/main.cpp and that way we can have the structure as I mentioned. But I agree it is out of the scope of this PR. But something to consider in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have some requested changes. Also, this PR seems not complete. To me it looks like many basics things have already been merged ... unreviewed.
@@ -62,10 +62,11 @@ using Solver_t = VariantFromConditionalTypes<CGSolver_t<T, Dim>, FFTSolver_t<T, | |||
namespace ippl { | |||
template <typename T, unsigned Dim> | |||
class FieldSolverBase { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I do not yet see the purpose of this abstract base class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to remove FieldSolver from the list of template arguments of PicManager. We need a type here to make shared pointer fsolver_m out of it. However, the FieldSolver class is defined in alpine directory. I find two solutions:
-
We can create a base class for the field solver in src/Manager/. (FieldSolverBase) with very basic member variables. Then, use it to create fsolver_m pointer in pic-manager, and complete/extend it in the FieldSolver class in alpine/ directory by inheritance.
-
In src/Manager/PicManager.h we can include the field solver class from alpine/FieldSolver.hpp and use the class FieldSolver as a type directly to create fsolver_m pointer.
I implemented the 1st solution, which doesn't require including code from alpine/. directory.
Does it make sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, It is a good idea to remove the field solver from the list of template arguments. No, the second solution is definitely not a good idea. I agree with your choice.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a cursory reading, I also don't understand the point of the FieldSolver(Base)
classes. It seems to be that their functionality can be merged into other data types.
It appears that FieldSolverBase
is just a wrapper object for a solver. But what semantic meaning does this have? This class is useful if there are many situations where we need another application-generic abstraction layer between the solvers themselves and the application. But the abstraction layer itself doesn't do anything; all the functionality is provided in the ALPINE FieldSolver
. As I understand it, conceptually, we have a field solver for the solve step in PIC. But this doesn't require a separate class. The solver is part of the PIC loop and can thus be handled by the PIC manager itself.
The subclass FieldSolver
also isn't as generic as the name suggests, or at least its code isn't written this way. The class is clearly written to be a wrapper for an electrostatic solver, given that its fields are referred to as E
and rho
. The code in this class would be more suited to an ALPINE-level electrostatic PIC manager superclass from which the individual managers are derived. (It's ALPINE-level because the solver initialization uses hard coded settings which might not be adapted to other applications.)
I think these classes are a little redundant, but perhaps introduced because of the complexity of the Solver_t
alias. Prior to a clean interface for a shared PIC manager, we need to address #182 and unify the semantic meaning of the template parameters to the solvers. These intermediate solver wrappers provide an interface that would not be needed at all if we could simply have a pointer to Solver
be our solver and automatically handle the different solver types.
Once all the solvers have a compatible base type, the PIC manager simply needs a pointer to Solver
and all the solver setup becomes generic as well. This eliminates the need for any middle layer handling solver-specific initialization modulo solver settings, e.g. FFT parameters and such.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@matt-frey @srikrrish Do you agree on removing FieldSolver and its base class entirely? Should I implement its variables/methods in the AlpineManager?
alpine/LandauDampingManager.h
Outdated
Vector_t<double, Dim> hr_m = hr; | ||
Vector_t<double, Dim> origin_m = origin; | ||
if ((this->loadbalancethreshold_m != 1.0) && (ippl::Comm->size() > 1)) { | ||
Vector_t<double, Dim> kw = kw_m; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see in so many places you define new temporary variables. Why are they needed? and why can't you directly use here kw_m
? Note these things increase the lines of code (which we want to minimize) and gives an impression of a complex code even though the code itself might be simple only.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it because of KOKKOS_LAMBDA
vs KOKKOS_CLASS_LAMBDA
? In this case we may then want to not specify so many of them in the class and define some of them just locally rather than having it in the class as well as defining a temporary variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I use local variables so that the KOKKOS_LAMBDA doesn't copy all the member variables of the class in the loop. I'll try to reduce local variables as much as possible in the next commit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.. also if that is not possible try reducing the number of variables in the class (if they are not used everywhere) and just have them only defined as local variables
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should move UniformPlasmaTest.cpp, ChargedParticles.hpp, LandauDampingMixedExec.cpp and LandauDampingMixedPrecision.cpp to a separate new directory as having them here makes it confusing.
@Arc676 I requested a review from you as you worked on redesigning the mini-apps interfaces quite extensively. But feel free to skip it if you don't have time which is perfectly fine. Note since some parts of this are already merged if you want to have a full overview unfortunately you have to directly look at the files and also may not be able to directly comment on the lines which you would like to. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some of the code (not necessarily introduced in this PR) is not properly formatted. (I didn't fully read through all the changes in the PR; the changes to the existing managers seem to be interface changes so I just skimmed through those.)
@@ -62,10 +62,11 @@ using Solver_t = VariantFromConditionalTypes<CGSolver_t<T, Dim>, FFTSolver_t<T, | |||
namespace ippl { | |||
template <typename T, unsigned Dim> | |||
class FieldSolverBase { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From a cursory reading, I also don't understand the point of the FieldSolver(Base)
classes. It seems to be that their functionality can be merged into other data types.
It appears that FieldSolverBase
is just a wrapper object for a solver. But what semantic meaning does this have? This class is useful if there are many situations where we need another application-generic abstraction layer between the solvers themselves and the application. But the abstraction layer itself doesn't do anything; all the functionality is provided in the ALPINE FieldSolver
. As I understand it, conceptually, we have a field solver for the solve step in PIC. But this doesn't require a separate class. The solver is part of the PIC loop and can thus be handled by the PIC manager itself.
The subclass FieldSolver
also isn't as generic as the name suggests, or at least its code isn't written this way. The class is clearly written to be a wrapper for an electrostatic solver, given that its fields are referred to as E
and rho
. The code in this class would be more suited to an ALPINE-level electrostatic PIC manager superclass from which the individual managers are derived. (It's ALPINE-level because the solver initialization uses hard coded settings which might not be adapted to other applications.)
I think these classes are a little redundant, but perhaps introduced because of the complexity of the Solver_t
alias. Prior to a clean interface for a shared PIC manager, we need to address #182 and unify the semantic meaning of the template parameters to the solvers. These intermediate solver wrappers provide an interface that would not be needed at all if we could simply have a pointer to Solver
be our solver and automatically handle the different solver types.
Once all the solvers have a compatible base type, the PIC manager simply needs a pointer to Solver
and all the solver setup becomes generic as well. This eliminates the need for any middle layer handling solver-specific initialization modulo solver settings, e.g. FFT parameters and such.
Done here 1ca0a23 |
Regarding the naming for the directory containing the examples without PicManager, at present I also don't have a good solution. But alpine0 sounds confusing. Also this additional directory can still be within the alpine directory itself as they are still alpine related examples. Currently I can only think of naming the directory as |
|
@mohsensadr Thanks for incorporating the comments and suggestions. I think some of the (possibly) larger issues in this PR can be addressed separately in other issues in the order of their priority and timing constraints. Hence I am approving it at the moment. |
@srikrrish No worries and thanks for your patience. I think I can merge only after @matt-frey has also approved it. |
Updating the pic-manager in the dev-3.2.0 including:
-making member variables of defined classes private.
-adding get/set functions.
-removing field solver from template parameter of pic-manager.
-revising the MPI calls according to dev-3.2.0.