Open greole opened 5 months ago
One of the requirements should be that you can switch between different parallel implementation: mpi, openmp+mpi and GPU+mpi by changing a keyword. Consequently, the field needs to be allocated on the different corresponding device.
A solution to achive could be the executor model of ginkgo.
Ginkgo implements multiple executors:
// define the omp, cuda, hip and reference kernels which will be bound to the
// operation
namespace kernels {
namespace omp {
void my_kernel(int x) {
// omp code
}
}
namespace cuda {
void my_kernel(int x) {
// cuda code
}
}
namespace hip {
void my_kernel(int x) {
// hip code
}
}
namespace dpcpp {
void my_kernel(int x) {
// dpcpp code
}
}
namespace reference {
void my_kernel(int x) {
// reference code
}
}
// Bind the kernels to the operation
[GKO_REGISTER_OPERATION](https://ginkgo-project.github.io/ginkgo-generated-documentation/doc/develop/group__Executor.html#ga7f2c119ff9f4f51c7f8e2d5dbbbbd044)(my_op, my_kernel);
int main() {
// create executors
auto omp = OmpExecutor::create();
auto cuda = CudaExecutor::create(0, omp);
auto hip = HipExecutor::create(0, omp);
auto dpcpp = DpcppExecutor::create(0, omp);
auto ref = ReferenceExecutor::create();
However, this would allow to implement the kernel differently for different GPU architectures. But it would also requires the implementation and maintenance of the same kernel for multiple architectures.
I could be sufficient to have a GPU, OpenMP, Serial exectutor. The type of GPU would be decided at compile time e.g. CUDA, HIP, SYCL.
Another question is how would you distribute the binaries (parameters: architecture, implementation)?
@bevanwsjones
regarding 3 (units): This library could be a candidate https://github.com/mpusz/mp-units
Also potentially interesting talk https://www.youtube.com/watch?v=aF3samjRzD4
Use thrust function calls to get std::algorithm kind functionality. For executor model ->
Discussing it we came up with the names Domain
for DomainField
and MeshedDomain
for GeometricFields
I am currently thinking about what the right level of abstraction and inheritance for expressing fields could be. For OpenFOAM we have several field classes:
Field<scalar>
Additionally various typedefs exists for convenience like:
The following code snipped shows how boundary and internalField are handled
Required Components
Proposed changes
Open questions:
ScalarField
instead ofvolScalarField
to make naming more concise; (GeometricScalarField
)scalarField
andvolScalarField
.scalarFields
vsvolScalarFields
, both have access to arithmetic functions butvolScalarFields
contain boundaries;Notes