Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 为什么湿漉漉的人会得到“湿”字;Can';t矢量表达式GHC.Prim.Int“;DPH程序中的错误?_Haskell_Data Parallel Haskell - Fatal编程技术网

Haskell 为什么湿漉漉的人会得到“湿”字;Can';t矢量表达式GHC.Prim.Int“;DPH程序中的错误?

Haskell 为什么湿漉漉的人会得到“湿”字;Can';t矢量表达式GHC.Prim.Int“;DPH程序中的错误?,haskell,data-parallel-haskell,Haskell,Data Parallel Haskell,我试图用DPH实现nqueens问题,但最终出现了无法向量化GHC.Prim.Int#错误。当我在谷歌上搜索错误时,我发现了一个GHC Bug,它谈到了用于模式匹配的向量化文字(http://haskell.1045720.n5.nabble.com/GHC-5702-Can-t-vectorise-pattern-matching-on-numeric-literals-td5076659.html). 我不确定这是否是同一个bug。 我的代码如下: {-# LANGUAGE Parallel

我试图用DPH实现nqueens问题,但最终出现了无法向量化GHC.Prim.Int#错误。当我在谷歌上搜索错误时,我发现了一个GHC Bug,它谈到了用于模式匹配的向量化文字(http://haskell.1045720.n5.nabble.com/GHC-5702-Can-t-vectorise-pattern-matching-on-numeric-literals-td5076659.html). 我不确定这是否是同一个bug。 我的代码如下:

