Index: codes/icosagcm/trunk/src/base/profiling.f90
===================================================================
--- codes/icosagcm/trunk/src/base/profiling.f90	(revision 667)
+++ codes/icosagcm/trunk/src/base/profiling.f90	(revision 667)
@@ -0,0 +1,90 @@
+MODULE profiling_mod
+  IMPLICIT NONE
+  SAVE
+  PRIVATE
+
+  INTEGER, PARAMETER :: max_id=20, max_depth=10
+  INTEGER :: nb_id=-10, depth=-10, current_id(max_depth)
+  CHARACTER(10), DIMENSION(max_id) :: name
+  REAL :: chrono(max_depth), elapsed(max_id)
+
+  PUBLIC :: init_profiling, register_id, enter_profile, exit_profile, print_profile
+
+CONTAINS
+
+  SUBROUTINE init_profiling
+    !$OMP MASTER
+    nb_id=0
+    depth=0
+    elapsed(:)=0
+    !$OMP END MASTER
+  END SUBROUTINE init_profiling
+
+  SUBROUTINE register_id(thename, id)
+    CHARACTER(*), INTENT(IN) :: thename
+    INTEGER, INTENT(OUT) :: id
+    !$OMP MASTER
+    nb_id = nb_id+1
+    id = nb_id
+    name(id)=thename
+    !$OMP END MASTER
+  END SUBROUTINE register_id
+
+  FUNCTION get_elapsed(start)
+    INTEGER(kind=8) :: count, count_rate
+    REAL :: start,get_elapsed
+    CALL SYSTEM_CLOCK(count,count_rate)
+    get_elapsed = (1.*count)/(1.*count_rate) - start
+    IF(get_elapsed<0.) get_elapsed=0.
+  END FUNCTION get_elapsed
+
+  SUBROUTINE enter_profile(id)
+    INTEGER, INTENT(IN) :: id
+    REAL :: my_chrono
+    !$OMP MASTER
+    depth = depth+1
+    chrono(depth) = get_elapsed(0.)
+    current_id(depth) = id
+    !$OMP END MASTER
+  END SUBROUTINE enter_profile
+   
+  SUBROUTINE exit_profile(id)
+    INTEGER, INTENT(IN) :: id
+    INTEGER :: parent_id
+    REAL :: my_elapsed
+    !$OMP MASTER
+    IF(depth<=0) THEN
+       PRINT *, 'exit_profile called at depth=0 !!'
+       STOP
+    END IF
+    IF(id /= current_id(depth)) THEN
+       PRINT *,' exit_profile : at depth ', depth, ' exiting ', TRIM(name(id)), ' after entering ', TRIM(name(current_id(depth)))
+       STOP
+    END IF
+    my_elapsed = get_elapsed(chrono(depth))
+    ! add elapsed to current profile
+    elapsed(id) = elapsed(id) + my_elapsed
+    depth = depth-1
+    ! and substract from parent profile
+    IF(depth>0) THEN
+       parent_id = current_id(depth)
+       elapsed(parent_id) = elapsed(parent_id) - my_elapsed
+    END IF
+    !$OMP END MASTER
+  END SUBROUTINE exit_profile
+
+  SUBROUTINE print_profile
+    INTEGER :: i
+    REAL :: total
+    !$OMP MASTER
+    PRINT *, '---------------------- Profiling -----------------------'
+    total = SUM(elapsed(1:nb_id))
+    PRINT *, 'Total (s) : ', total
+    DO i=1,nb_id
+       PRINT *, name(i), INT(elapsed(i)), INT(1000.*elapsed(i)/total)
+    END DO
+    PRINT *, '---------------------- Profiling -----------------------'
+    !$OMP END MASTER
+  END SUBROUTINE print_profile
+    
+END MODULE profiling_mod
Index: codes/icosagcm/trunk/src/icosa_init.f90
===================================================================
--- codes/icosagcm/trunk/src/icosa_init.f90	(revision 666)
+++ codes/icosagcm/trunk/src/icosa_init.f90	(revision 667)
@@ -21,6 +21,8 @@
   USE etat0_mod
   USE diagflux_mod
+  USE profiling_mod
   IMPLICIT NONE
   
+    CALL init_profiling
     CALL init_mpipara
     CALL trace_off
Index: codes/icosagcm/trunk/src/output/output_field.f90
===================================================================
--- codes/icosagcm/trunk/src/output/output_field.f90	(revision 666)
+++ codes/icosagcm/trunk/src/output/output_field.f90	(revision 667)
@@ -1,9 +1,16 @@
 MODULE output_field_mod
-USE genmod
+  USE genmod
+  USE xios_mod
+  USE profiling_mod
+  IMPLICIT NONE
+  SAVE
   PRIVATE
