main Program

Uses

  • program~~main~~UsesGraph program~main main module~cli cli program~main->module~cli module~game_of_life game_of_life program~main->module~game_of_life module~io io program~main->module~io mpi mpi program~main->mpi module~game_of_life->mpi module~comms comms module~game_of_life->module~comms

Board args


Calls

program~~main~~CallsGraph program~main main mpi_bcast mpi_bcast program~main->mpi_bcast mpi_comm_rank mpi_comm_rank program~main->mpi_comm_rank mpi_comm_size mpi_comm_size program~main->mpi_comm_size mpi_finalize mpi_finalize program~main->mpi_finalize mpi_init mpi_init program~main->mpi_init proc~find_steady_state find_steady_state program~main->proc~find_steady_state proc~read_cli_arg read_cli_arg program~main->proc~read_cli_arg proc~read_model_from_file read_model_from_file program~main->proc~read_model_from_file proc~find_steady_state->mpi_comm_rank mpi_allreduce mpi_allreduce proc~find_steady_state->mpi_allreduce mpi_barrier mpi_barrier proc~find_steady_state->mpi_barrier mpi_cart_create mpi_cart_create proc~find_steady_state->mpi_cart_create mpi_dims_create mpi_dims_create proc~find_steady_state->mpi_dims_create mpi_isend mpi_isend proc~find_steady_state->mpi_isend mpi_recv mpi_recv proc~find_steady_state->mpi_recv mpi_send mpi_send proc~find_steady_state->mpi_send proc~check_for_steady_state check_for_steady_state proc~find_steady_state->proc~check_for_steady_state proc~evolve_board evolve_board proc~find_steady_state->proc~evolve_board proc~exchange_boundaries exchange_boundaries proc~find_steady_state->proc~exchange_boundaries proc~get_local_grid_info get_local_grid_info proc~find_steady_state->proc~get_local_grid_info

Variables

Type Attributes Name Initial
logical :: local_steady = .false.

CLI args

character(len=:), allocatable :: executable_name

IO args

character(len=:), allocatable :: input_filename

IO args

character(len=:), allocatable :: io_error_message

MPI args


Source Code

program main
    ! allow(C121)
    use mpi
    use cli, only : read_cli_arg
    use game_of_life, only : check_for_steady_state, evolve_board, find_steady_state
    use io, only : read_model_from_file
    implicit none

    !! Board args
    integer, dimension(:,:), allocatable :: global_input_board
    integer :: generation_number, global_nrows, global_ncols
    logical :: local_steady = .false.

    !! CLI args
    character(len=:), allocatable :: executable_name, input_filename

    !! IO args
    character(len=:), allocatable :: io_error_message

    !! MPI args
    integer :: ierr, rank, nprocs
    logical :: error_found = .false.

    ! MPI Init
    call MPI_Init(ierr)
    call MPI_Comm_rank(MPI_COMM_WORLD, rank, ierr)
    call MPI_Comm_size(MPI_COMM_WORLD, nprocs, ierr)

    ! Read input on rank 0
    if (rank == 0) then
        ! Get current_board file path from command line
        if (command_argument_count() == 1) then
            call read_cli_arg(1, input_filename)
        else
            write(*,'(A)') "Error: Invalid input"
            call read_cli_arg(0, executable_name)
            write(*,'(A,A,A)') "Usage: ", executable_name, " <input_file_name>"
            error_found = .true.
        end if

        if (.not. error_found) then
            call read_model_from_file(input_filename, global_input_board, io_error_message)

            if (allocated(io_error_message)) then
                write (*,*) io_error_message
                deallocate(io_error_message)
                error_found = .true.
            end if

            if (.not. error_found) then
                global_ncols = size(global_input_board, 1)
                global_nrows = size(global_input_board, 2)
            end if
        end if
    end if

    ! Check for input errors
    call MPI_Bcast(error_found, 1, MPI_LOGICAL, 0, MPI_COMM_WORLD, ierr)
    if (error_found) then
        call MPI_Finalize(ierr)
        stop
    end if

    ! Broadcast global dimensions
    call MPI_Bcast(global_nrows, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)
    call MPI_Bcast(global_ncols, 1, MPI_INTEGER, 0, MPI_COMM_WORLD, ierr)

    call find_steady_state(local_steady, generation_number, global_input_board, global_ncols, global_nrows, MPI_COMM_WORLD, nprocs)

    ! if (rank == 0) then
    !     write(*,*) "Hello from rank 0", local_steady, generation_number
    ! end if

    if (rank == 0) then
        if (local_steady) then
            write(*,'(a,i6,a)') "Reached steady after ", generation_number, " generations"
        else
            write(*,'(a,i6,a)') "Did NOT Reach steady after ", generation_number, " generations"
        end if
    end if
    call MPI_Finalize(ierr)

end program main