Changeset 163:1aae525e1e79

Show
Ignore:
Timestamp:
03/21/2012 03:26:46 PM (15 months ago)
Author:
Andreas Schaefer <gentryx@…>
Branch:
default
Message:

camera frames are now propated to the GPU code

Location:
src/examples/flowingcanvas
Files:
4 modified

Legend:

Unmodified
Added
Removed
  • src/examples/flowingcanvas/canvascell.h

    r162 r163  
    2121    { 
    2222    public: 
     23        __host__ __device__ 
    2324        Particle(const float& pos0 = 0, const float& pos1 = 0, const float& _lifetime = 1000) : 
    2425            lifetime(_lifetime) 
     
    3031        } 
    3132 
     33        __host__ __device__ 
    3234        void update(const float& deltaT, const float& force0, const float& force1, const float& forceFactor, const float& friction) 
    3335        { 
     
    163165    } 
    164166 
    165     void readCam(unsigned char *frame, const float& factorX, const float& factorY, const int& width, const int& height) 
    166     { 
    167         int posX = pos[0] * factorX; 
    168         int posY = pos[1] * factorY; 
    169          
    170         int index = posY * width * 3 + posX * 3; 
    171         cameraPixel = (0xff << 24) +  
    172             (frame[index + 0] << 16) + 
    173             (frame[index + 1] <<  8) + 
    174             (frame[index + 2] <<  0); 
    175  
    176         int val = (int)frame[index + 0] + (int)frame[index + 1] + (int)frame[index + 2]; 
     167 
     168    __host__ __device__ 
     169    void readCam(const unsigned char& r, const unsigned char& g, const unsigned char& b) 
     170    { 
     171        cameraPixel = (0xff << 24) + (r << 16) + (g <<  8) + (b <<  0); 
     172 
     173        int val = (int)r + (int)g + (int)b; 
    177174        if (val < 500) { 
    178175            cameraLevel = 1.0; 
    179176        } else { 
    180             cameraLevel = std::max(0.0, cameraLevel - 0.05); 
    181         } 
     177            cameraLevel = max(0.0, cameraLevel - 0.05); 
     178        } 
     179    } 
     180 
     181    __host__ __device__ 
     182    float max(const float& a, const float& b) 
     183    { 
     184        return a > b ? a : b; 
    182185    } 
    183186 
  • src/examples/flowingcanvas/interactivesimulatorcpu.h

    r159 r163  
    3333            for (int x = 0; x < dim.x(); ++x) { 
    3434                Coord<2> c(x, y); 
    35                 (*this->curGrid)[c].readCam(&cameraFrame[0], factorX, factorY, cameraFrameWidth, cameraFrameHeight); 
     35                int index = (int)(y * factorY) * cameraFrameWidth + x * factorX; 
     36                unsigned char *pixel = &cameraFrame[3 * index]; 
     37                (*this->curGrid)[c].readCam(pixel[0], pixel[1], pixel[2]); 
    3638            } 
    3739        } 
  • src/examples/flowingcanvas/interactivesimulatorgpu.h

    r162 r163  
    55#include <libgeodecomp/misc/grid.h> 
    66 
     7// fixme: kernels need to be templates. should be included by GPUSimulator 
    78__global__ void updateKernel(CanvasCell *curGrid, CanvasCell *newGrid, unsigned width, unsigned nanoStep) 
    89{ 
     
    3839} 
    3940 
     41 
     42__global__ void updateCam(CanvasCell *grid, unsigned char *cameraBuffer, float factorX, float factorY, unsigned widthGrid, unsigned widthBuffer) 
     43{ 
     44    int x = blockDim.x * blockIdx.x + threadIdx.x; 
     45    int y = blockDim.y * blockIdx.y + threadIdx.y; 
     46    int indexGrid   = (y + 1) * widthGrid + x + 1; 
     47    int indexBuffer = (int)(y * factorY) * widthBuffer + x * factorX; 
     48    unsigned char *pixel = cameraBuffer + indexBuffer * 3; 
     49    
     50    grid[indexGrid].readCam(pixel[0], pixel[1], pixel[2]); 
     51} 
     52 
    4053namespace LibGeoDecomp { 
    4154 
    4255// fixme: this is hardcoded to 2d ATM 
     56// fixme: move to dedicated file 
    4357template<typename CELL_TYPE> 
    4458class GPUSimulator : public MonolithicSimulator<CELL_TYPE> 
     
    5064 
    5165    GPUSimulator(Initializer<CELL_TYPE> *initializer, const int& device = 0) : 
    52         MonolithicSimulator<CELL_TYPE>(initializer) 
     66        MonolithicSimulator<CELL_TYPE>(initializer), 
     67        inputBufferDevice(0), 
     68        inputBufferSize(0) 
    5369    { 
    5470        Coord<DIM> dim = this->initializer->gridDimensions(); 
     
    5874        cudaSetDevice(device); 
    5975        int byteSize = dim.prod() * sizeof(CELL_TYPE); 
    60         cudaMalloc(&transferGrid, byteSize); 
    61         cudaMemcpy(transferGrid, gridHost.baseAddress(), byteSize, cudaMemcpyHostToDevice); 
     76        cudaMalloc(&transferGridDevice, byteSize); 
     77        cudaMemcpy(transferGridDevice, gridHost.baseAddress(), byteSize, cudaMemcpyHostToDevice); 
    6278 
    6379        // pad actual grids to avoid edge cell handling 
     
    7389        dim3 gridDim; 
    7490        genKernelDimensions(&blockDim, &gridDim); 
    75         loadGridFromTransferBuffer<<<gridDim, blockDim>>>(curGridDevice, transferGrid, gridWidth() + 2, gridWidth()); 
     91        loadGridFromTransferBuffer<<<gridDim, blockDim>>>(curGridDevice, transferGridDevice, gridWidth() + 2, gridWidth()); 
     92 
     93        allocInputBuffer(Coord<2>(1, 1)); 
    7694        checkCudaError(); 
    7795    } 
     
    7997    virtual ~GPUSimulator() 
    8098    { 
    81         cudaFree(&curGridDevice); 
    82         cudaFree(&newGridDevice); 
     99        cudaFree(transferGridDevice); 
     100        cudaFree(curGridDevice); 
     101        cudaFree(newGridDevice); 
     102        cudaFree(inputBufferDevice); 
    83103    } 
    84104 
     
    104124        dim3 gridDim; 
    105125        genKernelDimensions(&blockDim, &gridDim); 
    106         storeGridToTransferBuffer<<<gridDim, blockDim>>>(curGridDevice, transferGrid, gridWidth() + 2, gridWidth()); 
     126        storeGridToTransferBuffer<<<gridDim, blockDim>>>(curGridDevice, transferGridDevice, gridWidth() + 2, gridWidth()); 
    107127        int byteSize = gridHost.getDimensions().prod() * sizeof(CELL_TYPE); 
    108         cudaMemcpy(gridHost.baseAddress(), transferGrid, byteSize, cudaMemcpyDeviceToHost); 
     128        cudaMemcpy(gridHost.baseAddress(), transferGridDevice, byteSize, cudaMemcpyDeviceToHost); 
    109129        checkCudaError(); 
    110130        return &gridHost; 
     131    } 
     132 
     133    virtual void updateInputBuffer(unsigned char *data, const Coord<DIM>& inputDim) 
     134    { 
     135        allocInputBuffer(inputDim); 
     136        // fixme: set element size externally 
     137        int byteSize = inputDim.prod() * 3 * sizeof(unsigned char); 
     138        cudaMemcpy(inputBufferDevice, data, byteSize, cudaMemcpyHostToDevice); 
     139   
     140        Coord<2> simGridDim = this->getInitializer()->gridDimensions(); 
     141        float factorX = 1.0 * inputDim.x() / simGridDim.x(); 
     142        float factorY = 1.0 * inputDim.y() / simGridDim.y(); 
     143 
     144        dim3 blockDim; 
     145        dim3 gridDim; 
     146        genKernelDimensions(&blockDim, &gridDim); 
     147        updateCam<<<gridDim, blockDim>>>(curGridDevice, inputBufferDevice, factorX, factorY, gridWidth() + 2, inputDim.x()); 
    111148    } 
    112149 
    113150private: 
    114151    GridType gridHost; 
    115     CELL_TYPE *transferGrid; 
     152    CELL_TYPE *transferGridDevice; 
    116153    CELL_TYPE *curGridDevice; 
    117154    CELL_TYPE *newGridDevice; 
    118  
     155    unsigned char *inputBufferDevice; 
     156    int inputBufferSize; 
     157 
     158    void allocInputBuffer(const Coord<DIM>& dim) 
     159    { 
     160        // fixme: set element size externally 
     161        int byteSize = dim.prod() * 3 * sizeof(unsigned char); 
     162        if (byteSize == inputBufferSize) { 
     163            return; 
     164        } 
     165 
     166        if (inputBufferDevice != 0) { 
     167            cudaFree(inputBufferDevice); 
     168        } 
     169 
     170        cudaMalloc(&inputBufferDevice, byteSize); 
     171        checkCudaError(); 
     172    } 
     173   
    119174    void checkCudaError() 
    120175    { 
     
    159214    typedef Grid<CELL_TYPE, Topology> GridType; 
    160215    typedef std::vector<boost::shared_ptr<Writer<CELL_TYPE> > > WriterVector; 
     216    static const int DIM = Topology::DIMENSIONS; 
    161217 
    162218    InteractiveSimulatorGPU(QObject *parent, Initializer<CELL_TYPE> *initializer) : 
     
    170226    virtual void readCam() 
    171227    { 
    172         std::cout << "fixme InteractiveSimulatorGPU::readCam()\n"; 
     228        Coord<DIM> dim = this->initializer->gridDimensions(); 
     229        this->updateInputBuffer(&cameraFrame[0], Coord<2>(cameraFrameWidth, cameraFrameHeight)); 
    173230    } 
    174231 
     
    182239    virtual void update() 
    183240    { 
    184         // for (int fixme = 0; fixme < 500; ++fixme)  
    185         GPUSimulator<CELL_TYPE>::step(); 
    186         // sleep(1); 
     241        for (int fixme = 0; fixme < 500; ++fixme)  
     242            GPUSimulator<CELL_TYPE>::step(); 
     243        sleep(1); 
    187244    } 
    188245 
  • src/examples/flowingcanvas/main.cu

    r162 r163  
    2727    flow.resize(1200, 900); 
    2828 
    29     // InteractiveSimulatorGPU<CanvasCell> *sim = new InteractiveSimulatorGPU<CanvasCell>( 
    30     InteractiveSimulatorCPU<CanvasCell> *sim = new InteractiveSimulatorCPU<CanvasCell>( 
     29    InteractiveSimulatorGPU<CanvasCell> *sim = new InteractiveSimulatorGPU<CanvasCell>( 
     30    // InteractiveSimulatorCPU<CanvasCell> *sim = new InteractiveSimulatorCPU<CanvasCell>( 
    3131        &flow, 
    3232        new CanvasInitializer());