+
   LOGICAL,SAVE :: xios_output 
 !$OMP THREADPRIVATE(xios_output)     
   LOGICAL,SAVE :: enable_io    
 !$OMP THREADPRIVATE(enable_io)     
+
+  INTEGER :: id_output
 
   PUBLIC enable_io,xios_output,output_field_init,output_field,output_field_finalize
@@ -13,7 +20,7 @@
   SUBROUTINE output_field_init
   USE getin_mod
-  USE xios_mod
-  USE write_field_mod
   IMPLICIT NONE
+
+    CALL register_id('output',id_output)
 
     enable_io=.TRUE.
@@ -30,31 +37,29 @@
       CALL xios_init_write_field
     ENDIF
-
-    
   END SUBROUTINE output_field_init
 
   SUBROUTINE output_field(name_in,field)
     USE field_mod
-    USE xios_mod
     USE write_field_mod
     IMPLICIT NONE  
-     CHARACTER(LEN=*),INTENT(IN) :: name_in
-      TYPE(t_field),POINTER :: field(:)
-
-      IF (xios_output) THEN
-        CALL xios_write_field(name_in,field)
-      ELSE
+    CHARACTER(LEN=*),INTENT(IN) :: name_in
+    TYPE(t_field),POINTER :: field(:)
+    
+    CALL enter_profile(id_output)
+    IF (xios_output) THEN
+       CALL xios_write_field(name_in,field)
+    ELSE
        CALL writeField(name_in,field)
-      ENDIF
+    ENDIF
+    CALL exit_profile(id_output)
 
   END SUBROUTINE output_field
 
   SUBROUTINE output_field_finalize
-  USE ioipsl
-  USE xios_mod
-  IMPLICIT NONE
+    USE ioipsl
+    IMPLICIT NONE
     
     IF (xios_output) THEN
-      CALL xios_write_field_finalize
+       CALL xios_write_field_finalize
     ENDIF
     
Index: codes/icosagcm/trunk/src/parallel/mpipara.F90
===================================================================
--- codes/icosagcm/trunk/src/parallel/mpipara.F90	(revision 666)
+++ codes/icosagcm/trunk/src/parallel/mpipara.F90	(revision 667)
@@ -12,5 +12,6 @@
   INTEGER,SAVE :: mpi_master
   
-  
+  INTEGER,SAVE :: id_mpi ! id for profiling
+
   INTERFACE allocate_mpi_buffer
     MODULE PROCEDURE allocate_mpi_buffer_r2, allocate_mpi_buffer_r3,allocate_mpi_buffer_r4
Index: codes/icosagcm/trunk/src/parallel/transfert_mpi.f90
===================================================================
--- codes/icosagcm/trunk/src/parallel/transfert_mpi.f90	(revision 666)
+++ codes/icosagcm/trunk/src/parallel/transfert_mpi.f90	(revision 667)
@@ -2,4 +2,5 @@
 USE genmod
 USE field_mod
+IMPLICIT NONE
   
   TYPE array
@@ -85,10 +86,9 @@
   END INTERFACE
 
-
-  
 CONTAINS
        
       
   SUBROUTINE init_transfert
+  USE profiling_mod
   USE domain_mod
   USE dimensions
@@ -100,5 +100,7 @@
   INTEGER :: ind,i,j
   LOGICAL ::ok
- 
+
+    CALL register_id('MPI', id_mpi)
+
     CALL create_request(field_t,req_i1)
 
@@ -1094,4 +1096,5 @@
 
   SUBROUTINE send_message_mpi(field,message)
+  USE profiling_mod
   USE field_mod
   USE domain_mod
@@ -1124,4 +1127,6 @@
 
 !    CALL trace_start("send_message_mpi")
+
+    CALL enter_profile(id_mpi)
 
 !$OMP BARRIER
@@ -1482,4 +1487,6 @@
 !$OMP BARRIER
 !    CALL trace_end("send_message_mpi")
+
+    CALL exit_profile(id_mpi)
     
   END SUBROUTINE send_message_mpi
@@ -1499,4 +1506,5 @@
    
   SUBROUTINE wait_message_mpi(message)
+  USE profiling_mod
   USE field_mod
   USE domain_mod
@@ -1527,4 +1535,6 @@
     message%open=.FALSE.
     IF (.NOT. message%pending) RETURN
+
+    CALL enter_profile(id_mpi)
 
 !    CALL trace_start("wait_message_mpi")
@@ -1667,4 +1677,6 @@
 !$OMP BARRIER
     
+    CALL exit_profile(id_mpi)
+
   END SUBROUTINE wait_message_mpi
 
Index: codes/icosagcm/trunk/src/time/timeloop_gcm.f90
===================================================================
--- codes/icosagcm/trunk/src/time/timeloop_gcm.f90	(revision 666)
+++ codes/icosagcm/trunk/src/time/timeloop_gcm.f90	(revision 667)
@@ -1,3 +1,4 @@
 MODULE timeloop_gcm_mod
