Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Template function to print a Thrust vector

I'm writing a matrix template class that prints to both file and std::cout, i.e.:

matrix<float> myMat;
...
myMat.cout(...)         // print to std::cout
myMat.write("out.txt")  // print to file

Both will share a common underlying printing function which I'm trying to implement as a template too, since I've seen different examples that use thrust::copy to write data to both std::cout and files.

Below is the skeleton of what I've done, but it is currently outputting garbage. Could anyone point to some errors I may have made? For example, am I allowed to pass std::cout around like this?

template <typename data_T> matrix {
    ...

    template <typename out_T> int printTo(out_T &out, ...) {
        data_T *start = ..., *end = ...;
        ...
        thrust::copy(start, end, std::ostream_iterator<data_T>(out, " "));
        ...
    }

    int cout(...) {
        ...
        printTo(std::cout, ...);
        ...
    }

    int write(char* path, ...) {
        ...
        std::ofstream file;
        file.open(path);
        printTo(file, ...);
        ...
    }
}

Edit:

  • Changing to int printTo(std::ostream &out, ...) {...} does not fix the problem.
  • More info: I read data into the matrix from a thrust::device_vector<T>, say dvec, and convert it to a data_T pointer pvec using thrust::raw_pointer_cast(&dvec[0]) (as the CUBLAS library uses raw pointers). I then operate on pvec and then want to print it out.
  • I've tried printing from a pointer of the original thrust::device_vector directly (i.e. *dvec) and it does work: thrust::copy((*dvec).begin(), (*dvec).begin() + n ...). So why can I copy only using *dvec iterators and not the raw pointer cast pvec?
like image 526
mchen Avatar asked Mar 24 '23 02:03

mchen


1 Answers

Don't use raw_pointer_cast here. That will fool Thrust into thinking that you've got a pointer to data on the host, which is why your code isn't giving you what you expect. I would have expected your code to just crash.

To copy a device_vector to an ostream_iterator, just use thrust::copy directly:

thrust::device_vector<float> vec = ...

thrust::copy(vec.begin(), vec.end(), std::ostream_iterator<float>(std::cout, " "));
like image 67
Jared Hoberock Avatar answered Mar 31 '23 18:03

Jared Hoberock