Files
stencilparallelpattern/writer.hpp

77 lines
2.1 KiB
C++
Raw Normal View History

2023-08-24 19:46:27 +02:00
/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
#pragma once
#ifndef WRITER_HPP
#define WRITER_HPP
#include <cstdint>
#include <filesystem>
#include <fstream>
#include <future>
#include <iostream>
#include <string>
#include <ff/ff.hpp>
#include "task.hpp"
using namespace ff;
template <typename T> class Writer : public ff::ff_node_t<Task<T>, void> {
public:
void *svc(Task<T> *);
void operator()(std::vector<std::shared_future<Task<T> *>> *);
};
// svc function for fastflow library
template <typename T> void *Writer<T>::svc(Task<T> *in) {
write_one_image(in);
return this->GO_ON;
}
// operator for std thread
template <typename T>
void Writer<T>::operator()(
std::vector<std::shared_future<Task<T> *>> *ResultsVector) {
if (!ResultsVector) {
std::cerr << "Error: invalid pointer to vector of futures "
"[Writer::operator()]"
<< std::endl;
return;
}
for (auto Result : *ResultsVector) {
Task<T> *t = Result.get();
write_one_image(t);
delete (t);
}
}
// writes out just one image, prepend the output image with "out_"
template <typename T> void write_one_image(Task<T> *t) {
std::string Pre = "out_";
std::filesystem::path Path = t->PathName;
std::string NameNew = Pre + Path.filename().string();
Path.replace_filename(NameNew);
std::fstream File{Path, File.out | File.binary};
if (!File.is_open()) {
std::cerr << "Error: Failed to open " << t->PathName.string() << std::endl;
return;
} else {
File.write(reinterpret_cast<char *>(&t->Rows), sizeof(t->Rows));
File.write(reinterpret_cast<char *>(&t->Cols), sizeof(t->Cols));
// use temporary buffer to not call the write function too frequently
T *buffer = new T[t->Cols];
for (int x = 0; x < t->Rows; ++x) {
for (int y = 0; y < t->Cols; ++y) {
buffer[y] = (*t->VectorData)[x][y];
}
File.write(reinterpret_cast<char *>(buffer), t->Cols * sizeof(T));
}
delete[] buffer;
File.close();
}
}
#endif /* WRITER_HPP */