/** * @file PndGpu.cu * @brief Helper and auxiliary functions for GPU stuff * @author Andreas Herten (a.herten@gmail.com) * @author Ludovico Bianchi (l.bianchi@fz-juelich.de) * @date 29 Jul 2015 */ #ifndef __PNDGPU__ #define __PNDGPU__ #include #include #include #include #include namespace PndGpu { // forward declaration namespace fake { struct TVector2; } } #ifdef THERE_IS_ROOT #include "TVector2.h" #else using namespace PndGpu::fake; #endif #define cucheck(call) \ { \ cudaError_t cucheck_err = (call); \ if(cucheck_err != cudaSuccess) { \ const char* err_str = cudaGetErrorString(cucheck_err); \ fprintf(stderr, "Error %s (%d): %s in %s\n", __FILE__, __LINE__, err_str, #call); \ exit(-1); \ } \ } /** * @namespace PndGpu Since all GPU helpers are not in sorted into classes, they are sorted into this namespace */ namespace PndGpu { /** * @namespace io Methods for input and output */ namespace io { void readPoints(std::string filename, std::vector &x, std::vector &y, std::vector &r, int upToLineNumber = 2) { std::ifstream file(filename.c_str()); float tempX, tempY, tempZ, tempR, tempI; char tempChar[10]; int i = 1; while (i <= upToLineNumber && file >> tempX >> tempY >> tempZ >> tempR >> tempI >> tempChar) { x.push_back(tempX); y.push_back(tempY); r.push_back(tempR); i++; } file.close(); } void readPointsEvt(std::string filename, std::vector &x, std::vector &y, std::vector &r, int nEvts = 1) { std::ifstream file(filename.c_str()); float tempX, tempY, tempZ, tempR; int evtId = 0; int tempI = 0; char tempChar[10]; int evtCounter = 0; int lineCounter = 0; while (file >> tempX >> tempY >> tempZ >> tempR >> tempI >> tempChar) { if (tempI != evtId) { evtId = tempI; if (evtCounter >= nEvts) break; evtCounter++; #if VERBOSE >= 2 std::cout << "Found event #: " << evtCounter << " (evtID: " << evtId << ")" << std::endl; #endif } #if VERBOSE >= 2 std::cout << "(x, y, r) = (" << tempX << ", " << tempY << ", " << tempR << ")" << std::endl; #endif x.push_back(tempX); y.push_back(tempY); r.push_back(tempR); lineCounter++; } #if VERBOSE >= 1 std::cout << "Read " << evtCounter << " events, " << lineCounter << " lines" << std::endl; #endif file.close(); } } // io /** * @namespace debug Helpers for printing debug information */ namespace debug { void printArray(float *a, int aLength) { for (int i = 0; i < aLength; i++) { std::cout << a[i] << std::endl; } } void printTwoArraysNextToEachOther(float *a, float *b, int aLengths) { for (int i = 0; i < aLengths; i++) { std::cout << a[i] << ", " << b[i] << std::endl; } } } // debug /** * @namespace fake Methods faking ROOT / C++ data structs */ namespace fake { struct TVector2 { TVector2() {}; TVector2(float _x, float _y) { fX = _x; fY = _y; }; private: float fX; float fY; }; } // fake /** * @namespace conversion Converting between different data types and containers, e.g. std::vector and arrays */ namespace conversion { std::vector twoFloatsToVector(float *a, float *b, int arrayLength, int arrayStart = 0) { std::vector result; for (unsigned int i = arrayStart; i < arrayLength; i++) { TVector2 tempVector(a[i], b[i]); result.push_back(tempVector); } return result; } std::vector > splitArraysAndConvertToTVector(float *array_x, float *array_y, int nHits, int nAngles) { std::vector > tempOuterVector; for (int i = 0; i < nHits; ++i) { std::vector tempInnerVector = PndGpu::conversion::twoFloatsToVector(array_x, array_y, (i + 1) * nAngles, i * nAngles); tempOuterVector.push_back(tempInnerVector); } return tempOuterVector; } std::vector > arrayOfHitsToVectorOfHits(float *array, int nHits, int nAngles) { std::vector > tempOuterVector; for (int i = 0; i < nHits; ++i) { std::vector tempInnerVector(array + i * nAngles, array + (i + 1) * nAngles); tempOuterVector.push_back(tempInnerVector); } return tempOuterVector; } template float *vectorToArray(T &vec, int *arrayLength) { *arrayLength = vec.size(); return & vec[0]; } } // conversion } // PndGpu #endif