Pergunta

Eu tenho lutado com isso o dia todo, eu estou tentando obter um gerador de números aleatórios para segmentos no meu código CUDA. Eu olhei através de todos os fóruns e sim este tema vem à tona um pouco justo, mas eu gastei horas tentando desvendar todos os tipos de códigos sem sucesso. Se alguém souber de um método simples, provavelmente um dispositivo kernel que pode ser chamado de volta um float aleatório entre 0 e 1, ou um inteiro que eu possa transformar eu ficaria muito grato.

Mais uma vez, espero usar o número aleatório no kernel, assim como rand (), por exemplo.

Agradecemos antecipadamente

Foi útil?

Solução

Eu não estou certo que eu entendo por que você precisar de alguma coisa especial. Qualquer PRNG tradicional deve porto mais ou menos diretamente. A linear congruente deve funcionar bem. Você tem algumas propriedades especiais que você está tentando estabelecer?

Outras dicas

Para quem estiver interessado, agora você pode fazê-lo via cuRAND .

Eu acho que qualquer discussão sobre Esta questão necessita para responder à solicitação original de Zenna e que é para um nível fio implementação. Especificamente um função do dispositivo que pode ser chamado de dentro de um kernel ou fio . Desculpe se eu exagerei as frases "em negrito", mas eu realmente acho que as respostas até agora não são muito abordando o que está sendo procurado aqui.

A biblioteca cuRAND é sua melhor aposta. Compreendo que as pessoas estão querendo reinventar a roda (faz um apreciar e usar mais propriamente bibliotecas 3o partido), mas geradores de números de alta qualidade de alta performance são abundantes e bem testado. A melhor informação que eu posso recomendar é sobre a documentação para a biblioteca GSL sobre os diferentes geradores aqui: http://www.gnu.org/software/gsl/manual/html_node/Random-number-generator-algorithms.html

Para qualquer código sério é melhor usar um dos principais algoritmos que os matemáticos / computador-cientistas têm no chão mais e mais à procura de fraquezas sistêmicas. O "tornado mersenne" é algo com um período (ciclo de repetição) na ordem de 10 ^ 6000 (MT19997 means "Mersenne tornado 2 ^ 19997") que foi especialmente adaptado para Nvidia para utilização a um nível de rosca dentro roscas do mesmos warp usando chamadas de rosca ID como sementes. Consulte Papel aqui: http: / /developer.download.nvidia.com/compute/cuda/2_2/sdk/website/projects/MersenneTwister/doc/MersenneTwister.pdf . Estou realmente trabalhando para implementar somehting usando esta biblioteca e se eu fazê-lo funcionar corretamente vou postar meu código. Nvidia tem alguns exemplos em seu site a documentação para o kit de ferramentas CUDA atual.

NOTA: Apenas para o registro eu não trabalho para Nvidia, mas vou admitir seu projeto de documentação e abstração para CUDA é algo que até agora têm sido impressionado com

.

Dependendo de sua aplicação, você deve ser cauteloso em usar LCGs sem considerar se os fluxos (um fluxo por fio) se sobrepõem. Você poderia implementar um leapfrog com LCG, mas então você precisa ter um LCG período suficientemente longo para garantir que a seqüência não repetir.

Um exemplo saltar poderia ser:

template <typename ValueType>
__device__ void leapfrog(unsigned long &a, unsigned long &c, int leap)
{
    unsigned long an = a;
    for (int i = 1 ; i < leap ; i++)
        an *= a;
    c = c * ((an - 1) / (a - 1));
    a = an;
}

template <typename ValueType>
__device__ ValueType quickrand(unsigned long &seed, const unsigned long a, const unsigned long c)
{
    seed = seed * a;
    return seed;
}

template <typename ValueType>
__global__ void mykernel(
    unsigned long *d_seeds)
{
    // RNG parameters
    unsigned long a = 1664525L;
    unsigned long c = 1013904223L;
    unsigned long ainit = a;
    unsigned long cinit = c;
    unsigned long seed;

    // Generate local seed
    seed = d_seeds[bid];
    leapfrog<ValueType>(ainit, cinit, tid);
    quickrand<ValueType>(seed, ainit, cinit);
    leapfrog<ValueType>(a, c, blockDim.x);

    ...
}

Mas então o período de que o gerador é provavelmente insuficiente na maioria dos casos.

Para ser honesto, eu olhar para usando uma biblioteca de terceiros, como NAG . Há alguns geradores de lotes no SDK também, mas isso não é provavelmente o que você está procurando neste caso.

Editar

Uma vez que este apenas se levantou votado, eu acho que vale a pena atualizar mencionar que cuRAND , como mencionado por respostas mais recentes a esta questão, está disponível e fornece um número de geradores e distribuições. Isso é definitivamente o melhor lugar para começar.

A melhor maneira para isso é escrever o seu próprio função dispositivo, aqui é o único

void RNG()
{   
    unsigned int m_w = 150;
    unsigned int m_z = 40;

    for(int i=0; i < 100; i++)
    {
        m_z = 36969 * (m_z & 65535) + (m_z >> 16);
        m_w = 18000 * (m_w & 65535) + (m_w >> 16);

        cout <<(m_z << 16) + m_w << endl;  /* 32-bit result */
    }
}

Vai dar-lhe 100 números aleatórios com resultado de 32 bits.

Se você quiser alguns números aleatórios entre 1 e 1000, você também pode tomar o result%1000, quer no ponto de consumo, ou no ponto de geração:

((m_z << 16) + m_w)%1000

Alterar valores m_w e m_z inicial (no exemplo, 150 e 40) permite que você obtenha um resultado diferente cada vez. Você pode usar threadIdx.x como um deles, que deve dar-lhe diferentes séries pseudo-aleatórios cada vez.

Eu queria acrescentar que ele funciona 2 tempo mais rápido do que a função rand (), e funciona muito bem;)

Há um pacote MDGPU (GPL), que inclui uma implementação do rand48 GNU () função para CUDA aqui .

Eu encontrei-o (muito facilmente, usando o Google, que eu suponho que você tentou :-) nos fóruns NVidia aqui .

Eu não encontrei um bom paralelo gerador de números para CUDA, no entanto ENTENDI encontrar um gerador de números aleatórios paralela com base em pesquisa acadêmica aqui: http://sprng.cs.fsu.edu/

Você pode experimentar Mersenne Twister para GPUs

É baseada em orientada SIMD rápido Mersenne Twister (SFMT), que é um gerador de números bastante rápido e confiável aleatória. Ele passa testes Marsaglias DIEHARD para geradores de números aleatórios.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top