/* * Sobel Edge Detection demonstration * Copyright (C) 2000-2001 * Ludovic Courtès, Chen Cjianxun, Tarek El-Ghazawi * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * $Source: bitbucket.org:berkeleylab/upc-runtime.git/upc-tests/benchmarks/gwu_bench/sobel/sobel.c $ */ #include #include #include #include #include #include #ifdef DEBUG_H # include DEBUG_H #else //# error "CONFIGDIR undefined." #define debug_init() #define debug_step ((void)0) #define debug(x) x #endif /* The UPC compiler for the SGI Origin based upon GCC 2.95.2 does not support * blocking factors. Therefore, arrays have to be declared with a blocking * factor equal to one (hence the need for index computation macros). The * BLOCK_BUG flag has to be set when using this compiler. * * The DYNAMIC flag should be defined at compilation time to use the dynamic * array allocation. In this case, the image size (IMGSIZE) doesn't need to be * defined at compilation time. Otherwise, IMGSIZE should always be a power * of 2. */ #if (!defined DYNAMIC) && (!defined IMGSIZE) # error "You must define IMGSIZE to set the number of bytes per row (must be a power of 2)." #endif /* ITERATION_NUM: number of iterations of the Sobel Edge Detections. Running * the algorithm several times allows to get a more accurate execution time. */ #define ITERATION_NUM 15.0 #define BYTET unsigned char /* struct RowOfBytes is a way to avoid compilation errors with compilers * not supporting too high blocking factors. */ #define BLOCK (IMGSIZE/THREADS) /* Block size */ typedef struct { #ifndef DYNAMIC BYTET r[IMGSIZE]; #else shared[] BYTET *r; #endif } RowOfBytes; #if (!defined BLOCK_BUG) && (!defined DYNAMIC) shared[IMGSIZE/THREADS] RowOfBytes orig[IMGSIZE], edge[IMGSIZE]; /* Next and previous rows index */ #define NEXT_ROW(i) ((i)+1) #define PREV_ROW(i) ((i)-1) #define FIRST_ROW(i) (!((i)%BLOCK)) #define LAST_ROW(i) (FIRST_ROW((i)+1)) #else /* BLOCK_BUG or DYNAMIC */ #ifndef DYNAMIC shared RowOfBytes orig[IMGSIZE], edge[IMGSIZE]; #else shared RowOfBytes *orig, *edge; //shared int IMGSIZE; #endif /* Next and previous rows index */ // IMGSIZE==BLOCK*THREADS /* NOTE: NEXT_ROW(IMGSIZE**2) doesn't work (need one more % but it's unused anyway) * PREV_ROW(0) doesn't work either (but unused as well) */ #define NEXT_ROW(i) ((((i)+THREADS)%IMGSIZE)+(((i)+THREADS)/IMGSIZE)) #define PREV_ROW_(i) ((((i)-THREADS)%IMGSIZE)+(((i)-THREADS)/IMGSIZE)) #define PREV_ROW(i) ((i=IMGSIZE) #endif /* The following function will ensure that the layout of the dynamically * allocated data is conforming to the UPC specs. */ void CheckDataLayout(shared RowOfBytes* ptr) { int i, j; size_t err=0; volatile struct RowOfBytes* lp; volatile BYTET* lp_b; for(i=0; iTHREADS) assert(upc_threadof(&ptr[j])==upc_threadof(&ptr[PREV_ROW(j)])); if(!((j+THREADS)/IMGSIZE)) assert(upc_threadof(&ptr[j])==upc_threadof(&ptr[NEXT_ROW(j)])); } } upc_barrier 888; } void GenRandom(shared RowOfBytes* arr) { int i,j; #ifdef DEBUG fprintf(stderr, "GenRandom(): Entering\n"); #endif for (i=0; iTHREADS); #ifdef DEBUG if (!MYTHREAD) fprintf(stderr, "sizeof(RowOfBytes)==%i\n", sizeof(RowOfBytes)); #endif orig = upc_all_alloc(THREADS, BLOCK*sizeof(RowOfBytes)); edge = upc_all_alloc(THREADS, BLOCK*sizeof(RowOfBytes)); if(!MYTHREAD) debug_step; upc_forall(i=0; i