node_worker Module Subroutine

module subroutine node_worker(resources, sys_geom, method_config, calc_type)

Uses

  • proc~~node_worker~~UsesGraph proc~node_worker node_worker module~mqc_error mqc_error proc~node_worker->module~mqc_error

Node worker for processing fragments assigned by node coordinator Bond connectivity is accessed via sys_geom%bonds

Arguments

Type IntentOptional Attributes Name
type(resources_t), intent(in) :: resources
type(system_geometry_t), intent(in), optional :: sys_geom
type(method_config_t), intent(in) :: method_config

Method configuration

integer(kind=int32), intent(in) :: calc_type

Calls

proc~~node_worker~~CallsGraph proc~node_worker node_worker abort_comm abort_comm proc~node_worker->abort_comm error error proc~node_worker->error interface~do_fragment_work do_fragment_work proc~node_worker->interface~do_fragment_work irecv irecv proc~node_worker->irecv isend isend proc~node_worker->isend proc~build_fragment_from_atom_list build_fragment_from_atom_list proc~node_worker->proc~build_fragment_from_atom_list proc~build_fragment_from_indices build_fragment_from_indices proc~node_worker->proc~build_fragment_from_indices proc~error_get_full_trace error_t%error_get_full_trace proc~node_worker->proc~error_get_full_trace proc~error_has_error error_t%error_has_error proc~node_worker->proc~error_has_error proc~fragment_destroy physical_fragment_t%fragment_destroy proc~node_worker->proc~fragment_destroy proc~result_isend result_isend proc~node_worker->proc~result_isend recv recv proc~node_worker->recv to_char to_char proc~node_worker->to_char proc~do_fragment_work do_fragment_work interface~do_fragment_work->proc~do_fragment_work proc~build_fragment_from_atom_list->proc~error_has_error proc~add_hydrogen_caps add_hydrogen_caps proc~build_fragment_from_atom_list->proc~add_hydrogen_caps proc~check_duplicate_atoms check_duplicate_atoms proc~build_fragment_from_atom_list->proc~check_duplicate_atoms proc~count_hydrogen_caps count_hydrogen_caps proc~build_fragment_from_atom_list->proc~count_hydrogen_caps proc~error_add_context error_t%error_add_context proc~build_fragment_from_atom_list->proc~error_add_context proc~fragment_compute_nelec physical_fragment_t%fragment_compute_nelec proc~build_fragment_from_atom_list->proc~fragment_compute_nelec proc~build_fragment_from_indices->proc~error_has_error proc~build_fragment_from_indices->proc~add_hydrogen_caps proc~calculate_monomer_distance calculate_monomer_distance proc~build_fragment_from_indices->proc~calculate_monomer_distance proc~build_fragment_from_indices->proc~check_duplicate_atoms proc~build_fragment_from_indices->proc~count_hydrogen_caps proc~build_fragment_from_indices->proc~error_add_context proc~build_fragment_from_indices->proc~fragment_compute_nelec proc~error_get_full_trace->proc~error_has_error proc~basis_set_destroy molecular_basis_type%basis_set_destroy proc~fragment_destroy->proc~basis_set_destroy proc~result_isend->isend send send proc~result_isend->send proc~atomic_basis_destroy atomic_basis_type%atomic_basis_destroy proc~basis_set_destroy->proc~atomic_basis_destroy proc~to_angstrom to_angstrom proc~calculate_monomer_distance->proc~to_angstrom proc~check_duplicate_atoms->error proc~check_duplicate_atoms->to_char proc~element_number_to_symbol element_number_to_symbol proc~check_duplicate_atoms->proc~element_number_to_symbol proc~error_set error_t%error_set proc~check_duplicate_atoms->proc~error_set proc~do_fragment_work->to_char proc~do_fragment_work->proc~error_add_context calc_energy calc_energy proc~do_fragment_work->calc_energy calc_gradient calc_gradient proc~do_fragment_work->calc_gradient calc_hessian calc_hessian proc~do_fragment_work->calc_hessian configuration configuration proc~do_fragment_work->configuration proc~calc_type_to_string calc_type_to_string proc~do_fragment_work->proc~calc_type_to_string proc~create_method create_method proc~do_fragment_work->proc~create_method proc~energy_reset energy_t%energy_reset proc~do_fragment_work->proc~energy_reset proc~do_fragment_work->proc~error_set proc~print_fragment_xyz print_fragment_xyz proc~do_fragment_work->proc~print_fragment_xyz proc~cgto_destroy cgto_type%cgto_destroy proc~atomic_basis_destroy->proc~cgto_destroy proc~factory_create method_factory_t%factory_create proc~create_method->proc~factory_create proc~mp2_reset mp2_energy_t%mp2_reset proc~energy_reset->proc~mp2_reset proc~print_fragment_xyz->to_char proc~print_fragment_xyz->proc~element_number_to_symbol proc~print_fragment_xyz->proc~to_angstrom info info proc~print_fragment_xyz->info proc~configure_dft configure_dft proc~factory_create->proc~configure_dft proc~configure_hf configure_hf proc~factory_create->proc~configure_hf proc~configure_mcscf configure_mcscf proc~factory_create->proc~configure_mcscf proc~configure_xtb configure_xtb proc~factory_create->proc~configure_xtb

