54#include "./base/base_uses.f90"
60 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'pao_ml'
65 TYPE training_point_type
66 TYPE(training_point_type),
POINTER :: next => null()
67 REAL(dp),
DIMENSION(:),
ALLOCATABLE :: input
68 REAL(dp),
DIMENSION(:),
ALLOCATABLE :: output
69 END TYPE training_point_type
71 TYPE training_list_type
72 CHARACTER(LEN=default_string_length) :: kindname =
""
73 TYPE(training_point_type),
POINTER :: head => null()
74 INTEGER :: npoints = 0
75 END TYPE training_list_type
91 TYPE(training_list_type),
ALLOCATABLE, &
92 DIMENSION(:) :: training_lists
94 IF (
SIZE(pao%ml_training_set) == 0)
RETURN
96 IF (pao%iw > 0)
WRITE (pao%iw, *)
'PAO|ML| Initializing maschine learning...'
99 cpabort(
"PAO maschine learning requires ROTINV parametrization")
101 CALL get_qs_env(qs_env, para_env=para_env, atomic_kind_set=atomic_kind_set)
104 ALLOCATE (training_lists(
SIZE(atomic_kind_set)))
105 DO i = 1,
SIZE(training_lists)
106 CALL get_atomic_kind(atomic_kind_set(i), name=training_lists(i)%kindname)
110 DO i = 1,
SIZE(pao%ml_training_set)
111 CALL add_to_training_list(pao, qs_env, training_lists, filename=pao%ml_training_set(i)%fn)
115 CALL sanity_check(qs_env, training_lists)
118 CALL training_list2matrix(training_lists, pao%ml_training_matrices, para_env)
121 CALL pao_ml_substract_prior(pao%ml_prior, pao%ml_training_matrices)
124 CALL pao_ml_print(pao, pao%ml_training_matrices)
127 CALL pao_ml_train(pao)
138 SUBROUTINE add_to_training_list(pao, qs_env, training_lists, filename)
141 TYPE(training_list_type),
DIMENSION(:) :: training_lists
142 CHARACTER(LEN=default_path_length) :: filename
144 CHARACTER(LEN=default_string_length) :: param
145 INTEGER :: iatom, ikind, natoms, nkinds, nparams
146 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom2kind, kindsmap
147 INTEGER,
DIMENSION(2) :: ml_range
148 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: hmat, positions
154 TYPE(
particle_type),
DIMENSION(:),
POINTER :: my_particle_set
155 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
156 TYPE(training_point_type),
POINTER :: new_point
158 NULLIFY (new_point, cell)
160 IF (pao%iw > 0)
WRITE (pao%iw,
'(A,A)')
" PAO|ML| Reading training frame from file: ", trim(filename)
165 IF (para_env%is_source())
THEN
166 CALL pao_read_raw(filename, param, hmat,
kinds, atom2kind, positions, xblocks, ml_range)
169 IF (trim(param) .NE. trim(adjustl(
id2str(pao%parameterization)))) &
170 cpabort(
"Restart PAO parametrization does not match")
173 CALL match_kinds(pao, qs_env,
kinds, kindsmap)
174 nkinds =
SIZE(kindsmap)
175 natoms =
SIZE(positions, 1)
179 CALL para_env%bcast(nkinds)
180 CALL para_env%bcast(natoms)
181 IF (.NOT. para_env%is_source())
THEN
182 ALLOCATE (hmat(3, 3))
183 ALLOCATE (kindsmap(nkinds))
184 ALLOCATE (positions(natoms, 3))
185 ALLOCATE (atom2kind(natoms))
187 CALL para_env%bcast(hmat)
188 CALL para_env%bcast(kindsmap)
189 CALL para_env%bcast(atom2kind)
190 CALL para_env%bcast(positions)
191 CALL para_env%bcast(ml_range)
193 IF (ml_range(1) /= 1 .OR. ml_range(2) /= natoms)
THEN
194 cpwarn(
"Skipping some atoms for PAO-ML training.")
201 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, qs_kind_set=qs_kind_set)
202 ALLOCATE (my_particle_set(natoms))
204 ikind = kindsmap(atom2kind(iatom))
205 my_particle_set(iatom)%atomic_kind => atomic_kind_set(ikind)
206 my_particle_set(iatom)%r = positions(iatom, :)
214 IF (iatom < ml_range(1) .OR. ml_range(2) < iatom) cycle
218 IF (mod(iatom - 1, para_env%num_pe) == para_env%mepos)
THEN
224 descriptor=new_point%input)
228 IF (para_env%is_source())
THEN
229 nparams =
SIZE(xblocks(iatom)%p, 1)
230 ALLOCATE (new_point%output(nparams))
231 new_point%output(:) = xblocks(iatom)%p(:, 1)
235 ikind = kindsmap(atom2kind(iatom))
236 training_lists(ikind)%npoints = training_lists(ikind)%npoints + 1
237 new_point%next => training_lists(ikind)%head
238 training_lists(ikind)%head => new_point
241 DEALLOCATE (cell, my_particle_set, hmat, kindsmap, positions, atom2kind)
243 END SUBROUTINE add_to_training_list
252 SUBROUTINE match_kinds(pao, qs_env, kinds, kindsmap)
256 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: kindsmap
258 CHARACTER(LEN=default_string_length) :: name
259 INTEGER :: ikind, jkind
262 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set)
264 cpassert(.NOT.
ALLOCATED(kindsmap))
265 ALLOCATE (kindsmap(
SIZE(
kinds)))
268 DO ikind = 1,
SIZE(
kinds)
269 DO jkind = 1,
SIZE(atomic_kind_set)
272 IF (trim(
kinds(ikind)%name) .EQ. trim(name))
THEN
274 kindsmap(ikind) = jkind
280 IF (any(kindsmap < 1)) &
281 cpabort(
"PAO: Could not match all kinds from training set")
282 END SUBROUTINE match_kinds
289 SUBROUTINE sanity_check(qs_env, training_lists)
291 TYPE(training_list_type),
DIMENSION(:),
TARGET :: training_lists
293 INTEGER :: ikind, pao_basis_size
295 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
296 TYPE(training_list_type),
POINTER :: training_list
298 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set)
300 DO ikind = 1,
SIZE(training_lists)
301 training_list => training_lists(ikind)
302 IF (training_list%npoints > 0) cycle
303 CALL get_qs_kind(qs_kind_set(ikind), basis_set=basis_set, pao_basis_size=pao_basis_size)
304 IF (pao_basis_size /= basis_set%nsgf) &
305 cpabort(
"Found no training-points for kind: "//trim(training_list%kindname))
308 END SUBROUTINE sanity_check
316 SUBROUTINE training_list2matrix(training_lists, training_matrices, para_env)
317 TYPE(training_list_type),
ALLOCATABLE, &
318 DIMENSION(:),
TARGET :: training_lists
320 DIMENSION(:),
TARGET :: training_matrices
323 INTEGER :: i, ikind, inp_size, ninputs, noutputs, &
325 TYPE(training_list_type),
POINTER :: training_list
327 TYPE(training_point_type),
POINTER :: cur_point, prev_point
329 cpassert(
ALLOCATED(training_lists) .AND. .NOT.
ALLOCATED(training_matrices))
331 ALLOCATE (training_matrices(
SIZE(training_lists)))
333 DO ikind = 1,
SIZE(training_lists)
334 training_list => training_lists(ikind)
335 training_matrix => training_matrices(ikind)
336 training_matrix%kindname = training_list%kindname
337 npoints = training_list%npoints
338 IF (npoints == 0)
THEN
339 ALLOCATE (training_matrix%inputs(0, 0))
340 ALLOCATE (training_matrix%outputs(0, 0))
345 inp_size = 0; out_size = 0
346 IF (
ALLOCATED(training_list%head%input)) &
347 inp_size =
SIZE(training_list%head%input)
348 IF (
ALLOCATED(training_list%head%output)) &
349 out_size =
SIZE(training_list%head%output)
350 CALL para_env%sum(inp_size)
351 CALL para_env%sum(out_size)
354 ALLOCATE (training_matrix%inputs(inp_size, npoints))
355 ALLOCATE (training_matrix%outputs(out_size, npoints))
356 training_matrix%inputs(:, :) = 0.0_dp
357 training_matrix%outputs(:, :) = 0.0_dp
360 ninputs = 0; noutputs = 0
361 cur_point => training_list%head
362 NULLIFY (training_list%head)
364 IF (
ALLOCATED(cur_point%input))
THEN
365 training_matrix%inputs(:, i) = cur_point%input(:)
366 ninputs = ninputs + 1
368 IF (
ALLOCATED(cur_point%output))
THEN
369 training_matrix%outputs(:, i) = cur_point%output(:)
370 noutputs = noutputs + 1
373 prev_point => cur_point
374 cur_point => cur_point%next
375 DEALLOCATE (prev_point)
377 training_list%npoints = 0
380 CALL para_env%sum(training_matrix%inputs)
381 CALL para_env%sum(training_matrix%outputs)
384 CALL para_env%sum(noutputs)
385 CALL para_env%sum(ninputs)
386 cpassert(noutputs == npoints .AND. ninputs == npoints)
389 END SUBROUTINE training_list2matrix
396 SUBROUTINE pao_ml_substract_prior(ml_prior, training_matrices)
397 INTEGER,
INTENT(IN) :: ml_prior
400 INTEGER :: i, ikind, npoints, out_size
403 DO ikind = 1,
SIZE(training_matrices)
404 training_matrix => training_matrices(ikind)
405 out_size =
SIZE(training_matrix%outputs, 1)
406 npoints =
SIZE(training_matrix%outputs, 2)
407 IF (npoints == 0) cycle
408 ALLOCATE (training_matrix%prior(out_size))
411 SELECT CASE (ml_prior)
413 training_matrix%prior(:) = 0.0_dp
415 training_matrix%prior(:) = sum(training_matrix%outputs, 2)/real(npoints,
dp)
417 cpabort(
"PAO: unknown prior")
422 training_matrix%outputs(:, i) = training_matrix%outputs(:, i) - training_matrix%prior
426 END SUBROUTINE pao_ml_substract_prior
433 SUBROUTINE pao_ml_print(pao, training_matrices)
437 INTEGER :: i, ikind, n, npoints
441 IF (pao%iw_mldata > 0)
THEN
442 DO ikind = 1,
SIZE(training_matrices)
443 training_matrix => training_matrices(ikind)
444 npoints =
SIZE(training_matrix%outputs, 2)
446 WRITE (pao%iw_mldata, *)
"PAO|ML| training-point kind: ", trim(training_matrix%kindname), &
447 " point:", i,
" in:", training_matrix%inputs(:, i), &
448 " out:", training_matrix%outputs(:, i)
456 DO ikind = 1,
SIZE(training_matrices)
457 training_matrix => training_matrices(ikind)
458 n =
SIZE(training_matrix%inputs)
460 WRITE (pao%iw,
"(A,I3,A,E10.1,1X,E10.1,1X,E10.1)")
" PAO|ML| Descriptor for kind: "// &
461 trim(training_matrix%kindname)//
" size: ", &
462 SIZE(training_matrix%inputs, 1),
" min/mean/max: ", &
463 minval(training_matrix%inputs), &
464 sum(training_matrix%inputs)/real(n,
dp), &
465 maxval(training_matrix%inputs)
469 END SUBROUTINE pao_ml_print
475 SUBROUTINE pao_ml_train(pao)
478 CHARACTER(len=*),
PARAMETER :: routinen =
'pao_ml_train'
482 CALL timeset(routinen, handle)
484 SELECT CASE (pao%ml_method)
492 cpabort(
"PAO: unknown machine learning scheme")
495 CALL timestop(handle)
497 END SUBROUTINE pao_ml_train
508 CHARACTER(len=*),
PARAMETER :: routinen =
'pao_ml_predict'
510 INTEGER :: acol, arow, handle, iatom, ikind, natoms
511 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: descriptor, variances
512 REAL(
dp),
DIMENSION(:, :),
POINTER :: block_x
518 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
520 CALL timeset(routinen, handle)
525 particle_set=particle_set, &
526 atomic_kind_set=atomic_kind_set, &
527 qs_kind_set=qs_kind_set, &
531 ALLOCATE (variances(natoms))
532 variances(:) = 0.0_dp
538 iatom = arow; cpassert(arow == acol)
539 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
540 IF (
SIZE(block_x) == 0) cycle
551 CALL pao_ml_predict_low(pao, ikind=ikind, &
552 descriptor=descriptor, &
553 output=block_x(:, 1), &
554 variance=variances(iatom))
556 DEALLOCATE (descriptor)
559 block_x(:, 1) = block_x(:, 1) + pao%ml_training_matrices(ikind)%prior
565 CALL para_env%sum(variances)
566 IF (pao%iw_mlvar > 0)
THEN
568 WRITE (pao%iw_mlvar, *)
"PAO|ML| atom:", iatom,
" prediction variance:", variances(iatom)
574 IF (pao%iw > 0)
WRITE (pao%iw,
"(A,E20.10,A,T71,I10)")
" PAO|ML| max prediction variance:", &
575 maxval(variances),
" for atom:", maxloc(variances)
577 IF (maxval(variances) > pao%ml_tolerance) &
578 cpabort(
"Variance of prediction above ML_TOLERANCE.")
580 DEALLOCATE (variances)
582 CALL timestop(handle)
594 SUBROUTINE pao_ml_predict_low(pao, ikind, descriptor, output, variance)
596 INTEGER,
INTENT(IN) :: ikind
597 REAL(
dp),
DIMENSION(:),
INTENT(IN) :: descriptor
598 REAL(
dp),
DIMENSION(:),
INTENT(OUT) :: output
599 REAL(
dp),
INTENT(OUT) :: variance
601 SELECT CASE (pao%ml_method)
610 cpabort(
"PAO: unknown machine learning scheme")
613 END SUBROUTINE pao_ml_predict_low
626 REAL(
dp),
DIMENSION(:, :),
INTENT(INOUT) :: forces
628 CHARACTER(len=*),
PARAMETER :: routinen =
'pao_ml_forces'
630 INTEGER :: acol, arow, handle, iatom, ikind
631 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: descr_grad, descriptor
632 REAL(
dp),
DIMENSION(:, :),
POINTER :: block_g
638 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
640 CALL timeset(routinen, handle)
645 particle_set=particle_set, &
646 atomic_kind_set=atomic_kind_set, &
647 qs_kind_set=qs_kind_set)
655 iatom = arow; cpassert(arow == acol)
656 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
657 IF (
SIZE(block_g) == 0) cycle
665 descriptor=descriptor)
668 CALL pao_ml_gradient_low(pao, ikind=ikind, &
669 descriptor=descriptor, &
670 outer_deriv=block_g(:, 1), &
679 descr_grad=descr_grad, &
682 DEALLOCATE (descriptor, descr_grad)
687 CALL timestop(handle)
699 SUBROUTINE pao_ml_gradient_low(pao, ikind, descriptor, outer_deriv, gradient)
701 INTEGER,
INTENT(IN) :: ikind
702 REAL(
dp),
DIMENSION(:),
INTENT(IN) :: descriptor, outer_deriv
703 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: gradient
705 ALLOCATE (gradient(
SIZE(descriptor)))
707 SELECT CASE (pao%ml_method)
715 cpabort(
"PAO: unknown machine learning scheme")
718 END SUBROUTINE pao_ml_gradient_low
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
Handles all functions related to the CELL.
subroutine, public cell_create(cell, hmat, periodic, tag)
allocates and initializes a cell
Handles all functions related to the CELL.
subroutine, public dbcsr_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset)
...
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
subroutine, public dbcsr_iterator_start(iterator, matrix, shared, dynamic, dynamic_byrows)
...
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
integer, parameter, public default_path_length
Machine interface based on Fortran 2003 and POSIX.
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Interface to the message passing library MPI.
Routines for reading and writing restart files.
subroutine, public pao_kinds_ensure_equal(pao, qs_env, ikind, pao_kind)
Ensure that the kind read from the restart is equal to the kind curretly in use.
subroutine, public pao_read_raw(filename, param, hmat, kinds, atom2kind, positions, xblocks, ml_range)
Reads a restart file into temporary datastructures.
Feature vectors for describing chemical environments in a rotationally invariant fashion.
subroutine, public pao_ml_calc_descriptor(pao, particle_set, qs_kind_set, cell, iatom, descriptor, descr_grad, forces)
Calculates a descriptor for chemical environment of given atom.
Gaussian Process implementation.
subroutine, public pao_ml_gp_gradient(pao, ikind, descriptor, outer_deriv, gradient)
Calculate gradient of Gaussian process.
subroutine, public pao_ml_gp_train(pao)
Builds the covariance matrix.
subroutine, public pao_ml_gp_predict(pao, ikind, descriptor, output, variance)
Uses covariance matrix to make prediction.
Neural Network implementation.
subroutine, public pao_ml_nn_gradient(pao, ikind, descriptor, outer_deriv, gradient)
Calculate gradient of neural network.
subroutine, public pao_ml_nn_train(pao)
Trains the neural network on given training points.
subroutine, public pao_ml_nn_predict(pao, ikind, descriptor, output, variance)
Uses neural network to make a prediction.
Main module for PAO Machine Learning.
subroutine, public pao_ml_forces(pao, qs_env, matrix_g, forces)
Calculate forces contributed by machine learning.
subroutine, public pao_ml_init(pao, qs_env)
Initializes the learning machinery.
subroutine, public pao_ml_predict(pao, qs_env)
Fills paomatrix_X based on machine learning predictions.
Types used by the PAO machinery.
Define the data structure for the particle information.
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs)
Get the QUICKSTEP environment.
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, init_u_ramping_each_scf, reltmat, ghost, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.