Commit bb96d3ce authored by Luca Tornatore's avatar Luca Tornatore
Browse files

first commit

parent cb0092c8
Loading
Loading
Loading
Loading
+79 −0
Changes for examples/00_mpi_first_steps/000_MPI_template.c: 79 added lines, 0 removed lines.
Original line number Diff line number Diff line

/* ────────────────────────────────────────────────────────────────────────── *
│                                                                            │
│ This file is part of the exercises for the Lectures on                     │
│   "Foundations of High Performance Computing"                              │
│ given at                                                                   │
│   Master in HPC and                                                        │
│   Master in Data Science and Scientific Computing                          │
│ @ SISSA, ICTP and University of Trieste                                    │
│                                                                            │
│ contact: luca.tornatore@inaf.it                                            │
│                                                                            │
│     This 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 3 of the License, or      │
│     (at your option) any later version.                                    │
│     This code 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, see <http://www.gnu.org/licenses/>   │
│                                                                            │
* ────────────────────────────────────────────────────────────────────────── */

#if defined(__STDC__)
#  if (__STDC_VERSION__ >= 199901L)
#     define _XOPEN_SOURCE 700
#  endif
#endif
#include <stdlib.h>     
#include <stdio.h>
#include <omp.h>
#include <mpi.h>

  
int main( int argc, char **argv )
{
  // ····················
  // initialize MPI
  {
    int provided;
    MPI_Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided);
    if ( provided < MPI_THREAD_FUNNELED )
      {
	// manage with some meaningful message
	// free every memory block that you may
	// already allocated
	MPI_Abort(MPI_COMM_WORLD, 1);
      }
  }

  // ····················
  // Best practice: don't use the
  // default MPI_COMM_WORLD,
  // use your own world
    
  int Myrank, Ntasks;
  MPI_Comm myCOMM_WORLD;

  MPI_Comm_dup ( MPI_COMM_WORLD, &myCOMM_WORLD );

  // get infos on your world
  MPI_Comm_size( myCOMM_WORLD, &Ntasks );    
  MPI_Comm_rank( myCOMM_WORLD, &Myrank );     


  // ·····················
  /*
   * your code
   */

  // ····················
  // always finalize MPI

  MPI_Finalize();
  return 0;
}
+168 −0
Changes for examples/00_mpi_first_steps/000_where_I_am.c: 168 added lines, 0 removed lines.
Original line number Diff line number Diff line

/* ────────────────────────────────────────────────────────────────────────── *
│                                                                            │
│ This file is part of the exercises for the Lectures on                     │
│   "Foundations of High Performance Computing"                              │
│ given at                                                                   │
│   Master in HPC and                                                        │
│   Master in Data Science and Scientific Computing                          │
│ @ SISSA, ICTP and University of Trieste                                    │
│                                                                            │
│ contact: luca.tornatore@inaf.it                                            │
│                                                                            │
│     This 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 3 of the License, or      │
│     (at your option) any later version.                                    │
│     This code 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, see <http://www.gnu.org/licenses/>   │
│                                                                            │
* ────────────────────────────────────────────────────────────────────────── */


#if defined(__STDC__)
#  if (__STDC_VERSION__ >= 199901L)
#     define _XOPEN_SOURCE 700
#  endif
#endif
#define _GNU_SOURCE
#include <stdlib.h>     
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#if defined(_GNU_SOURCE)
#include <sched.h>
#endif
#include <omp.h>
#include <mpi.h>


int read_proc__self_stat ( int, int * );
int get_cpu_id           ( void       );


int main( int argc, char **argv )
{

  int provided;
  MPI_Init_thread(&argc, &argv, MPI_THREAD_FUNNELED, &provided);
  if ( provided < MPI_THREAD_FUNNELED )
    {
      // manage
      MPI_Abort(MPI_COMM_WORLD, 1);
    }

  int Myrank, Ntasks;
  MPI_Comm myCOMM_WORLD;

  MPI_Comm_dup ( MPI_COMM_WORLD, &myCOMM_WORLD );
  MPI_Comm_size( myCOMM_WORLD, &Ntasks );    
  MPI_Comm_rank( myCOMM_WORLD, &Myrank );     

  int hostname_len;
  char myhostname[MPI_MAX_PROCESSOR_NAME];
  MPI_Get_processor_name(myhostname, &hostname_len);

 
 #pragma omp parallel
  {
   #if defined (_OPENMP) 
    int me = omp_get_thread_num();
   #else
    int me = 0;
   #endif
    int mycpu = get_cpu_id();
    
    printf("T %03d th %03d cpu %03d on host %s\n", Myrank, me, mycpu, myhostname);
  }

  MPI_Finalize();
  return 0;
}