Called by

proc~~node_worker~~CalledByGraph proc~node_worker node_worker interface~node_worker node_worker interface~node_worker->proc~node_worker proc~gmbe_run_distributed gmbe_context_t%gmbe_run_distributed proc~gmbe_run_distributed->interface~node_worker proc~mbe_run_distributed mbe_context_t%mbe_run_distributed proc~mbe_run_distributed->interface~node_worker

Variables

Type Visibility Attributes Name Initial
integer(kind=int32), private :: dummy_msg
type(error_t), private :: error
integer(kind=int64), private :: fragment_idx
integer(kind=int32), private, allocatable :: fragment_indices(:)
integer(kind=int32), private :: fragment_size
integer(kind=int32), private :: fragment_type

0 = monomer (indices), 1 = intersection (atom list)

type(physical_fragment_t), private :: phys_frag
type(request_t), private :: req
type(calculation_result_t), private :: result
type(MPI_Status), private :: status

Source Code

   module subroutine node_worker(resources, sys_geom, method_config, calc_type)
      !! Node worker for processing fragments assigned by node coordinator
      !! Bond connectivity is accessed via sys_geom%bonds
      use mqc_error, only: error_t
      type(resources_t), intent(in) :: resources
      type(system_geometry_t), intent(in), optional :: sys_geom
      type(method_config_t), intent(in) :: method_config  !! Method configuration
      integer(int32), intent(in) :: calc_type

      integer(int64) :: fragment_idx
      integer(int32) :: fragment_size, dummy_msg
      integer(int32) :: fragment_type  !! 0 = monomer (indices), 1 = intersection (atom list)
      integer(int32), allocatable :: fragment_indices(:)
      type(calculation_result_t) :: result
      type(MPI_Status) :: status
      type(physical_fragment_t) :: phys_frag
      type(error_t) :: error

      ! MPI request handles for non-blocking operations
      type(request_t) :: req

      dummy_msg = 0

      do
         call isend(resources%mpi_comms%node_comm, dummy_msg, 0, TAG_WORKER_REQUEST, req)
         call wait(req)
         call irecv(resources%mpi_comms%node_comm, fragment_idx, 0, MPI_ANY_TAG, req)
         call wait(req, status)

         select case (status%MPI_TAG)
         case (TAG_WORKER_FRAGMENT)
            ! Receive fragment type (0 = monomer indices, 1 = intersection atom list)
            call irecv(resources%mpi_comms%node_comm, fragment_type, 0, TAG_WORKER_FRAGMENT, req)
            call wait(req)
            call irecv(resources%mpi_comms%node_comm, fragment_size, 0, TAG_WORKER_FRAGMENT, req)
            call wait(req)
            ! Note: must use blocking recv for allocatable arrays since size is unknown
            allocate (fragment_indices(fragment_size))
            call recv(resources%mpi_comms%node_comm, fragment_indices, 0, TAG_WORKER_FRAGMENT, status)

            ! Build physical fragment based on type
            if (present(sys_geom)) then
               if (fragment_type == 0) then
                  ! Monomer: fragment_indices are monomer indices
                  call build_fragment_from_indices(sys_geom, fragment_indices, phys_frag, error, sys_geom%bonds)
               else
                  ! Intersection: fragment_indices are atom indices
           call build_fragment_from_atom_list(sys_geom, fragment_indices, fragment_size, phys_frag, error, sys_geom%bonds)
               end if

               if (error%has_error()) then
                  call logger%error(error%get_full_trace())
                  call abort_comm(resources%mpi_comms%world_comm, 1)
               end if

               ! Process the chemistry fragment with physical geometry
          call do_fragment_work(fragment_idx, result, method_config, phys_frag, calc_type, resources%mpi_comms%world_comm)

               call phys_frag%destroy()
            else
               ! Process without physical geometry (old behavior)
               call do_fragment_work(fragment_idx, result, method_config, &
                                     calc_type=calc_type, world_comm=resources%mpi_comms%world_comm)
            end if

            ! Send result back to coordinator
            call result_isend(result, resources%mpi_comms%node_comm, 0, TAG_WORKER_SCALAR_RESULT, req)
            call wait(req)

            ! Clean up result
            call result%destroy()
            deallocate (fragment_indices)
         case (TAG_WORKER_FINISH)
            exit
         case default
            ! Unexpected MPI tag - this should not happen in normal operation
            call logger%error("Worker received unexpected MPI tag: "//to_char(status%MPI_TAG))
            call logger%error("Expected TAG_WORKER_FRAGMENT or TAG_WORKER_FINISH")
            call abort_comm(resources%mpi_comms%world_comm, 1)
         end select
      end do
   end subroutine node_worker