/* * Copyright 1993-2010 NVIDIA Corporation. All rights reserved. * * NVIDIA Corporation and its licensors retain all intellectual property and * proprietary rights in and to this software and related documentation. * Any use, reproduction, disclosure, or distribution of this software * and related documentation without an express license agreement from * NVIDIA Corporation is strictly prohibited. * * Please refer to the applicable NVIDIA end user license agreement (EULA) * associated with this source code for terms and conditions that govern * your use of this NVIDIA software. * */ #include "../common/book.h" #include "../common/cpu_bitmap.h" #define DIM 512 #define BLOCK_DIM 16 struct cuComplex { float r; float i; __device__ cuComplex( float a, float b ) : r(a), i(b) {} __device__ float magnitude2( void ) { return r * r + i * i; } __device__ cuComplex operator*(const cuComplex& a) { return cuComplex(r*a.r - i*a.i, i*a.r + r*a.i); } __device__ cuComplex operator+(const cuComplex& a) { return cuComplex(r+a.r, i+a.i); } }; __device__ int julia( int x, int y ) { const float scale = 1.5; float jx = scale * (float)(DIM/2 - x)/(DIM/2); float jy = scale * (float)(DIM/2 - y)/(DIM/2); cuComplex c(-0.8, 0.156); cuComplex a(jx, jy); int i = 0; for (i=0; i<200; i++) { a = a * a + c; if (a.magnitude2() > 1000) return 0; } return 1; } __global__ void kernel( unsigned char *ptr ) { // map from blockIdx to pixel position int x = blockIdx.x*blockDim.x+threadIdx.x; int y = blockIdx.y*blockDim.y+threadIdx.y; int offset = x + y * DIM; // now calculate the value at that position if(x < DIM && y < DIM) { int juliaValue = julia( x, y ); ptr[offset*4 + 0] = 255 * juliaValue; ptr[offset*4 + 1] = 0; ptr[offset*4 + 2] = 0; ptr[offset*4 + 3] = 255; } } // globals needed by the update routine struct DataBlock { unsigned char *dev_bitmap; }; int main( void ) { DataBlock data; CPUBitmap bitmap( DIM, DIM, &data ); unsigned char *dev_bitmap; HANDLE_ERROR( cudaMalloc( (void**)&dev_bitmap, bitmap.image_size() ) ); data.dev_bitmap = dev_bitmap; dim3 grid((DIM + (BLOCK_DIM-1)) / BLOCK_DIM, (DIM + (BLOCK_DIM-1)) / BLOCK_DIM); dim3 block(BLOCK_DIM, BLOCK_DIM); kernel<<>>( dev_bitmap ); HANDLE_ERROR( cudaMemcpy( bitmap.get_ptr(), dev_bitmap, bitmap.image_size(), cudaMemcpyDeviceToHost ) ); HANDLE_ERROR( cudaFree( dev_bitmap ) ); cudaDeviceReset(); // bitmap.display_and_exit(); }