#define CPU_ID_ENTRY_IN_PROCSTAT 39


int get_cpu_id( void )
{
 #if defined(_GNU_SOURCE)                              // GNU SOURCE ------------
  
  return  sched_getcpu( );

 #else

 #ifdef SYS_getcpu                                     //     direct sys call ---
  
  int cpuid;
  if ( syscall( SYS_getcpu, &cpuid, NULL, NULL ) == -1 )
    return -1;
  else
    return cpuid;
  
 #else      

  unsigned val;
  if ( read_proc__self_stat( CPU_ID_ENTRY_IN_PROCSTAT, &val ) == -1 )
    return -1;

  return (int)val;

 #endif                                                // -----------------------
 #endif

}



int read_proc__self_stat( int field, int *ret_val )
/*
  Other interesting fields:

  pid      : 0
  father   : 1
  utime    : 13
  cutime   : 14
  nthreads : 18
  rss      : 22
  cpuid    : 39

  read man /proc page for fully detailed infos
 */
{
  // not used, just mnemonic
  // char *table[ 52 ] = { [0]="pid", [1]="father", [13]="utime", [14]="cutime", [18]="nthreads", [22]="rss", [38]="cpuid"};

  *ret_val = 0;

  FILE *file = fopen( "/proc/self/stat", "r" );
  if (file == NULL )
    return -1;

  char   *line = NULL;
  int     ret;
  size_t  len;
  ret = getline( &line, &len, file );
  fclose(file);

  if( ret == -1 )
    return -1;

  char *savetoken = line;
  char *token = strtok_r( line, " ", &savetoken);
  --field;
  do { token = strtok_r( NULL, " ", &savetoken); field--; } while( field );

  *ret_val = atoi(token);

  free(line);

  return 0;
}
+65 −0
Changes for examples/00_mpi_first_steps/00_basic.c: 65 added lines, 0 removed lines.
Original line number Diff line number Diff line

/* ────────────────────────────────────────────────────────────────────────── *
│                                                                            │
│ This file is part of the exercises for the Lectures on                     │
│   "Foundations of High Performance Computing"                              │
│ given at                                                                   │
│   Master in HPC and                                                        │
│   Master in Data Science and Scientific Computing                          │
│ @ SISSA, ICTP and University of Trieste                                    │
│                                                                            │
│ contact: luca.tornatore@inaf.it                                            │
│                                                                            │
│     This 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 3 of the License, or      │
│     (at your option) any later version.                                    │
│     This code 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, see <http://www.gnu.org/licenses/>   │
│                                                                            │
* ────────────────────────────────────────────────────────────────────────── */

#include <stdlib.h>
#include <stdio.h>

#include <mpi.h>


int main ( int argc, char **argv )
{

  int Rank;
  int Ntasks;
  {
    int provided;
    MPI_Init_thread(&argc, &argv, MPI_THREAD_SINGLE, &provided);
    if ( provided < MPI_THREAD_SINGLE )
      {
	// manage
	MPI_Abort(MPI_COMM_WORLD, 1);
      }
  }
  
  MPI_Comm_rank( MPI_COMM_WORLD, &Rank );
  MPI_Comm_size( MPI_COMM_WORLD, &Ntasks );

  int planets;
  int myplanets;
  
  planets = (argc > 1? atoi(*(argv+1)) : 0 );

  myplanets  = planets / Ntasks;
  myplanets += (Rank < planets % Ntasks);
  
  printf( "Hello world, I'm task %d among %d friends, i'll model %d planets\n",
	  Rank, Ntasks, myplanets );

  MPI_Finalize();

  return 0;
}
+71 −0
Changes for examples/00_mpi_first_steps/00_helloworld.c: 71 added lines, 0 removed lines.
Original line number Diff line number Diff line

/* ────────────────────────────────────────────────────────────────────────── *
│                                                                            │
│ This file is part of the exercises for the Lectures on                     │
│   "Foundations of High Performance Computing"                              │
│ given at                                                                   │
│   Master in HPC and                                                        │
│   Master in Data Science and Scientific Computing                          │
│ @ SISSA, ICTP and University of Trieste                                    │
│                                                                            │
│ contact: luca.tornatore@inaf.it                                            │
│                                                                            │
│     This 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 3 of the License, or      │
│     (at your option) any later version.                                    │
│     This code 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, see <http://www.gnu.org/licenses/>   │
│                                                                            │
* ────────────────────────────────────────────────────────────────────────── */

