CUDA: agrupando a alocação de memória do dispositivo em C ++

Estou começando a usar o CUDA no momento e tenho que admitir que estou um pouco decepcionado com a API C. Entendo os motivos da escolha C, mas, se a linguagem tivesse sido baseada em C ++, vários aspectos seriam muito mais simples, por exemplo, alocação de memória do dispositivo (viacudaMalloc)

Meu plano era fazer isso sozinho, usando sobrecarregadooperator new com colocaçãonew e RAII (duas alternativas). Eu estou querendo saber se há alguma ressalva que eu não notei até agora. O códigoparece para trabalhar, mas ainda estou pensando em possíveis vazamentos de memória.

O uso doRAII código seria o seguinte:

CudaArray<float> device_data(SIZE);
// Use `device_data` as if it were a raw pointer.

Talvez uma classe seja um exagero nesse contexto (especialmente porque você ainda precisará usarcudaMemcpy, a classe apenas encapsula RAII), portanto a outra abordagem seriaposicionamentonew:

float* device_data = new (cudaDevice) float[SIZE];
// Use `device_data` …
operator delete [](device_data, cudaDevice);

Aqui,cudaDevice&nbsp;apenas atua como uma tag para acionar a sobrecarga. No entanto, como no posicionamento normalnew&nbsp;isso indicaria o posicionamento, acho a sintaxe estranhamente consistente e talvez até preferível a usar uma classe.

Eu apreciaria críticas de todo tipo. Alguém talvez saiba se algo nessa direção está planejado para a próxima versão do CUDA (que, como ouvi dizer, melhorará o suporte a C ++, seja lá o que eles querem dizer com isso).

Então, minha pergunta é na verdade tripla:

É a minha veiculaçãonew&nbsp;sobrecarga semanticamente correta? Isso vaza memória?Alguém tem informações sobre futuros desenvolvimentos CUDA que seguem nessa direção geral (vamos ser sinceros: interfaces C em C ++ s * ck)?Como posso levar isso adiante de maneira consistente (existem outras APIs a serem consideradas, por exemplo, não apenas a memória do dispositivo, mas também um armazenamento de memória constante e memória de textura)?
// Singleton tag for CUDA device memory placement.
struct CudaDevice {
    static CudaDevice const& get() { return instance; }
private:
    static CudaDevice const instance;
    CudaDevice() { }
    CudaDevice(CudaDevice const&);
    CudaDevice& operator =(CudaDevice const&);
} const& cudaDevice = CudaDevice::get();

CudaDevice const CudaDevice::instance;

inline void* operator new [](std::size_t nbytes, CudaDevice const&) {
    void* ret;
    cudaMalloc(&ret, nbytes);
    return ret;
}

inline void operator delete [](void* p, CudaDevice const&) throw() {
    cudaFree(p);
}

template <typename T>
class CudaArray {
public:
    explicit
    CudaArray(std::size_t size) : size(size), data(new (cudaDevice) T[size]) { }

    operator T* () { return data; }

    ~CudaArray() {
        operator delete [](data, cudaDevice);
    }

private:
    std::size_t const size;
    T* const data;

    CudaArray(CudaArray const&);
    CudaArray& operator =(CudaArray const&);
};

Sobre o singleton empregado aqui: Sim, estou ciente de suas desvantagens. No entanto, estes não são relevantes neste contexto. Tudo o que eu precisava aqui era de uma pequena marca de tipo que não fosse copiável. Todo o resto (ou seja, considerações sobre multithreading, hora da inicialização) não se aplica.