smoothing algorithm


/ Published in: C
Save to your folder(s)

OpenSHMEM parallel programming implementation for the Smoothing Algorithm


Copy this code and paste it in your HTML
  1. /*
  2.  *
  3.  * Copyright (c) 2011 - 2013
  4.  * University of Houston System and Oak Ridge National Laboratory.
  5.  *
  6.  * All rights reserved.
  7.  *
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  *
  12.  * o Redistributions of source code must retain the above copyright notice,
  13.  * this list of conditions and the following disclaimer.
  14.  *
  15.  * o Redistributions in binary form must reproduce the above copyright
  16.  * notice, this list of conditions and the following disclaimer in the
  17.  * documentation and/or other materials provided with the distribution.
  18.  *
  19.  * o Neither the name of the University of Houston System, Oak Ridge
  20.  * National Laboratory nor the names of its contributors may be used to
  21.  * endorse or promote products derived from this software without specific
  22.  * prior written permission.
  23.  *
  24.  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  25.  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  26.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  27.  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  28.  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  29.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
  30.  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  31.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  32.  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  33.  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  34.  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  35.  *
  36.  */
  37.  
  38.  
  39.  
  40. /*
  41.  * get on PE 0 (master) from PE 1, but with a non-symmetric variable
  42.  */
  43.  
  44. /*
  45.  *Smoothing Algorithm Implementation in OpenSHMEM
  46.  */
  47.  
  48. /*
  49.  *OpenSHMEM is an effort to create a specification for a standardized API for parallel programming in the
  50.   Partitioned Global Address Space. Along with the specification the project is also creating a reference
  51.   implementation of the API. This implementation attempts to be portable, to allow it to be deployed in
  52.   multiple environments, and to be a starting point for implementations targeted to particular hardware
  53.   platforms.*/
  54.  
  55. #include <stdlib.h>
  56. #include <stdio.h>
  57. #include <string.h>
  58. #include <math.h>
  59. #include <shmem.h>
  60. #include <time.h>
  61.  
  62. /* some constants */
  63. #define FILTERHEIGHT 5
  64. #define FILTERWIDTH 5
  65. #define SEGMENTS 5
  66. #define ITERATIONS 10
  67.  
  68. /* some prototupes */
  69. void allocate_2D_int_matrix (int ***matrix, int dim0, int dim1);
  70. void free_2D_int_matrix (int ***matrix);
  71. void gray_erode(int **img, int height, int width, int filterheight, int filterwidth, int iterations, int pixrange, int localheight, int heightoffset );
  72. void update_ghostcells ( int **buffer, int height, int width, int fhlimit, int localheight, int heightoffset );
  73.  
  74. /* shmem init variables */
  75. int rank, size;
  76.  
  77. /* variables for calculating the time */
  78. double wtime, wtime1, wtime2;
  79. struct timeval start, end;
  80. double t;
  81.  
  82. /* main function */
  83. int main(int argc, char **argv)
  84. {
  85. int localheight=0;
  86. int realheight=0;
  87. int height, width,i, j, k, heightoffset;
  88. int **labels=NULL;
  89. FILE *fpa;
  90.  
  91. /* initializing shmem values */
  92. start_pes (0);
  93. size = _num_pes ();
  94. rank = _my_pe ();
  95.  
  96. /* determining inputs */
  97. if (argc != 5 ) {
  98. printf("usage: %s <inputfile> <outputfile> <height> <width>\n", argv[0]);
  99. exit(0);
  100. }
  101. height = atoi ( argv[3]);
  102. width = atoi ( argv[4]);
  103.  
  104. /* creating symmetric memory */
  105. labels = (int **) shmalloc (height*sizeof(int *));
  106. for ( i = 0; i < height; i++ )
  107. { labels[i] = (int*) shmalloc (width*sizeof(int*)); }
  108.  
  109. allocate_2D_int_matrix ( &labels, height, width );
  110.  
  111. /* reading from the input file */
  112. if ( rank == 0 )
  113. {
  114. fpa = fopen ( argv[1], "rb");
  115. fread ( &(labels[0][0]), sizeof(int), height*width, fpa);
  116. fclose ( fpa );
  117. }
  118.  
  119. /* datapartitioning between the processes */
  120. localheight = height/size;
  121. realheight = localheight + 4 ;
  122. heightoffset = 2;
  123. if ( rank == 0 ) {
  124. realheight -= 2 ;
  125. heightoffset = 0;
  126. }
  127. if ( rank == (size -1) ) {
  128. realheight -= 2;
  129. }
  130.  
  131. shmem_barrier_all ();
  132. /* distributing input datum to all the symmetric variables */
  133. for ( i=1; i<size; i++ ) {
  134. if ( rank == i )
  135. if ( shmem_addr_accessible(&labels[0][0], 0)) {
  136. if ( rank == ( size -1 ) ) { k = 0; } else { k = 2; }
  137. for ( j = 0; j < localheight+k; j++ ) {
  138. shmem_int_get(&labels[j+heightoffset][0], &labels[j+(localheight*rank)][0], width, 0);
  139. }
  140. }
  141. else { printf("Not_accessible_Error_00"); }
  142. }
  143.  
  144. /* gray erode calculation */
  145. shmem_barrier_all();
  146. gettimeofday(&start, NULL);
  147. gray_erode(labels, height, width, FILTERHEIGHT,FILTERWIDTH, ITERATIONS, SEGMENTS, localheight, heightoffset );
  148. gettimeofday(&end, NULL);
  149.  
  150. /* calculating and displaying time taken */
  151. if( rank == 0 )
  152. {
  153. t = (double) ((end.tv_sec * 1000000 + end.tv_usec) - (start.tv_sec * 1000000 + start.tv_usec)) / 1000000.0;
  154. printf("Total Time%f \n",t);
  155. }
  156.  
  157. /* transferring datum back to root */
  158. shmem_barrier_all ();
  159. for ( k = 0; k < size; k++){
  160. if ( rank == k ) {
  161. for ( i = 0; i < localheight; i++ ) {
  162. shmem_int_put(&labels[i+(localheight*rank)][0], &labels[i+heightoffset][0], width, 0);
  163. }
  164. }
  165. }
  166.  
  167. shmem_barrier_all ();
  168. /* creating output file */
  169. if(rank == 0) {
  170. fpa = fopen ( argv[2], "wb");
  171. fwrite( &(labels[0][0]), sizeof(int), height*width, fpa );
  172. fclose( fpa );
  173. }
  174.  
  175. free_2D_int_matrix ( &labels);
  176. return 0;
  177. }
  178. /**********************************************************************/
  179. /**********************************************************************/
  180. /**********************************************************************/
  181. void gray_erode(int **img, int height /*realheight*/, int width, int filterheight,
  182. int filterwidth, int iterations, int pixrange, int localheight, int heightoffset )
  183. {
  184. int maxlabel=0;
  185. int fh, fw, iters, pixval=0, i, j, s;
  186. int fhlimit = filterheight/2;
  187. int fwlimit = filterwidth/2;
  188. int **smoothedlabels;
  189. int* labeltemp;
  190. int realheight;
  191.  
  192. allocate_2D_int_matrix ( &smoothedlabels, height, width );
  193.  
  194. realheight = localheight + 4 ;
  195. if ( rank == 0 ) {
  196. realheight -= 2 ;
  197. }
  198. if ( rank == (size -1) ) {
  199. realheight -= 2;
  200. }
  201.  
  202. height = realheight;
  203.  
  204. for (i=heightoffset; i<heightoffset+localheight; i++)
  205. for (j=0; j<width; j++)
  206. smoothedlabels[i][j] = img[i][j];
  207.  
  208. labeltemp = (int*)malloc(sizeof(int) * pixrange);
  209. for (s=0; s<pixrange; s++)
  210. labeltemp[s] = 0;
  211.  
  212.  
  213. for (iters=0; iters<iterations; iters++) {
  214. /* update ghost cells first */
  215. update_ghostcells ( img, height, width, fhlimit, localheight, heightoffset );
  216. shmem_barrier_all();
  217. for (i=fhlimit; i<height-fhlimit; i++) {
  218. for (j=fwlimit; j<width-fwlimit; j++) {
  219.  
  220. for (fh=-fhlimit; fh<=fhlimit; fh++) {
  221. for (fw=-fwlimit; fw<=fwlimit; fw++) {
  222. labeltemp[img[i+fh][j+fw]]++;
  223. }
  224. }
  225. for (s=0; s<pixrange; s++) {
  226. if (labeltemp[s]>maxlabel) {
  227. maxlabel = labeltemp[s];
  228. pixval = s;
  229. }
  230. }
  231. smoothedlabels[i][j]=pixval;
  232.  
  233. for (s=0; s<pixrange; s++)
  234. labeltemp[s] = 0;
  235. maxlabel = 0;
  236. }// End of Width Loop
  237. }// End of Height Loop
  238.  
  239. for (i=heightoffset; i<heightoffset + localheight; i++)
  240. for (j=0; j<width; j++)
  241. img[i][j] = smoothedlabels[i][j];
  242.  
  243. }
  244.  
  245. free_2D_int_matrix ( &smoothedlabels );
  246. free(labeltemp);
  247. return;
  248. }
  249. /**********************************************************************/
  250. /**********************************************************************/
  251. /**********************************************************************/
  252. void allocate_2D_int_matrix (int ***matrix, int dim0, int dim1)
  253. {
  254. int i;
  255. int ** tmp_field0;
  256. int *data;
  257.  
  258. data = (int *) shmalloc(dim0*dim1*sizeof(int));
  259. if (data == NULL ) {
  260. printf("%d @ %s, Could not allocate memory\n", __LINE__,__FILE__);
  261. return;
  262. }
  263.  
  264. tmp_field0 = (int **) shmalloc (dim0*sizeof(int *));
  265. if (tmp_field0 == NULL ) {
  266. printf("%d @ %s, Could not allocate memory\n", __LINE__,__FILE__);
  267. return;
  268. }
  269. for (i=0; i<dim0; i++) {
  270. tmp_field0[i] = &(data[i*dim1]);
  271. }
  272.  
  273. *matrix=tmp_field0;
  274. return;
  275. }
  276. /**********************************************************************/
  277. /**********************************************************************/
  278. /**********************************************************************/
  279. void free_2D_int_matrix (int ***matrix)
  280. {
  281. int *matrix_tmp0;
  282. int **matrix_tmp1;
  283.  
  284. matrix_tmp0=**matrix;
  285. matrix_tmp1=*matrix;
  286.  
  287. shfree(matrix_tmp0);
  288. shfree(matrix_tmp1);
  289.  
  290. *matrix=NULL;
  291. return;
  292. }
  293. /**********************************************************************/
  294. /**********************************************************************/
  295. /**********************************************************************/
  296. void update_ghostcells ( int **buffer, int height, int width, int fhlimit,int localheight, int heightoffset )
  297. {
  298.  
  299. int i, j, k;
  300.  
  301. shmem_barrier_all() ;
  302.  
  303. if ( size < 2 ) {
  304. /* Nothing to be done */
  305. return;
  306. }
  307.  
  308. if ( rank != 0 ) {
  309. if ( shmem_addr_accessible(&buffer[0][0], rank-1)) {
  310. if ( (rank - 1 ) == 0 )
  311. { for ( i = 0; i < 2; i++ ) shmem_int_get ( &(buffer[i][0]), &(buffer[i+(localheight-2)][0]), width, rank-1); }
  312. else {
  313. for ( i = 0; i < 2; i++ ) shmem_int_get ( &(buffer[i][0]), &(buffer[i+(localheight)][0]), width, rank-1); } }
  314. else {
  315. printf("Not_Accessible_Error_01"); }
  316.  
  317. if ( shmem_addr_accessible(&buffer[0][0], rank-1)) {
  318. if ( (rank - 1 ) == 0 )
  319. { for ( i = 0; i < 2; i++ ) shmem_int_put ( &(buffer[i+(localheight)][0]), &(buffer[i+heightoffset][0]), width, rank-1); }
  320. else {
  321. for ( i = 0; i < 2; i++ ) shmem_int_put ( &(buffer[i+(localheight)+2][0]), &(buffer[i+heightoffset][0]), width, rank-1); } }
  322. else {
  323. printf("Not_Accessible_Error_02"); }
  324. }
  325.  
  326. shmem_barrier_all ();
  327. return;
  328. }

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.