Функция шаблона для печати вектора тяги

Я пишу класс шаблона matrix, который печатает как в файл, так и в std::cout, то есть:

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

Оба будут иметь общую базовую функцию печати, которую я также пытаюсь реализовать в качестве шаблона, поскольку я видел разные примеры, использующие thrust::copy для записи данных как в std::cout, так и в файлы.

Ниже приведена схема того, что я сделал, но в настоящее время выводит мусор. Может ли кто-нибудь указать на некоторые ошибки, которые я, возможно, сделал? Например, могу ли я передавать std::cout вот так?

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, ...);
        ...
    }
}

Изменить:

  • Изменение на int printTo(std::ostream &out, ...) {...} не решает проблему.
  • Дополнительная информация: я читаю данные в матрицу из thrust::device_vector<T>, скажем, dvec, и преобразовываю их в указатель data_T pvec с помощью thrust::raw_pointer_cast(&dvec[0]) (поскольку библиотека CUBLAS использует необработанные указатели). Затем я работаю с pvec и хочу его распечатать.
  • Я пробовал печатать из указателя исходного thrust::device_vector напрямую (т.е. *dvec), и это действительно работает: thrust::copy((*dvec).begin(), (*dvec).begin() + n ...). Так почему же я могу копировать только с помощью итераторов *dvec, а не с помощью прямого приведения указателя pvec?

person mchen    schedule 04.05.2013    source источник
comment
Вам не нужно делать printTo шаблонной функцией. Просто пусть первый аргумент будет ссылкой std::ostream.   -  person Some programmer dude    schedule 05.05.2013
comment
@JoachimPileborg, спасибо - я изменил его на int printTo(std::ostream &out, ...) {...}, как и было предложено, но он все еще выводит мусор. Любые другие идеи?   -  person mchen    schedule 05.05.2013
comment
Как вы храните данные? Как вы на самом деле инициализируете start и end?   -  person Some programmer dude    schedule 05.05.2013
comment
Я читаю данные в matrix из thrust::device_vector<T>, скажем, dvec, и преобразовываю их в data_T указатель pvec с помощью thrust::raw_pointer_cast(&dvec[0]) (поскольку библиотека CUBLAS использует необработанные указатели). Затем я работаю с pvec и хочу его распечатать.   -  person mchen    schedule 05.05.2013
comment
Я пробовал печатать из указателя исходного thrust::device_vector напрямую (т. е. *dvec), и это действительно работает: thrust::copy((*dvec).begin(), (*dvec).begin() + n ...). Так почему же я могу копировать только из *dvec, а не из необработанного указателя pvec?   -  person mchen    schedule 05.05.2013
comment
Какие предположения вы делаете об упаковке данных? Например, для необработанного указателя pvec печать первого элемента работает правильно, но каждый элемент после первого является мусором? Другими словами, итерация с использованием необработанного указателя может не учитывать некоторые базовые методы реализации структуры данных, которые компенсирует итерация с использованием фактического итератора.   -  person Jason    schedule 05.05.2013


Ответы (1)


Не используйте здесь raw_pointer_cast. Это заставит Thrust думать, что у вас есть указатель на данные на хосте, поэтому ваш код не дает вам того, что вы ожидаете. Я ожидал, что ваш код просто выйдет из строя.

Чтобы скопировать device_vector в ostream_iterator, просто используйте thrust::copy напрямую:

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

thrust::copy(vec.begin(), vec.end(), std::ostream_iterator<float>(std::cout, " "));
person Jared Hoberock    schedule 05.05.2013
comment
Большое спасибо @JaredHoberock - как я могу сохранить итератор vec.begin()? На самом деле я зацикливаюсь на фрагментах данных, считывающих вектор тяги, поскольку подматрица большей матрицы может не храниться в памяти непрерывно. - person mchen; 05.05.2013
comment
Вы можете использовать thrust::device_vector<float>::iterator i = vec.begin(); или thrust::device_ptr<float> ptr = vec.data();. - person Jared Hoberock; 05.05.2013
comment
Спасибо @JaredHoberock, но что, если я хочу использовать итератор с моим собственным типом шаблона: thrust::device_vector<data_T>::iterator i = ...? Я получаю ошибку компиляции expected a ";", если я меняю с <float> на <data_T>. - person mchen; 05.05.2013