From 24aab7c9a3fce4b4e78bf210874c7efc0d1e66f8 Mon Sep 17 00:00:00 2001 From: David Mayerich Date: Thu, 31 Jul 2014 16:16:25 -0500 Subject: [PATCH] added field and complexfield classes --- math/complexfield.cuh | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ math/field.cuh | 247 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ math/realfield.cuh | 2 -- math/rect.h | 6 +++--- 4 files changed, 340 insertions(+), 5 deletions(-) create mode 100644 math/complexfield.cuh create mode 100644 math/field.cuh diff --git a/math/complexfield.cuh b/math/complexfield.cuh new file mode 100644 index 0000000..25c1b3e --- /dev/null +++ b/math/complexfield.cuh @@ -0,0 +1,90 @@ +#ifndef RTS_COMPLEXFIELD_H +#define RTS_COMPLEXFIELD_H + +#include "cublas_v2.h" +#include + +#include "../math/field.cuh" +#include "../math/complex.h" + +namespace rts{ + +/*This class stores functions for saving images of complex fields +*/ +template +class complexfield : public field< rts::complex, D >{ + using field< rts::complex, D >::R; + using field< rts::complex, D >::X; + using field< rts::complex, D >::shape; + +public: + + //find the maximum value of component n + rts::complex find_max(unsigned int n){ + cublasStatus_t stat; + cublasHandle_t handle; + + //create a CUBLAS handle + stat = cublasCreate(&handle); + if(stat != CUBLAS_STATUS_SUCCESS){ + std::cout<<"CUBLAS Error: initialization failed"< result; + + if(sizeof(T) == 4) + stat = cublasIcamax(handle, L, (const cuComplex*)X[n], 1, &index); + else + stat = cublasIzamax(handle, L, (const cuDoubleComplex*)X[n], 1, &index); + + index -= 1; //adjust for 1-based indexing + + //if there was a GPU error, terminate + if(stat != CUBLAS_STATUS_SUCCESS){ + std::cout<<"CUBLAS Error: failure finding maximum value."<), cudaMemcpyDeviceToHost)); + return result; + } + +public: + + //constructor (no parameters) + complexfield() : field, D>(){}; + + //constructor (resolution specified) + complexfield(unsigned int r0, unsigned int r1) : field, D>(r0, r1){}; + + //assignment operator (scalar value) + complexfield & operator= (const complex rhs){ + + field< complex, D >::operator=(rhs); + return *this; + } + + //assignment operator (vector value) + complexfield & operator= (const vec< complex, D > rhs){ + + field< complex, D >::operator=(rhs); + return *this; + } + + void toImage(std::string filename, unsigned int n){ + + } + + +}; + + +} //end namespace rts + + +#endif \ No newline at end of file diff --git a/math/field.cuh b/math/field.cuh new file mode 100644 index 0000000..ab60701 --- /dev/null +++ b/math/field.cuh @@ -0,0 +1,247 @@ +#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>> (result.X[n], X[n], rhs.X[n], R[0], R[1]); return result; - - } ///copy constructor diff --git a/math/rect.h b/math/rect.h index ba2c3dd..28f5846 100644 --- a/math/rect.h +++ b/math/rect.h @@ -154,9 +154,9 @@ public: { std::stringstream ss; vec A = C - X * (T)0.5 - Y * (T)0.5; - ss<"<<"C="<"<<"D="<"<<"C="<"<<"D="<