簡體   English   中英

如何推動:: make_transform_iterator取消引用device_ptr?

[英]How to thrust::make_transform_iterator that dereferences a device_ptr?

C ++和CUDA的新功能。 使用MSVS 2015社區和CUDA 9.2。

我嘗試制作一個transform_iterator,它僅取消引用device_ptr。

我收到編譯錯誤:函數“ dereference_device_double_functor :: operator()”無法通過給定的參數列表調用

我還制作了一個使用host_vector和普通雙指針的版本,以確保我的函子用法正確。

    #include <iostream>
    #include "thrust\device_vector.h"
    #include "thrust\host_vector.h"

    struct dereference_device_double_functor
    {
        dereference_device_double_functor() {}

        typedef thrust::device_reference<thrust::device_ptr<double>> argument_type;
        typedef double result_type;

        __host__ __device__
            double operator()(thrust::device_reference<thrust::device_ptr<double>> xDpRef) const {
            thrust::device_ptr<double> xDp = (thrust::device_ptr<double>)xDpRef;
            return *xDp;
        }
    };

    struct dereference_host_double_functor
    {
        dereference_host_double_functor() {}

        typedef double* argument_type;
        typedef double result_type;

        __host__ __device__
            double operator()(double* const& xPtr) const {
            return *xPtr;
        }
    };

    int main()
    {
        // Create double
        thrust::device_vector<double> dv(1, 5);
        thrust::host_vector<double> hv(1, 6);

        // Make sure its there
        std::cout << dv[0] << std::endl;
        std::cout << hv[0] << std::endl;

        // Create pointers to doubles
        thrust::device_vector<thrust::device_ptr<double>> dvPtr(1);
        thrust::device_vector<double*> hvPtr(1);

        // Assign pointers to doubles
        dvPtr[0] = &(dv[0]);
        hvPtr[0] = &(hv[0]);

        // Make sure pointers point correctly
        std::cout << *((thrust::device_ptr<double>)dvPtr[0]) << std::endl;
        std::cout << *(hvPtr[0]) << std::endl;

        // Test functor with iterator
        auto dvi = dvPtr.begin();
        double dvd = dereference_device_double_functor()(*dvi);
        auto hvi = hvPtr.begin();
        double hvd = dereference_host_double_functor()(*hvi);

        // Make sure it worked with iterator
        std::cout << dvd << std::endl;
        std::cout << hvd << std::endl;

        // Make dereferencing transfom iterators
        auto tik = thrust::make_transform_iterator(dvPtr.begin(), dereference_device_double_functor());
        auto tij = thrust::make_transform_iterator(hvPtr.begin(), dereference_host_double_functor());

        // Check that transform iterators work
        //std::cout << *tik << std::endl; // Will cause compile error: function "dereference_device_double_functor::operator()" cannot be called with the given argument list
        std::cout << *tij << std::endl;

        return 0;
    }

感謝你的幫助!

在您的問題中,您聲明以下內容:

我嘗試制作一個transform_iterator,它僅取消引用device_ptr。

但是,這不是我在您的代碼中看到的:

    __host__ __device__
        double operator()(thrust::device_reference<thrust::device_ptr<double>> xDpRef) const {

當我在linux上編譯您的代碼時,我得到以下內容(摘自編譯錯誤提示):

$ nvcc -std=c++11 -o t351 t351.cu
/usr/local/cuda/bin/..//include/thrust/iterator/transform_iterator.h(312): error: function "dereference_device_double_functor::operator()" cannot be called with the given argument list
            argument types are: (thrust::device_ptr<double>)
            object type is: dereference_device_double_functor
...

因此推力為您傳遞了一個thrust::device_ptr<double> 但是您的函子運算符已配置為采用thrust::device_reference<thrust::device_ptr<double>>

當我從中修改您的代碼時:

    __host__ __device__
        double operator()(thrust::device_reference<thrust::device_ptr<double>> xDpRef) const {

對此:

    __host__ __device__
        double operator()(thrust::device_ptr<double> xDpRef) const {

它可以為我編譯並正確運行(在Linux上):

$ cat t351.cu
 #include <iostream>
    #include <thrust/device_vector.h>
    #include <thrust/host_vector.h>

    struct dereference_device_double_functor
    {
        dereference_device_double_functor() {}

        typedef thrust::device_reference<thrust::device_ptr<double>> argument_type;
        typedef double result_type;

        __host__ __device__
            double operator()(thrust::device_ptr<double> xDpRef) const {
            thrust::device_ptr<double> xDp = (thrust::device_ptr<double>)xDpRef;
            return *xDp;
        }
    };

    struct dereference_host_double_functor
    {
        dereference_host_double_functor() {}

        typedef double* argument_type;
        typedef double result_type;

        __host__ __device__
            double operator()(double* const& xPtr) const {
            return *xPtr;
        }
    };

    int main()
    {
        // Create double
        thrust::device_vector<double> dv(1, 5);
        thrust::host_vector<double> hv(1, 6);

        // Make sure its there
        std::cout << dv[0] << std::endl;
        std::cout << hv[0] << std::endl;

        // Create pointers to doubles
        thrust::device_vector<thrust::device_ptr<double>> dvPtr(1);
        thrust::device_vector<double*> hvPtr(1);

        // Assign pointers to doubles
        dvPtr[0] = &(dv[0]);
        hvPtr[0] = &(hv[0]);

        // Make sure pointers point correctly
        std::cout << *((thrust::device_ptr<double>)dvPtr[0]) << std::endl;
        std::cout << *(hvPtr[0]) << std::endl;

        // Test functor with iterator
        auto dvi = dvPtr.begin();
        double dvd = dereference_device_double_functor()(*dvi);
        auto hvi = hvPtr.begin();
        double hvd = dereference_host_double_functor()(*hvi);

        // Make sure it worked with iterator
        std::cout << dvd << std::endl;
        std::cout << hvd << std::endl;

        // Make dereferencing transfom iterators
        auto tik = thrust::make_transform_iterator(dvPtr.begin(), dereference_device_double_functor());
        auto tij = thrust::make_transform_iterator(hvPtr.begin(), dereference_host_double_functor());

        // Check that transform iterators work
        std::cout << *tik << std::endl; // Will cause compile error: function "dereference_device_double_functor::operator()" cannot be called with the given argument list
        std::cout << *tij << std::endl;

        return 0;
    }
$ nvcc -std=c++11 -o t351 t351.cu
$ cuda-memcheck ./t351
========= CUDA-MEMCHECK
5
6
5
6
5
6
5
6
========= ERROR SUMMARY: 0 errors
$

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM