2

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);
        }

2 Answers2

2

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];
        });
Douglas
  • 53,759
  • 13
  • 140
  • 188
  • `j` is a private variable for each thread, since it's declared *within* the anonymous function. It wouldn't have been private if you'd declared it at the beginning of your outer method (like you did in your C++ code). – Douglas Nov 22 '14 at 13:26
0

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.

Community
  • 1
  • 1
Bob Bryan
  • 3,687
  • 1
  • 32
  • 45