/*
 * Hello World example with MPI
 */

#include <stdlib.h>
#include <stdio.h>
#include <mpi.h>

int main ( int argc, char **argv )
{
  // ·················
  // intialize MPI
  int provided_thread_level;
  MPI_Comm myCOMM_WORLD;
  MPI_Init_thread( &argc, &argv, MPI_THREAD_SINGLE, &provided_thread_level );
  
  if ( provided_thread_level < MPI_THREAD_SINGLE )
    {
      printf("it was impossibile to get the thread level MPI_THREAD_SINGLE\n");
      MPI_Abort(MPI_COMM_WORLD, 1);
    }
  
  // ··················
  // Good practice: don't use
  // MPI_COMM_WORLD
  // Create a separate working space
  
   int Ntasks;
   int Myrank;
   MPI_Comm_dup( MPI_COMM_WORLD, &myCOMM_WORLD );
   MPI_Comm_size( myCOMM_WORLD, &Ntasks );
   MPI_Comm_rank( myCOMM_WORLD, &Myrank );

   // ·················
   // Greetings
   printf("hello MPI world, I'm rank %d out of %d\n", Myrank, Ntasks );

   // ·················
   // Finalize MPI
   
   MPI_Finalize();
   
   return 0;
}
+105 −0
Changes for examples/01_mpi_send_receive/.backups/01_send_and_recv.c~: 105 added lines, 0 removed lines.
Original line number Diff line number Diff line

/*
 * Simple demonstration of Send and Recv
 * ··········································
 *
 * Even Ranks send a message to subsequent odd ranks,
 * and receive a reply
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <mpi.h>


int main ( int argc, char **argv )
{

  // ············································
  // initialize MPI
  int Rank;
  int Ntasks;
  {
    int provided;
    MPI_Init_thread(&argc, &argv, MPI_THREAD_SINGLE, &provided);
    if ( provided < MPI_THREAD_SINGLE )
      {
	// manage
	MPI_Abort(MPI_COMM_WORLD, 1);
      }
  }

  MPI_Comm_rank( MPI_COMM_WORLD, &Rank );
  MPI_Comm_size( MPI_COMM_WORLD, &Ntasks );

  // ············································
  // print the hostname for every rank
  char hostname[100];
  int hostname_size = 100;
  gethostname( &hostname[0], hostname_size );

  printf( "Rank %d is running on host %s\n", Rank, hostname );

  MPI_Barrier(MPI_COMM_WORLD);

  // ············································
  // determines who's my buddy
  
  int Im_even = (Rank % 2 == 0);
  int my_buddy;
  if ( Im_even )
    my_buddy = Rank+1;
  else
    my_buddy = Rank-1;


  // ············································
  // if I do have a buddy..
  if ( my_buddy < Ntasks )
    {

      #define FIRST_ROUND 0
      #define SECOND_ROUND 1
      
      if ( Im_even )
	{
	  int        buddy_rank;
	  MPI_Status status;

	  MPI_Send( &Rank, 1, MPI_INT, my_buddy, FIRST_ROUND, MPI_COMM_WORLD );
	  MPI_Recv( &buddy_rank, 1, MPI_INT, my_buddy, SECOND_ROUND, MPI_COMM_WORLD, &status );
	  

	  if ( status.MPI_SOURCE == my_buddy )
	    printf("\tRank %d says: I confirm I have received a reply from my buddy\n", Rank);
	  else
	    printf("oops, a stranger has replied to me\n");	  
	}
      else
	{
	  int        buddy_rank;
	  MPI_Status status;

	  MPI_Recv( &buddy_rank, 1, MPI_INT, my_buddy, FIRST_ROUND, MPI_COMM_WORLD, &status );
	  MPI_Send( &Rank, 1, MPI_INT, my_buddy, SECOND_ROUND, MPI_COMM_WORLD );
	  

	  if ( status.MPI_SOURCE == my_buddy )
	    printf("Rank %d says: I confirm I have received the message from my buddy\n", Rank);
	  else
	    printf("oops, a stranger has communicated with me\n");	  
	}
      
    }
  else
    // ·······················
    // sadness
    printf("Rank %d has got nobody to talk with\n", Rank );
    

  MPI_Finalize();

  return 0;
}
Loading