How optimized this code using only pragma directive?

General OpenMP discussion

Re: How optimized this code using only pragma directive?

Postby alessandro » Mon Jun 17, 2013 10:27 am

The tricks was using:
#pragma omp parallel for private(r,g,b,gr1)

Thanks for the precious help. :D
alessandro
 
Posts: 26
Joined: Tue Jun 11, 2013 2:14 am

Re: How optimized this code using only pragma directive?

Postby ftinetti » Mon Jun 17, 2013 11:09 am

The tricks was using:
#pragma omp parallel for private(r,g,b,gr1)


And gr2?

Fernando.
ftinetti
 
Posts: 567
Joined: Wed Feb 10, 2010 2:44 pm

Re: How optimized this code using only pragma directive?

Postby alessandro » Mon Jun 17, 2013 1:15 pm

In the end, I removed some code because the formula is different, but the code is identical, and these for me are experiments to understand the workflow of an OpenMP applications.
Naturally if is was different I would have left it and added even gr2, etc.
alessandro
 
Posts: 26
Joined: Tue Jun 11, 2013 2:14 am

Re: How optimized this code using only pragma directive?

Postby alessandro » Mon Jun 17, 2013 10:44 pm

Here the actual mess of the code that i made that contain on the comment part different attempt and an attempt of debugging.
Code: Select all
#include "CImg.h"
#include  <iostream>
#include <time.h>
#ifdef _OPENMP
   #include <omp.h>
#endif /* _OPENMP */
using namespace cimg_library;
using namespace std;

int main() {

   //Construct image from reading an image file.
   CImg<unsigned char> src("img.jpg");

   int width = src.width();
   int height = src.height();
   int depth = src.depth();
   //New grayscale images.
   CImg<unsigned char> gray1(width,height,depth,1);
   

   unsigned char r,g,b;
   unsigned char gr1 = 0;
   
       clock_t clock_timer;
       double wall_timer;
        clock_timer = clock();
        #ifdef _OPENMP
           wall_timer = omp_get_wtime();
        #endif /* _OPENMP */
   /* Convert RGB image to grayscale image */
   //int num_threads=2;
   //#pragma omp parallel for num_threads(num_threads) private(r,g,b,gr1)
   #pragma omp parallel for private(r,g,b,gr1)
   for(int i=0;i<width;i++){
      for(int j=0;j<height;j++){
         /* L'ordine di i e j è casuale ma si mantiene all'interno del ciclo.
         Quindi se ad es. abbiamo i=24 ed j=9 si mantiene finché non cambia j,
         poi può essere j=10 oppure no, ma i rimane 24.
         In seguito, quanto cambia i, può saltare 25 e scrivere un'altro numero.
         */
           /*
           std::cout << "Red (i,j):" << (src(i,j,0,0)) << "(" << i << "," << j << ")" <<"\n";
           std::cout << "Green (i,j):" << src(i,j,0,1) << "(" << i << "," << j << ")"  <<"\n";
           std::cout << "Blue (i,j):" << src(i,j,0,2) << "(" << i << "," << j << ")"  <<"\n";
           */
          
         //Return a pointer to a located pixel value.
         r = src(i,j,0,0); // First channel RED
         g = src(i,j,0,1); // Second channel GREEN
         b = src(i,j,0,2); // Third channel BLUE
         //std::cout << "RGB (i,j):" << r << g << b << " (" << i << "," << j << ")" << "\n";

         //PAL and NTSC
         //Y = 0.299*R + 0.587*G + 0.114*B
         gr1 = round(0.299*((double)r) + 0.587*((double)g) + 0.114*((double)b));
         //std::cout << "gr1:" << gr1 <<"\n";

         gray1(i,j,0,0) = gr1;
         /*
         if ((i>=450 && i<=450) && (j>=1 && j<=50))
         std::cout << "gray1 (i,j,0,0) " << "(" <<i <<","<<j<< ")" << " gr1 :" << gr1 << "\n";
         */
      }    
   }
   std::cout << " time on clock(): " << (double) (clock() - clock_timer) / CLOCKS_PER_SEC;
   #ifdef _OPENMP   
      std::cout << " time on wall: " <<  omp_get_wtime() - wall_timer << "\n";
   #endif /* _OPENMP */          
   //save the new grayscale images
   gray1.save("gray1.jpg");
   //show all images
   (src,gray1).display("RGB to Grayscale");

   return 0;
}


For see the performance of the applications I used the system:
Listing 8. Understanding omp_get_wtime
Later I will post some minor change on the code. :)

ftinetti wrote:c) I've not used GDB

Exist some other way for debug the code on Linux?
Or do you use a different OS?

Now the only other system that i use is the older "print" method... :lol:
Foolproof but don't always real pratical put aside small and easy esample ... :?

Note:
After the review of the code i noticed the lack of the initialization:
Code: Select all
clock_timer = clock();
#ifdef _OPENMP
           wall_timer = omp_get_wtime();