{-# LANGUAGE ParallelArrays #-}
{-# OPTIONS_GHC -fvectorise #-}
module NQueensP (nqueens_wrapper) 
where

import qualified Prelude
import Data.Array.Parallel
import Data.Array.Parallel.Prelude
import Data.Array.Parallel.Prelude.Int as I
import qualified Data.Array.Parallel.PArray as P


isSafe i q n  = isSafeHelper i (Prelude.zip (P.toList (toPArrayP q)) [n, n I.- 1..1]) 
            where isSafeHelper i []  = True
                  isSafeHelper i (x:xs) = (i I.== Prelude.fst x) && I.abs(i I.-   
                                  (Prelude.fst x)) I./= I.abs(n I.- (Prelude.snd x)) && 
                                       isSafeHelper i xs

nqueens_wrapper::Int -> PArray (PArray Int)
nqueens_wrapper n = toPArrayP (mapP toPArrayP (nqueens n 0))

nqueens::Int -> Int -> [:[:Int:]:]
nqueens n 1 = [:[:i:] | i <- (enumFromToP 1 n) :]
nqueens n k = [: [:i:] +:+ q | i <- oneton, q <- boards, isSafe i q k:]
           where boards = nqueens n (k I.- 1)
                 oneton = (enumFromToP 1 n) 
{-#语言并行数组}
{-#选项{GHC-fvectorise}
模块NQueensP(nqueens\u包装器)
哪里
进口合格前奏曲
导入Data.Array.Parallel
导入Data.Array.Parallel.Prelude
将Data.Array.Parallel.Prelude.Int作为I导入
将限定的Data.Array.Parallel.PArray作为P导入
isSafe i q n=isSafeHelper i(Prelude.zip(P.toList(toPArrayP q))[n,ni.-1..1])
其中isSafeHelper i[]=True
isSafeHelper i(x:xs)=(i.i.==Prelude.fst x)和i.abs(i.i.-
(Prelude.fst x)I./=I.abs(ni.-(Prelude.snd x))和
isSafeHelper i xs
nqueens_包装器::Int->PArray(PArray Int)
nqueens_包装n=toPArrayP(mapP-toPArrayP(nqueens n 0))
nqueens::Int->Int->[:[:Int:::]

nqueens n 1=[:[:i:]| i是的,这似乎与您提到的bug有关。您得到的错误源于此行:

nqueens n 1 = [:[:i:] | i <- (enumFromToP 1 n) :]

我们现在已经处理了一条神秘的错误消息。这并不意味着我们已经完成了,因为下一条错误消息似乎同样神秘:

*** Vectorisation error ***
    Tycon not vectorised:  []
isSafe
(我认为)的问题在于,您使用了大量未使用
-fvectorise
编译的数据类型和变量。这意味着您不能只使用链接列表(
Tycon未矢量化:[]
),
Prelude.fst
Prelude.snd
,或
Prelude.zip
,除非您在模块中重新定义这些结构。(令人烦恼的是,如果不重新定义,我甚至无法使用
()

我们将不得不重写isSafe
。让我们看看它的第一行:

isSafe i q n  = isSafeHelper i (Prelude.zip (P.toList (toPArrayP q)) [n, n I.- 1..1]) 
我们不能使用
Prelude.zip
,但我们可以使用
zip
,这意味着我们不必再转换
q
。但是,我们的递减列表应该使用DPH组合符重写。愚蠢的是,
enumFromThenToP
不存在,所以我们将说
mapP(ni.-)(enumfromtop0(ni.-1))
以获得与
[n,ni.-1..1]
的并行等价物。因此这一行变成:

isSafe i q n  = isSafeHelper i (zipP q (mapP (n I.-) (enumFromToP 0 (n I.- 1))))
现在,对于isSafeHelper:

isSafeHelper i [] = True
isSafeHelper i (x:xs)
    = (i I.== Prelude.fst x)
    && I.abs(i I.- (Prelude.fst x)) I./= I.abs(n I.- (Prelude.snd x))
    && isSafeHelper i xs
由于
Prelude.fst
Prelude.snd
不可用,您可以通过在模式本身中提取元组的以下部分来解决此问题:

isSafeHelper i [] = True
isSafeHelper i ((x1,x2):xs)
    = (i I.== x1)
    && I.abs(i I.- x) I./= I.abs(n I.- x2)
    && isSafeHelper i xs
但是,当然,它仍然无法编译:您的参数将是一个平行列表,而不是序曲样式的链表。为了解决这个问题,我们将使用以下函数以更具功能性的样式重写它:

all
仍然适用于链接列表,但请注意,您并不是在自己的函数中手动解构列表。如果有一个用于并行列表的
allP
不是很好吗?它会,但没有。不过,编写它并不难:

allP :: (a -> Bool) -> [: a :] -> Bool
allP p arr = andP (mapP p arr)
将所有这些放在一起,您可以编写
isSafe
,如下所示:

isSafe i q n = allP (isSafePredicate i n) (zipP q ntoone) 
  where
    isSafePredicate i n (x1, x2)
        = (i I.== x1)
        && I.abs(i I.- x1) I./= I.abs(n I.- x2)
    ntoone = mapP (n I.-) (enumFromToP 0 (n I.- 1))

nqueens\u包装器
看起来不错。您的代码现在应该可以编译了

请注意:

  • 我不知道它是否有效(我得到了
    ***异常:crossMapP:notimplemented
    ,并且不知道如何修复它),但它看起来应该有效
  • 用另一种方法重写
    isSafe
    是行不通的。如果你试图在
    Prelude
    列表中使用
    Prelude
    数字,你最终会再次抱怨
    Int
    。我想这是因为
    isSafe
    至少有一个向量化函数
    nqueens
    使用
  • 不要包含
    Data.Array.Parallel.Prelude
    。声明如下:

    此模块不应再在用户代码中显式导入。用户代码只应并行导入,并且在向量器支持类型类之前,导入特定于类型的模块

  • 不要对本地定义发疯。
    isSafeHelper
    在您的版本中缺少其
    n
    参数

allP :: (a -> Bool) -> [: a :] -> Bool
allP p arr = andP (mapP p arr)
isSafe i q n = allP (isSafePredicate i n) (zipP q ntoone) 
  where
    isSafePredicate i n (x1, x2)
        = (i I.== x1)
        && I.abs(i I.- x1) I./= I.abs(n I.- x2)
    ntoone = mapP (n I.-) (enumFromToP 0 (n I.- 1))