+  USE profiling_mod
   USE icosa
   USE disvert_mod
@@ -13,5 +14,5 @@
   TYPE(t_message),SAVE :: req_ps0, req_mass0, req_theta_rhodz0, req_u0, req_q0, req_W0, req_geopot0
   LOGICAL, SAVE :: positive_theta
-
+  INTEGER :: itau_prof, id_timeloop, id_dyn, id_phys, id_dissip, id_adv, id_diags
   PUBLIC :: init_timeloop, timeloop
 
@@ -32,8 +33,18 @@
     CHARACTER(len=255) :: def
 
+    CALL register_id('timeloop',id_timeloop)
+    CALL register_id('dyn',id_dyn)
+    CALL register_id('dissip',id_dissip)
+    CALL register_id('phys',id_phys)
+    CALL register_id('adv',id_adv)
+    CALL register_id('diags',id_diags)
+
     CALL init_caldyn
     
 !    IF (xios_output) itau_out=1
     IF (.NOT. enable_io) itau_out=HUGE(itau_out)
+
+    itau_prof=100
+    CALL getin('itau_profiling',itau_prof)
 
     positive_theta=.FALSE.
@@ -231,11 +242,11 @@
 
     !$OMP MASTER
-    CALL SYSTEM_CLOCK(start_clock)
-    CALL SYSTEM_CLOCK(count_rate=rate_clock)
+    CALL SYSTEM_CLOCK(start_clock, rate_clock)
     !$OMP END MASTER   
 
     DO it=itau0+1,itau0+itaumax
-
        IF (is_master) CALL print_iteration(it, itau0, itaumax, start_clock, rate_clock)
+
+       CALL enter_profile(id_timeloop)
 
        IF (xios_output) THEN
@@ -267,4 +278,5 @@
        CALL guided(it*dt,f_ps,f_theta_rhodz,f_u,f_q)
 
+       CALL enter_profile(id_dyn)
        SELECT CASE(scheme_family)
        CASE(explicit)
@@ -273,5 +285,7 @@
           CALL HEVI_scheme(it, fluxt_zero)
        END SELECT
-
+       CALL exit_profile(id_dyn)
+
+       CALL enter_profile(id_dissip)
        IF (MOD(it,itau_dissip)==0) THEN
           
@@ -288,6 +302,8 @@
           ENDIF
           
+          CALL enter_profile(id_diags)
           CALL check_conserve_detailed(it, AAM_dyn, &
                f_ps,f_dps,f_u,f_theta_rhodz,f_phis)
+          CALL exit_profile(id_diags)
        
           CALL dissip(f_ps,f_mass,f_phis,f_geopot,f_theta_rhodz,f_u, f_dtheta_rhodz,f_du)
@@ -299,8 +315,12 @@
           END IF
 
+          CALL enter_profile(id_diags)
           CALL check_conserve_detailed(it, AAM_dissip, &
                f_ps,f_dps,f_u,f_theta_rhodz,f_phis)
+          CALL exit_profile(id_diags)
        END IF
+       CALL exit_profile(id_dissip)
        
+       CALL enter_profile(id_adv)
        IF(MOD(it,itau_adv)==0) THEN
           CALL advect_tracer(f_hfluxt,f_wfluxt,f_u, f_q,f_rhodz, & ! update q and rhodz after RK step
@@ -322,9 +342,13 @@
           IF(positive_theta) CALL copy_q_to_theta(f_theta_rhodz,f_rhodz,f_q)
        END IF
+       CALL exit_profile(id_adv)
        
+       CALL enter_profile(id_diags)
        IF (MOD(it,itau_physics)==0) THEN
           CALL check_conserve_detailed(it, AAM_dyn, &
             f_ps,f_dps,f_u,f_theta_rhodz,f_phis)
+          CALL enter_profile(id_phys)
           CALL physics(it,f_phis, f_ps, f_theta_rhodz, f_u, f_wflux, f_q)        
+          CALL exit_profile(id_phys)
           CALL check_conserve_detailed(it, AAM_phys, &
                f_ps,f_dps,f_u,f_theta_rhodz,f_phis)
@@ -345,5 +369,7 @@
           CALL write_output_fields_basic(.FALSE.,f_phis, f_ps, f_mass, f_geopot, f_theta_rhodz, f_u, f_W, f_q)
        ENDIF
-
+       CALL exit_profile(id_diags)
+
+       CALL exit_profile(id_timeloop)
     END DO
     
@@ -382,4 +408,6 @@
             '  -- Completion in (min) : ', INT((total-elapsed)/60.)
     END IF
+    IF(MOD(it,itau_prof)==0) CALL print_profile
+
   END SUBROUTINE print_iteration
 
