使用openMP时的意外行为任务

时间:2018-03-31 16:10:15

标签: c openmp pseudocode sudoku

我试图编写一个用于解决数独的蛮力算法的并行版本。

串行算法如下,伪码:

solve(matrix, x, y):
    for i in [0,9]:
        //If test number fits rules
        if(valid(matrix, x, y, i):
            matrix[y,x] = i
            //Try next cell recursively
            if(solve(matrix, nextEmptyX, nextEmptyY)) return true
            //test number not the solution, backtrack.
            matrix[y][x] = 0
 return false;

如果我在这个伪代码中犯了错误,我很抱歉,但我认为这是正确的。无论哪种方式,我的串行算法都可以工作。

问题在于我试图像这样对其进行并行化

solve(matrix, x, y):
    for i in [0,9]:
        if(valid(matrix, x, y, i):
            val = 0
            #pragma omp task firstprivate(x, y, i, matrix, val)
                copy_matrix = copyOf(matrix)
                copy_matrix[y][x] = i
                val = solve(copy_matrix, nextEmptyX, nextEmptyY)
                if(val) print_matrix
            if(val) return true
            matrix[y][x] = 0
#pragma omp taskwait 
return false;

在我看来,这段代码应该尝试新任务中每个单元格的每个暂定值,并且至少有一个任务应该有正确的解决方案。但是当我运行它时,它并没有测试(y,x)的每个组合(它实际上似乎只测试矩阵的第一行而且它没有找到结果。

我这样打电话:

#pragma omp parallel sections
    {
            #pragma omp section
            solve(matrix, 0, 0);
    }

通过设置omp_set_num_threads(1)

,即使对于单个线程也是如此

如果除了删除OMP注释之外什么都不做,那么该算法可以正常工作。

有人能看到问题吗?

编辑:我刚刚意识到有时执行会跳过任务块,我不知道为什么会发生这种情况,但似乎导致问题。

1 个答案:

答案 0 :(得分:0)

C中,#pragma omp仅适用于以下行。

缩进表明你应该

solve(matrix, x, y):
    for i in [0,9]:
        if(valid(matrix, x, y, i):
            val = 0
            #pragma omp task firstprivate(x, y, i, matrix, val)
              {
                copy_matrix = copyOf(matrix)
                copy_matrix[y][x] = i
                val = solve(copy_matrix, nextEmptyX, nextEmptyY)
                if(val) print_matrix
              }
            if(val) return true
            matrix[y][x] = 0
#pragma omp taskwait 
return false;

不确定这是否足以解决您的问题。