#ifndef RTS_FIELD_CUH #define RTS_FIELD_CUH #include #include #include #include "../math/rect.h" #include "../cuda/threads.h" #include "../cuda/error.h" #include "../cuda/devices.h" namespace rts{ //multiply R = X * Y template __global__ void gpu_field_multiply(T* R, T* X, T* Y, unsigned int r0, unsigned int r1){ int iu = blockIdx.x * blockDim.x + threadIdx.x; int iv = blockIdx.y * blockDim.y + threadIdx.y; //make sure that the thread indices are in-bounds if(iu >= r0 || iv >= r1) return; //compute the index into the field int i = iv*r0 + iu; //calculate and store the result R[i] = X[i] * Y[i]; } //assign a constant value to all points template __global__ void gpu_field_assign(T* ptr, T val, unsigned int r0, unsigned int r1){ int iu = blockIdx.x * blockDim.x + threadIdx.x; int iv = blockIdx.y * blockDim.y + threadIdx.y; //make sure that the thread indices are in-bounds if(iu >= r0 || iv >= r1) return; //compute the index into the field int i = iv*r0 + iu; //calculate and store the result ptr[i] = val; } template class field{ protected: T* X[D]; //pointer to the field data unsigned int R[2]; //field resolution rts::rect shape; //position and shape of the field slice public: //returns a list of file names given an input string with wild cards std::vector process_filename(std::string name){ std::stringstream ss(name); std::string item; std::vector elems; while(std::getline(ss, item, '.')) //split the string at the '.' character (filename and extension) { elems.push_back(item); } std::string prefix = elems[0]; //prefix contains the filename (with wildcard '?' characters) std::string ext = elems[1]; //file extension (ex. .bmp, .png) ext = std::string(".") + ext; //add a period back into the extension size_t i0 = prefix.find_first_of("?"); //find the positions of the first and last wildcard ('?'') size_t i1 = prefix.find_last_of("?"); std::string postfix = prefix.substr(i1+1); prefix = prefix.substr(0, i0); unsigned int digits = i1 - i0 + 1; //compute the number of wildcards std::vector flist; //create a vector of file names //fill the list for(unsigned int d=0; d>> (X[n], rhs, R[0], R[1]); return *this; } //assignment of vector component field & operator= (const vec rhs){ int maxThreads = rts::maxThreadsPerBlock(); //compute the optimal block size int SQRT_BLOCK = (int)std::sqrt((float)maxThreads); //create one thread for each detector pixel dim3 dimBlock(SQRT_BLOCK, SQRT_BLOCK); dim3 dimGrid((R[0] + SQRT_BLOCK -1)/SQRT_BLOCK, (R[1] + SQRT_BLOCK - 1)/SQRT_BLOCK); //assign the constant value to all positions and dimensions for(unsigned int n=0; n>> (X[n], rhs.v[n], R[0], R[1]); return *this; } //multiply two fields (element-wise multiplication) field operator* (const field & rhs){ int maxThreads = rts::maxThreadsPerBlock(); //compute the optimal block size int SQRT_BLOCK = (int)std::sqrt((float)maxThreads); //create one thread for each detector pixel dim3 dimBlock(SQRT_BLOCK, SQRT_BLOCK); dim3 dimGrid((R[0] + SQRT_BLOCK -1)/SQRT_BLOCK, (R[1] + SQRT_BLOCK - 1)/SQRT_BLOCK); //create a scalar field to store the result field result(R[0], R[1]); for(int n=0; n>> (result.X[n], X[n], rhs.X[n], R[0], R[1]); return result; } T* ptr(unsigned int n = 0){ if(n < D) return X[n]; else return NULL; } //return the vector component at position (u, v) vec get(unsigned int u, unsigned int v){ vec result; for(unsigned int d=0; d