问题
hi i am converting this c++ ( openmp ) parallel for to c# parallel for but it says :
Error 1 Not all code paths return a value in lambda expression of type '
System.Func<int,System.Threading.Tasks.ParallelLoopState,int,int>
'
here is my codes :
c++
void floyd_warshall(int NumOfThreads) {
int i, j, k;
omp_set_num_threads(NumOfThreads);
for (k = 0; k < n; ++k)
#pragma omp parallel for private(i,j)
for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
/* If i and j are different nodes and if
the paths between i and k and between
k and j exist, do */
if ((dist[i][k] * dist[k][j] != 0) && (i != j))
/* See if you can't get a shorter path
between i and j by interspacing
k somewhere along the current
path */
if ((dist[i][k] + dist[k][j] < dist[i][j]) || (dist[i][j] == 0))
dist[i][j] = dist[i][k] + dist[k][j];
}
c#
void floyd_warshall(int NumOfThreads)
{
int k;
ParallelOptions pOp;
pOp.MaxDegreeOfParallelism = NumOfThreads;
for (k = 0; k < n; ++k)
Parallel.For<int>(0, n, pOp , () => 0, (i, loop, j) =>
{ // for (i = 0; i < n; ++i)
for (j = 0; j < n; ++j)
/* If i and j are different nodes and if
the paths between i and k and between
k and j exist, do */
if ((dist[i, k] * dist[k, j] != 0) && (i != j))
/* See if you can't get a shorter path
between i and j by interspacing
k somewhere along the current
path */
if ((dist[i, k] + dist[k, j] < dist[i, j]) || (dist[i, j] == 0))
dist[i, j] = dist[i, k] + dist[k, j];
}, (j) => 0);
}
回答1:
You can use a simpler overload of the Parallel.For
method that doesn't require your delegate to have a return vale.
var pOp = new ParallelOptions { MaxDegreeOfParallelism = NumOfThreads };
for (int k = 0; k < n; ++k)
Parallel.For(0, n, pOp, i =>
{ // for (i = 0; i < n; ++i)
for (int j = 0; j < n; ++j)
/* If i and j are different nodes and if
the paths between i and k and between
k and j exist, do */
if ((dist[i, k] * dist[k, j] != 0) && (i != j))
/* See if you can't get a shorter path
between i and j by interspacing
k somewhere along the current
path */
if ((dist[i, k] + dist[k, j] < dist[i, j]) || (dist[i, j] == 0))
dist[i, j] = dist[i, k] + dist[k, j];
});
回答2:
I ran into the same problem as you and managed to solve it. It turns out that our code is doing very similar things with Parallel.For. You can see my solution from this link. The biggest difference seems to be that you are using a value type (int) for thread local storage and I am using a reference type.
The first issue is that you need a return statement. For example, right before this line:
}, (j) => 0);
Add something like:
return 0;
The 2nd thing you will probably have to do is replace this line:
}, (j) => 0);
with something like:
}, (j) => j = 0);
This is the 5th parameter to the Parallel.For function and is called by each thread after its work has been completed. You can also do a no op by doing something like j = j, if you need the value unchanged. But, that will generate a self assignment warning and you will have to use a #pragma to disable the warning.
来源:https://stackoverflow.com/questions/27077472/simple-convert-openmp-parallel-for-to-c-sharp-parallel-for