diff --git a/src/cp2k_runs.F b/src/cp2k_runs.F index f3a63722fa..9f95edb1e2 100644 --- a/src/cp2k_runs.F +++ b/src/cp2k_runs.F @@ -16,7 +16,6 @@ MODULE cp2k_runs cp2k_year,& enable_color_tags USE cp_files, ONLY: close_file,& - get_unit_number,& open_file USE cp_output_handling, ONLY: cp_add_iter_level,& cp_print_key_finished_output,& @@ -473,9 +472,9 @@ CONTAINS TYPE(section_type), POINTER :: g_section TYPE(section_vals_type), POINTER :: g_data -! the primus of all slaves, talks to the master on topics concerning all slaves failure=.FALSE. + ! the primus of all slaves, talks to the master on topics concerning all slaves CALL timeset(routineN,handle) NULLIFY(my_parser,g_section,g_data,default_units) @@ -598,12 +597,13 @@ CONTAINS ENDIF ! and write the restart now, that's the point where the next job starts, even if this one is running - IF (para_env%ionode) THEN - iunit=get_unit_number() - OPEN(UNIT=iunit,FILE="RESTARTFARM") + iunit=cp_print_key_unit_nr(logger,root_section,"FARMING%RESTART",& + extension=".restart",error=error) + IF (iunit>0) THEN WRITE(iunit,*) i_job_to_restart - CLOSE(UNIT=iunit) ENDIF + CALL cp_print_key_finished_output(iunit,logger,root_section,"FARMING%RESTART",error=error) + ! this is the job range to be executed. ijob_start=farming_env%restart_n @@ -611,7 +611,7 @@ CONTAINS IF (output_unit>0 .AND. ijob_end-ijob_start<0) THEN WRITE(output_unit,FMT="(T2,A)") "FARMING| --- WARNING --- NO JOBS NEED EXECUTION ? " WRITE(output_unit,FMT="(T2,A)") "FARMING| is the cycle keyword required ?" - WRITE(output_unit,FMT="(T2,A)") "FARMING| or is a stray RESTARTFARM present ?" + WRITE(output_unit,FMT="(T2,A)") "FARMING| or is a stray RESTART file present ?" WRITE(output_unit,FMT="(T2,A)") "FARMING| or is the group_size requested smaller than the number of CPUs?" ENDIF diff --git a/src/farming_methods.F b/src/farming_methods.F index d8805defba..076b1e1e5d 100644 --- a/src/farming_methods.F +++ b/src/farming_methods.F @@ -7,6 +7,7 @@ MODULE farming_methods USE cp_files, ONLY: get_unit_number USE cp_output_handling, ONLY: cp_print_key_finished_output,& + cp_print_key_generate_filename,& cp_print_key_unit_nr USE cp_para_types, ONLY: cp_para_env_type USE f77_blas @@ -113,187 +114,202 @@ CONTAINS INTEGER :: i, iunit, n_rep_val, & num_slaves, output_unit, stat INTEGER, DIMENSION(:), POINTER :: dependencies, i_vals - LOGICAL :: failure, has_dep + LOGICAL :: explicit, failure, has_dep TYPE(cp_logger_type), POINTER :: logger - TYPE(section_vals_type), POINTER :: farming_section, jobs_section + TYPE(section_vals_type), POINTER :: farming_section, & + jobs_section, print_key failure=.FALSE. + NULLIFY(farming_section, jobs_section, print_key, logger, dependencies, i_vals) + logger => cp_error_get_logger(error) + farming_env%group_size_wish_set=.FALSE. + farming_env%ngroup_wish_set =.FALSE. + farming_section => section_vals_get_subs_vals(root_section,"FARMING",& + error=error) - farming_env%group_size_wish_set=.FALSE. - farming_env%ngroup_wish_set =.FALSE. - farming_section => section_vals_get_subs_vals(root_section,"FARMING",& - error=error) + IF (ASSOCIATED(farming_env%group_partition)) THEN + DEALLOCATE(farming_env%group_partition,stat=stat) + CPPostconditionNoFail(stat==0,cp_warning_level,routineP,error) + END IF - IF (ASSOCIATED(farming_env%group_partition)) THEN - DEALLOCATE(farming_env%group_partition,stat=stat) - CPPostconditionNoFail(stat==0,cp_warning_level,routineP,error) - END IF + ! The following input order is used + ! 1) GROUP_PARTITION + ! 2) NGROUP + ! 3) GROUP_SIZE (default 8) + CALL section_vals_val_get(farming_section,"GROUP_PARTITION",& + n_rep_val=n_rep_val,error=error) + IF (n_rep_val>0) THEN + CALL section_vals_val_get(farming_section,"GROUP_PARTITION",& + i_vals=i_vals,error=error) + ALLOCATE(farming_env%group_partition(0:SIZE(i_vals)-1)) + farming_env%group_partition(:)=i_vals + farming_env%ngroup_wish_set=.TRUE. + farming_env%ngroup_wish=SIZE(i_vals) + ELSE + CALL section_vals_val_get(farming_section,"NGROUP",& + n_rep_val=n_rep_val,error=error) + IF (n_rep_val>0) THEN + CALL section_vals_val_get(farming_section,"NGROUP",& + i_val=farming_env%ngroup_wish,error=error) + farming_env%ngroup_wish_set=.TRUE. + ELSE + CALL section_vals_val_get(farming_section,"GROUP_SIZE",& + i_val=farming_env%group_size_wish,error=error) + farming_env%group_size_wish_set=.TRUE. + END IF + END IF - ! The following input order is used - ! 1) GROUP_PARTITION - ! 2) NGROUP - ! 3) GROUP_SIZE (default 8) - CALL section_vals_val_get(farming_section,"GROUP_PARTITION",& - n_rep_val=n_rep_val,error=error) - IF (n_rep_val>0) THEN - CALL section_vals_val_get(farming_section,"GROUP_PARTITION",& - i_vals=i_vals,error=error) - ALLOCATE(farming_env%group_partition(0:SIZE(i_vals)-1)) - farming_env%group_partition(:)=i_vals - farming_env%ngroup_wish_set=.TRUE. - farming_env%ngroup_wish=SIZE(i_vals) - ELSE - CALL section_vals_val_get(farming_section,"NGROUP",& - n_rep_val=n_rep_val,error=error) - IF (n_rep_val>0) THEN - CALL section_vals_val_get(farming_section,"NGROUP",& - i_val=farming_env%ngroup_wish,error=error) - farming_env%ngroup_wish_set=.TRUE. - ELSE - CALL section_vals_val_get(farming_section,"GROUP_SIZE",& - i_val=farming_env%group_size_wish,error=error) - farming_env%group_size_wish_set=.TRUE. - END IF - END IF + + CALL section_vals_val_get(farming_section,"RESTART_FILE_NAME",& + explicit=explicit,error=error) + IF (explicit) THEN + CALL section_vals_val_get(farming_section,"RESTART_FILE_NAME",& + c_val=farming_env%restart_file_name,error=error) + ELSE + print_key => section_vals_get_subs_vals(farming_section,"RESTART",error=error) + farming_env%restart_file_name=cp_print_key_generate_filename(logger,print_key,extension=".restart",& + my_local=.FALSE., error=error) + END IF - CALL section_vals_val_get(farming_section,"RESTART",& - l_val=farming_env%restart,error=error) - CALL section_vals_val_get(farming_section,"MAX_JOBS_PER_GROUP",& - i_val=farming_env%max_steps,error=error) - CALL section_vals_val_get(farming_section,"CYCLE",& - l_val=farming_env%cycle,error=error) - CALL section_vals_val_get(farming_section,"WAIT_TIME",& - r_val=farming_env%wait_time,error=error) + CALL section_vals_val_get(farming_section,"DO_RESTART",& + l_val=farming_env%restart,error=error) + CALL section_vals_val_get(farming_section,"MAX_JOBS_PER_GROUP",& + i_val=farming_env%max_steps,error=error) + CALL section_vals_val_get(farming_section,"CYCLE",& + l_val=farming_env%cycle,error=error) + CALL section_vals_val_get(farming_section,"WAIT_TIME",& + r_val=farming_env%wait_time,error=error) - CALL section_vals_val_get(farming_section,"MASTER_SLAVE",& - l_val=farming_env%master_slave,error=error) + CALL section_vals_val_get(farming_section,"MASTER_SLAVE",& + l_val=farming_env%master_slave,error=error) - jobs_section => section_vals_get_subs_vals(farming_section,"JOB",error=error) - CALL section_vals_get(jobs_section,n_repetition=farming_env % njobs,error=error) - - ALLOCATE(farming_env%Job(farming_env % njobs),STAT=stat) - CPPostcondition(stat==0,cp_failure_level,routineP,error,failure) - CALL init_job_type(farming_env%job) + jobs_section => section_vals_get_subs_vals(farming_section,"JOB",error=error) + CALL section_vals_get(jobs_section,n_repetition=farming_env % njobs,error=error) + + ALLOCATE(farming_env%Job(farming_env % njobs),STAT=stat) + CPPostcondition(stat==0,cp_failure_level,routineP,error,failure) + CALL init_job_type(farming_env%job) - IF (.NOT. failure) THEN - has_dep=.FALSE. - DO i=1,farming_env%njobs - CALL section_vals_val_get(jobs_section,i_rep_section=i,& - keyword_name="DIRECTORY",c_val=farming_env%Job(i)%cwd,error=error) - CALL section_vals_val_get(jobs_section,i_rep_section=i,& - keyword_name="INPUT_FILE_NAME",c_val=farming_env%Job(i)%input,error=error) - CALL section_vals_val_get(jobs_section,i_rep_section=i,& - keyword_name="OUTPUT_FILE_NAME",c_val=farming_env%Job(i)%output,error=error) + IF (.NOT. failure) THEN + has_dep=.FALSE. + DO i=1,farming_env%njobs + CALL section_vals_val_get(jobs_section,i_rep_section=i,& + keyword_name="DIRECTORY",c_val=farming_env%Job(i)%cwd,error=error) + CALL section_vals_val_get(jobs_section,i_rep_section=i,& + keyword_name="INPUT_FILE_NAME",c_val=farming_env%Job(i)%input,error=error) + CALL section_vals_val_get(jobs_section,i_rep_section=i,& + keyword_name="OUTPUT_FILE_NAME",c_val=farming_env%Job(i)%output,error=error) - ! if job id is not specified the job id is the index - CALL section_vals_val_get(jobs_section,i_rep_section=i,& - keyword_name="JOB_ID",n_rep_val=n_rep_val,error=error) - IF (n_rep_val==0) THEN - farming_env%Job(i)%id=i - ELSE - CALL section_vals_val_get(jobs_section,i_rep_section=i,& - keyword_name="JOB_ID",i_val=farming_env%Job(i)%id,error=error) - ENDIF + ! if job id is not specified the job id is the index + CALL section_vals_val_get(jobs_section,i_rep_section=i,& + keyword_name="JOB_ID",n_rep_val=n_rep_val,error=error) + IF (n_rep_val==0) THEN + farming_env%Job(i)%id=i + ELSE + CALL section_vals_val_get(jobs_section,i_rep_section=i,& + keyword_name="JOB_ID",i_val=farming_env%Job(i)%id,error=error) + ENDIF - ! get dependencies - CALL section_vals_val_get(jobs_section,i_rep_section=i,& - keyword_name="DEPENDENCIES",n_rep_val=n_rep_val,error=error) - IF (n_rep_val==0) THEN - ALLOCATE(farming_env%Job(i)%dependencies(0)) - ELSE - CALL section_vals_val_get(jobs_section,i_rep_section=i,& - keyword_name="DEPENDENCIES",i_vals=dependencies,error=error) - ALLOCATE(farming_env%Job(i)%dependencies(SIZE(dependencies,1))) - farming_env%Job(i)%dependencies=dependencies - IF (SIZE(dependencies,1).NE.0) has_dep=.TRUE. - ENDIF - END DO - END IF + ! get dependencies + CALL section_vals_val_get(jobs_section,i_rep_section=i,& + keyword_name="DEPENDENCIES",n_rep_val=n_rep_val,error=error) + IF (n_rep_val==0) THEN + ALLOCATE(farming_env%Job(i)%dependencies(0)) + ELSE + CALL section_vals_val_get(jobs_section,i_rep_section=i,& + keyword_name="DEPENDENCIES",i_vals=dependencies,error=error) + ALLOCATE(farming_env%Job(i)%dependencies(SIZE(dependencies,1))) + farming_env%Job(i)%dependencies=dependencies + IF (SIZE(dependencies,1).NE.0) has_dep=.TRUE. + ENDIF + END DO + END IF - IF (has_dep) THEN - CPPostcondition(farming_env%master_slave,cp_failure_level,routineP,error,failure) - CPPostcondition(.NOT.farming_env%cycle,cp_failure_level,routineP,error,failure) - ENDIF - - IF (.NOT. failure) THEN - - logger => cp_error_get_logger(error) - output_unit=cp_print_key_unit_nr(logger,farming_section,"PROGRAM_RUN_INFO",& - extension=".log",error=error) - - ! master slave not supported - IF (para_env%num_pe==1) THEN - farming_env%master_slave=.FALSE. - WRITE(output_unit,FMT="(T2,A)") "FARMING| Master-slave setup not support for serial runs" - ENDIF - IF (farming_env%master_slave) THEN - num_slaves=para_env%num_pe-1 - ELSE - num_slaves=para_env%num_pe - ENDIF - - IF (output_unit > 0) THEN - WRITE(output_unit,FMT="(T2,A,T71,I10)") "FARMING| Number of jobs found",farming_env%njobs - IF (farming_env%ngroup_wish_set) THEN - WRITE(output_unit,FMT="(T2,A,T71,I10)") "FARMING| Ngroup wish:",farming_env%ngroup_wish - IF (ASSOCIATED(farming_env%group_partition)) THEN - WRITE(output_unit,FMT="(T2,A)",ADVANCE="NO") "FARMING| User partition:" - DO i=0,SIZE(farming_env%group_partition)-1 - IF (MODULO(i,4)==0) WRITE(output_unit,*) - WRITE(output_unit,FMT='(I4)',ADVANCE="NO") farming_env%group_partition(i) - END DO - WRITE(output_unit,*) - IF (SUM(farming_env%group_partition).NE.num_slaves) THEN - WRITE(output_unit,FMT="(T2,A,T61,I10,T71,I10)") & - "FARMING| WARNING : group partition CPUs not equal to the available number (ignoring master) ", & - num_slaves, SUM(farming_env%group_partition) - WRITE(output_unit,FMT="(T2,A)") "FARMING| partition data ignored" ! any better idea ?? - DEALLOCATE(farming_env%group_partition) - ENDIF - ENDIF - ENDIF - IF (farming_env%group_size_wish_set) THEN - WRITE(output_unit,FMT="(T2,A,T71,I10)") "FARMING| Group size wish:", & - farming_env%group_size_wish - ENDIF - WRITE(output_unit,FMT="(T2,A,T71,I10)") "FARMING| Max steps :",farming_env%max_steps - IF (farming_env%cycle) THEN - text="YES" - ELSE - text=" NO" - ENDIF - WRITE(output_unit,FMT="(T2,A,T78,A3)") "FARMING| Cyclic jobs execution:",text - IF (farming_env%restart) THEN - text="YES" - ELSE - text=" NO" - ENDIF - WRITE(output_unit,FMT="(T2,A,T78,A3)") "FARMING| Restarting farm:",text - farming_env%restart_n = 1 - IF (farming_env%restart) THEN - iunit=get_unit_number() - OPEN(UNIT=iunit,FILE="RESTARTFARM",IOSTAT=stat) - IF (stat==0) THEN - READ(UNIT=iunit,FMT=*,IOSTAT=stat) farming_env%restart_n - IF (stat/=0) THEN - WRITE(output_unit,"(T2,A)") & - "FARMING| ---- WARNING ---- failed to read from RESTARTFARM, starting at 1" - ELSE - WRITE(output_unit,"(T2,A,T71,I10)") & - "FARMING| restarting from RESTARTFARM, starting at ",farming_env%restart_n - ENDIF - ELSE - WRITE(output_unit,"(T2,A)") & - "FARMING| ---- WARNING ---- failed to open RESTARTFARM, starting at 1" - ENDIF - CLOSE(iunit,IOSTAT=stat) - ENDIF - - CALL cp_print_key_finished_output(output_unit,logger,farming_section,& - "PROGRAM_RUN_INFO", error=error) - ENDIF + IF (has_dep) THEN + CPPostcondition(farming_env%master_slave,cp_failure_level,routineP,error,failure) + CPPostcondition(.NOT.farming_env%cycle,cp_failure_level,routineP,error,failure) ENDIF - CALL mp_bcast(farming_env%restart_n,para_env%source,para_env%group) + + IF (.NOT. failure) THEN + + output_unit=cp_print_key_unit_nr(logger,farming_section,"PROGRAM_RUN_INFO",& + extension=".log",error=error) + + ! master slave not supported + IF (para_env%num_pe==1) THEN + farming_env%master_slave=.FALSE. + WRITE(output_unit,FMT="(T2,A)") "FARMING| Master-slave setup not support for serial runs" + ENDIF + IF (farming_env%master_slave) THEN + num_slaves=para_env%num_pe-1 + ELSE + num_slaves=para_env%num_pe + ENDIF + + IF (output_unit > 0) THEN + WRITE(output_unit,FMT="(T2,A,T71,I10)") "FARMING| Number of jobs found",farming_env%njobs + IF (farming_env%ngroup_wish_set) THEN + WRITE(output_unit,FMT="(T2,A,T71,I10)") "FARMING| Ngroup wish:",farming_env%ngroup_wish + IF (ASSOCIATED(farming_env%group_partition)) THEN + WRITE(output_unit,FMT="(T2,A)",ADVANCE="NO") "FARMING| User partition:" + DO i=0,SIZE(farming_env%group_partition)-1 + IF (MODULO(i,4)==0) WRITE(output_unit,*) + WRITE(output_unit,FMT='(I4)',ADVANCE="NO") farming_env%group_partition(i) + END DO + WRITE(output_unit,*) + IF (SUM(farming_env%group_partition).NE.num_slaves) THEN + WRITE(output_unit,FMT="(T2,A,T61,I10,T71,I10)") & + "FARMING| WARNING : group partition CPUs not equal to the available number (ignoring master) ", & + num_slaves, SUM(farming_env%group_partition) + WRITE(output_unit,FMT="(T2,A)") "FARMING| partition data ignored" ! any better idea ?? + DEALLOCATE(farming_env%group_partition) + ENDIF + ENDIF + ENDIF + IF (farming_env%group_size_wish_set) THEN + WRITE(output_unit,FMT="(T2,A,T71,I10)") "FARMING| Group size wish:", & + farming_env%group_size_wish + ENDIF + WRITE(output_unit,FMT="(T2,A,T71,I10)") "FARMING| Max steps :",farming_env%max_steps + IF (farming_env%cycle) THEN + text="YES" + ELSE + text=" NO" + ENDIF + WRITE(output_unit,FMT="(T2,A,T78,A3)") "FARMING| Cyclic jobs execution:",text + IF (farming_env%restart) THEN + text="YES" + ELSE + text=" NO" + ENDIF + WRITE(output_unit,FMT="(T2,A,T78,A3)") "FARMING| Restarting farm:",text + farming_env%restart_n = 1 + IF (farming_env%restart) THEN + iunit=get_unit_number() + OPEN(UNIT=iunit,FILE=farming_env%restart_file_name,IOSTAT=stat) + IF (stat==0) THEN + READ(UNIT=iunit,FMT=*,IOSTAT=stat) farming_env%restart_n + IF (stat/=0) THEN + WRITE(output_unit,"(T2,A)") & + "FARMING| ---- WARNING ---- failed to read from ("//TRIM(farming_env%restart_file_name)//") starting at 1" + ELSE + WRITE(output_unit,"(T2,A)") & + "FARMING| restarting from ("//TRIM(farming_env%restart_file_name)//")" + WRITE(output_unit,"(T2,A,T71,I10)") & + "FARMING| restarting at ",farming_env%restart_n + ENDIF + ELSE + WRITE(output_unit,"(T2,A)") & + "FARMING| ---- WARNING ---- failed to open ("//TRIM(farming_env%restart_file_name)//"), starting at 1" + ENDIF + CLOSE(iunit,IOSTAT=stat) + ENDIF + + CALL cp_print_key_finished_output(output_unit,logger,farming_section,& + "PROGRAM_RUN_INFO", error=error) + ENDIF + ENDIF + CALL mp_bcast(farming_env%restart_n,para_env%source,para_env%group) END SUBROUTINE diff --git a/src/farming_types.F b/src/farming_types.F index 181d4712cc..6eb5e179be 100644 --- a/src/farming_types.F +++ b/src/farming_types.F @@ -37,6 +37,7 @@ MODULE farming_types LOGICAL :: CYCLE LOGICAL :: master_slave INTEGER, DIMENSION(:), POINTER :: group_partition ! user preference for partitioning the cpus + CHARACTER(LEN=default_path_length) :: restart_file_name ! restart file for farming CHARACTER(LEN=default_path_length) :: cwd ! directory we started from INTEGER :: Njobs ! how many jobs to run INTEGER :: restart_n ! where to start diff --git a/src/input_cp2k.F b/src/input_cp2k.F index c29ba9375c..85cf623795 100644 --- a/src/input_cp2k.F +++ b/src/input_cp2k.F @@ -38,6 +38,7 @@ MODULE input_cp2k section_vals_get_subs_vals, section_vals_type USE input_val_types, ONLY: char_t,& integer_t,& + lchar_t,& logical_t,& real_t USE kinds, ONLY: dp @@ -1505,13 +1506,6 @@ CONTAINS CALL section_add_keyword(section,keyword,error=error) CALL keyword_release(keyword,error=error) - CALL keyword_create(keyword, name="RESTART",& - description="restart a farming job (and should pick up where the previous left off)",& - usage="RESTART",default_l_val=.FALSE.,lone_keyword_l_val=.TRUE.,& - supported_feature=.TRUE.,error=error) - CALL section_add_keyword(section,keyword,error=error) - CALL keyword_release(keyword,error=error) - CALL keyword_create(keyword, name="MAX_JOBS_PER_GROUP",& variants=(/"MAX_JOBS"/),& description="maximum number of jobs executed per group",& @@ -1591,6 +1585,28 @@ CONTAINS CALL section_add_subsection(section,print_key,error=error) CALL section_release(print_key,error=error) + CALL keyword_create(keyword, name="DO_RESTART",& + description="Restart a farming job (and should pick up where the previous left off)",& + usage="DO_RESTART",default_l_val=.FALSE.,lone_keyword_l_val=.TRUE.,& + supported_feature=.TRUE.,error=error) + CALL section_add_keyword(section,keyword,error=error) + CALL keyword_release(keyword,error=error) + + CALL keyword_create(keyword, name="RESTART_FILE_NAME",& + description="Name of the restart file to use for restarting a FARMING run. If not "//& + "specified the name is determined from PROJECT name.",& + usage="RESTART_FILE_NAME ", type_of_var=lchar_t,& + error=error) + CALL section_add_keyword(section,keyword,error=error) + CALL keyword_release(keyword,error=error) + + CALL cp_print_key_section_create(print_key,"RESTART",& + description="controls the printing of the restart for FARMING.",& + print_level=low_print_level,add_last=add_last_numeric,filename="FARMING",& + supported_feature=.TRUE.,error=error) + CALL section_add_subsection(section,print_key,error=error) + CALL section_release(print_key,error=error) + END SUBROUTINE create_farming_section ! ***************************************************************************** diff --git a/tests/FARMING/regtest-1/farming-5.inp b/tests/FARMING/regtest-1/farming-5.inp index f1f129c771..0767af3f38 100644 --- a/tests/FARMING/regtest-1/farming-5.inp +++ b/tests/FARMING/regtest-1/farming-5.inp @@ -1,6 +1,7 @@ &GLOBAL PROGRAM FARMING RUN_TYPE NONE + PROJECT FARMING_TO_RESTART &END GLOBAL &FARMING diff --git a/tests/FARMING/regtest-1/farming-6.inp b/tests/FARMING/regtest-1/farming-6.inp index a0b9c584f5..deb7c159e9 100644 --- a/tests/FARMING/regtest-1/farming-6.inp +++ b/tests/FARMING/regtest-1/farming-6.inp @@ -1,3 +1,5 @@ +#CPQA DEPENDS farming-5.inp + &GLOBAL PROGRAM FARMING RUN_TYPE NONE @@ -6,7 +8,8 @@ &FARMING NGROUP 2 ! CYCLE - RESTART + RESTART_FILE_NAME FARMING_TO_RESTART-FARMING-1.restart + DO_RESTART ! MAX_JOBS_PER_GROUP 10 &JOB DIRECTORY dir-1