computablee / DotMP

A collection of powerful abstractions for parallel programming in .NET with an OpenMP-like API.
https://computablee.github.io/DotMP/
GNU Lesser General Public License v2.1
29 stars 8 forks source link

Add `ForReduction` and `ParallelForReduction` #10

Closed computablee closed 1 year ago

computablee commented 1 year ago

OpenMP's for construct supports a reduction clause, used like this:

// suppose there's a vector `double arr[]' with length `len`
double sum = 0;

#pragma omp parallel for reduction(+:sum)
for (int i = 0; i < len; i++)
    sum += arr[i];

I was thinking of implementing this as follows:

// suppose there's an array `double[] arr`
double sum = 0;

OpenMP.Parallel.ParallelForReduction(0, arr.Length, to: ref sum, op: (a, b) => a + b, action: (ref sum) => {
    sum += arr[i];
});

However, there are some problems.

  1. We would need to accept a custom delegate void ActionRef<T>(ref T a) instead of the Action that's accepted by For.
  2. Future interoperability with private/firstprivate/shared as documented by #9
  3. This won't work for subtraction, as is supported by OpenMP's reduction clause (this might be fine, we can discuss).
  4. Setting the default value of the thread-local variable passed to ActionRef as documented here.

The biggest issue I see is 2 on this list. #9 documents issues with hugely added complexity implementing those clauses, and this would only compound the issue. The easy way out is to not support the clauses in #9 in ForReduction and ParallelForReduction, but that sounds cheap to me. Number 4 on this list also feels like it could be a big problem, though could be mitigated by adding a OpenMP.Operations enum and passing that instead of a lambda (this would fix number 3, too!). Any insight would be appreciated!

computablee commented 1 year ago

I have implemented these.