Como um grande número de atribuições para a mesma matriz causa um pyopencl.LogicError quando executado na GPU?

Estou usando pyOpenCL para fazer alguns cálculos complexos. Ele roda bem na CPU, mas recebo um erro ao tentar executá-lo em uma NVIDIA GeForce 9400M (256 MB). Estou trabalhando no Mac OS X Lion (10.7.5)

O estranho é que esse erro nem sempre aparece. Parece ocorrer quando meus cálculos usam números maiores (resultando em iterações maiores), mas apenas quando executados na GPU.

Não estou escrevendo para locais de memória que não devo escrever. Excluí possíveis problemas com a modificação simultânea executando o código como um único item de trabalho.

Simplifiquei meu código OpenCL o máximo possível e, a partir do que foi deixado, criei um código muito simples com comportamento extremamente estranho que causa apyopencl.LogicError. Consiste em 2 loops aninhados, nos quais são feitas algumas atribuições aoresult array. Essa atribuição nem precisa depender do estado do loop. Isso é executado em um único thread (ou item de trabalho,shape = (1,)) na GPU.

__kernel void weirdError(__global unsigned int* result){
    unsigned int outer = (1<<30)-1;
    for(int i=20; i--; ){
        unsigned int inner = 0;
        while(inner != outer){
            result[0] = 1248;
            result[1] = 1337;
            inner++;
        }
        outer++;
    }
}

O estranho é que a remoção de qualquer uma das atribuições à matriz de resultados remove o erro. Além disso, diminuindo o valor inicial de externo (até(1<<20)-1 por exemplo) também remove o erro. Nesses casos, o código retorna normalmente, com o resultado correto disponível no buffer correspondente. Na CPU, nunca gera um erro.

O código OpenCL é executado no Python usando o PyOpenCL.

Nada extravagante na configuração:

platform = cl.get_platforms()[0]
device = platform.get_devices(cl.device_type.GPU)[0]
context = cl.Context([device])
program = cl.Program(context, getProgramCode()).build()
queue = cl.CommandQueue(context)

Neste código Python, defino oresult_buf para0, então eu executo o cálculo no OpenCL que definirá seus valores em uma iteração grande. Depois, tento coletar esse valor da memória do dispositivo, mas é aí que dá errado:

result = numpy.zeros(2, numpy.uint32)
result_buf = cl.Buffer(context, mem_flags.READ_WRITE | mem_flags.COPY_HOST_PTR, hostbuf=result)

shape = (1,)
program.weirdError(queue, shape, None, result_buf)

cl.enqueue_copy(queue, result, result_buf)

A última linha me dá:

pyopencl.LogicError: clEnqueueReadBuffer failed: invalid command queue

Como essa atribuição repetida pode causar um erro?

E mais importante: como isso pode ser evitado?

Entendo que esse problema provavelmente depende da plataforma e, portanto, talvez seja difícil de reproduzir. Mas essa é a única máquina à qual tenho acesso; portanto, o código deve funcionar nessa máquina.

AVISO LEGAL: Eu nunca trabalhei com OpenCL (ou CUDA) antes. Eu escrevi o código em uma máquina em que a GPU não suporta OpenCL. Eu sempre testei na CPU. Agora que mudei para a GPU, acho frustrante que os erros não ocorram de maneira consistente e não faço ideia do porquê.

questionAnswers(2)

yourAnswerToTheQuestion