#endif /* _OPENMP */
alessandro
 
Posts: 26
Joined: Tue Jun 11, 2013 2:14 am

Re: How optimized this code using only pragma directive?

Postby alessandro » Mon Jun 17, 2013 11:41 pm

Code: Select all
#include "CImg.h"
#include  <iostream>
#include <time.h>
#include <string>
#include <sstream>
#ifdef _OPENMP
   #include <omp.h>
#endif /* _OPENMP */

template <typename T>
  std::string NumberToString ( T Number )
  {
     std::ostringstream ss;
     ss << Number;
     return ss.str();
  }
 
  double get_omp_wtime()  {
   double wall_timer=0;
   
      #ifdef _OPENMP
         wall_timer = omp_get_wtime();
      #endif /* _OPENMP */
   
   return wall_timer;
   }
 
void print_omp_clock_timer_elapsed(clock_t previous_clock_timer,clock_t current_clock_timer) 
   {
      /*Attenzione all'ordine di dichiarazione delle funzioni che significa sostanzialmente
       * non tentare di usare funzioni che si trovano più in basso nel codice, dato che la lettura
       * è sequenziale.
       * In caso contrario si presenteranno errori di out of scope.
       * Per dire che l'ordine di dichiarazioni delle funzioni nel codice è importante.
       */

        std::cout << " Time on clock(): " << (double) (current_clock_timer - previous_clock_timer) / CLOCKS_PER_SEC;
   }    
 
void println_omp_clock_timer_elapsed(clock_t previous_clock_timer,clock_t current_clock_timer) 
   {
        print_omp_clock_timer_elapsed(previous_clock_timer,current_clock_timer);
        std::cout << "\n";
   }   
   
void println_omp_clock_wtime_elapsed(clock_t previous_clock_timer,clock_t current_clock_timer,double previous_wall_timer, double current_wall_timer ) 
   {
      /*
       * Attenzione all'ordine di dichiarazione delle funzioni per evitare errori di out of scope.
       */
        print_omp_clock_timer_elapsed(previous_clock_timer,current_clock_timer);
      #ifdef _OPENMP   
         std::cout << " time on wall: " << current_wall_timer - previous_wall_timer << "\n";
      #endif /* _OPENMP */
   }   
   

using namespace cimg_library;
using namespace std;

int main() {

   //Construct image from reading an image file.
   CImg<unsigned char> src("img.jpg");

   int width = src.width();
   int height = src.height();
   int depth = src.depth();
   //New grayscale images.
   CImg<unsigned char> gray1(width,height,depth,1);
   
     unsigned char r,g,b;
   unsigned char gr1 = 0;
   
   clock_t clock_timer,current_clock_timer;
    double wall_timer,current_wall_timer;
   
    clock_timer = clock();
   wall_timer = get_omp_wtime();
   /* Convert RGB image to grayscale image */
   #pragma omp parallel for private(r,g,b,gr1)
   for(int i=0;i<width;i++){
      for(int j=0;j<height;j++){
         /* L'ordine di i e j è casuale ma si mantiene all'interno del ciclo.
         Quindi se ad es. abbiamo i=24 ed j=9 si mantiene finché non cambia j,
         poi può essere j=10 oppure no, ma i rimane 24.
         In seguito, quanto cambia i, può saltare 25 e scrivere un'altro numero.
         */
          
         //Return a pointer to a located pixel value.
         r = src(i,j,0,0); // First channel RED
         g = src(i,j,0,1); // Second channel GREEN
         b = src(i,j,0,2); // Third channel BLUE

         //PAL and NTSC
         //Y = 0.299*R + 0.587*G + 0.114*B
         gr1 = round(0.299*((double)r) + 0.587*((double)g) + 0.114*((double)b));

         gray1(i,j,0,0) = gr1;
      }    
   }
   println_omp_clock_wtime_elapsed(clock_timer,clock(),wall_timer,get_omp_wtime());
   
   //save the new grayscale images
   gray1.save("gray1.jpg");
   //show all images
   (src,gray1).display("RGB to Grayscale");

   return 0;
}

Slowly I'm polish the example adding some utilities. :)
alessandro
 
Posts: 26
Joined: Tue Jun 11, 2013 2:14 am

Re: How optimized this code using only pragma directive?

Postby chabachull » Mon Jun 17, 2013 11:48 pm

Take into account there is no data copy, just data allocation. Data copy is implied by the copyin clause.


Yes, I know. ;)
Sorry I wasn't clear. I just wanted to stress out that with the private clause more memory would be needed which can be problematic. A poor choice of words leads to this misunderstanding.
chabachull
 
Posts: 5
Joined: Mon Jun 17, 2013 3:02 am

Previous

Return to Using OpenMP

Who is online

Users browsing this forum: Google [Bot] and 5 guests