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")
102 CALL get_qs_env(qs_env, para_env=para_env, atomic_kind_set=atomic_kind_set)
105 ALLOCATE (training_lists(
SIZE(atomic_kind_set)))
106 DO i = 1,
SIZE(training_lists)
107 CALL get_atomic_kind(atomic_kind_set(i), name=training_lists(i)%kindname)
111 DO i = 1,
SIZE(pao%ml_training_set)
112 CALL add_to_training_list(pao, qs_env, training_lists, filename=pao%ml_training_set(i)%fn)
116 CALL sanity_check(qs_env, training_lists)
119 CALL training_list2matrix(training_lists, pao%ml_training_matrices, para_env)
122 CALL pao_ml_substract_prior(pao%ml_prior, pao%ml_training_matrices)
125 CALL pao_ml_print(pao, pao%ml_training_matrices)
128 CALL pao_ml_train(pao)
139 SUBROUTINE add_to_training_list(pao, qs_env, training_lists, filename)
142 TYPE(training_list_type),
DIMENSION(:) :: training_lists
143 CHARACTER(LEN=default_path_length) :: filename
145 CHARACTER(LEN=default_string_length) :: param
146 INTEGER :: iatom, ikind, natoms, nkinds, nparams
147 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: atom2kind, kindsmap
148 INTEGER,
DIMENSION(2) :: ml_range
149 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: hmat, positions
155 TYPE(
particle_type),
DIMENSION(:),
POINTER :: my_particle_set
156 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
157 TYPE(training_point_type),
POINTER :: new_point
159 NULLIFY (new_point, cell)
161 IF (pao%iw > 0)
WRITE (pao%iw,
'(A,A)')
" PAO|ML| Reading training frame from file: ", trim(filename)
166 IF (para_env%is_source())
THEN
167 CALL pao_read_raw(filename, param, hmat,
kinds, atom2kind, positions, xblocks, ml_range)
170 IF (trim(param) /= trim(adjustl(
id2str(pao%parameterization))))
THEN
171 cpabort(
"Restart PAO parametrization does not match")
175 CALL match_kinds(pao, qs_env,
kinds, kindsmap)
176 nkinds =
SIZE(kindsmap)
177 natoms =
SIZE(positions, 1)
181 CALL para_env%bcast(nkinds)
182 CALL para_env%bcast(natoms)
183 IF (.NOT. para_env%is_source())
THEN
184 ALLOCATE (hmat(3, 3))
185 ALLOCATE (kindsmap(nkinds))
186 ALLOCATE (positions(natoms, 3))
187 ALLOCATE (atom2kind(natoms))
189 CALL para_env%bcast(hmat)
190 CALL para_env%bcast(kindsmap)
191 CALL para_env%bcast(atom2kind)
192 CALL para_env%bcast(positions)
193 CALL para_env%bcast(ml_range)
195 IF (ml_range(1) /= 1 .OR. ml_range(2) /= natoms)
THEN
196 cpwarn(
"Skipping some atoms for PAO-ML training.")
203 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, qs_kind_set=qs_kind_set)
204 ALLOCATE (my_particle_set(natoms))
206 ikind = kindsmap(atom2kind(iatom))
207 my_particle_set(iatom)%atomic_kind => atomic_kind_set(ikind)
208 my_particle_set(iatom)%r = positions(iatom, :)
216 IF (iatom < ml_range(1) .OR. ml_range(2) < iatom) cycle
220 IF (mod(iatom - 1, para_env%num_pe) == para_env%mepos)
THEN
226 descriptor=new_point%input)
230 IF (para_env%is_source())
THEN
231 nparams =
SIZE(xblocks(iatom)%p, 1)
232 ALLOCATE (new_point%output(nparams))
233 new_point%output(:) = xblocks(iatom)%p(:, 1)
237 ikind = kindsmap(atom2kind(iatom))
238 training_lists(ikind)%npoints = training_lists(ikind)%npoints + 1
239 new_point%next => training_lists(ikind)%head
240 training_lists(ikind)%head => new_point
243 DEALLOCATE (cell, my_particle_set, hmat, kindsmap, positions, atom2kind)
245 END SUBROUTINE add_to_training_list
254 SUBROUTINE match_kinds(pao, qs_env, kinds, kindsmap)
258 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: kindsmap
260 CHARACTER(LEN=default_string_length) :: name
261 INTEGER :: ikind, jkind
264 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set)
266 cpassert(.NOT.
ALLOCATED(kindsmap))
267 ALLOCATE (kindsmap(
SIZE(
kinds)))
270 DO ikind = 1,
SIZE(
kinds)
271 DO jkind = 1,
SIZE(atomic_kind_set)
274 IF (trim(
kinds(ikind)%name) == trim(name))
THEN
276 kindsmap(ikind) = jkind
282 IF (any(kindsmap < 1))
THEN
283 cpabort(
"PAO: Could not match all kinds from training set")
285 END SUBROUTINE match_kinds
292 SUBROUTINE sanity_check(qs_env, training_lists)
294 TYPE(training_list_type),
DIMENSION(:),
TARGET :: training_lists
296 INTEGER :: ikind, pao_basis_size
298 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
299 TYPE(training_list_type),
POINTER :: training_list
301 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set)
303 DO ikind = 1,
SIZE(training_lists)
304 training_list => training_lists(ikind)
305 IF (training_list%npoints > 0) cycle
306 CALL get_qs_kind(qs_kind_set(ikind), basis_set=basis_set, pao_basis_size=pao_basis_size)
307 IF (pao_basis_size /= basis_set%nsgf)
THEN
309 cpabort(
"Found no training-points for kind: "//trim(training_list%kindname))
313 END SUBROUTINE sanity_check
321 SUBROUTINE training_list2matrix(training_lists, training_matrices, para_env)
322 TYPE(training_list_type),
ALLOCATABLE, &
323 DIMENSION(:),
TARGET :: training_lists
325 DIMENSION(:),
TARGET :: training_matrices
328 INTEGER :: i, ikind, inp_size, ninputs, noutputs, &
330 TYPE(training_list_type),
POINTER :: training_list
332 TYPE(training_point_type),
POINTER :: cur_point, prev_point
334 cpassert(
ALLOCATED(training_lists) .AND. .NOT.
ALLOCATED(training_matrices))
336 ALLOCATE (training_matrices(
SIZE(training_lists)))
338 DO ikind = 1,
SIZE(training_lists)
339 training_list => training_lists(ikind)
340 training_matrix => training_matrices(ikind)
341 training_matrix%kindname = training_list%kindname
342 npoints = training_list%npoints
343 IF (npoints == 0)
THEN
344 ALLOCATE (training_matrix%inputs(0, 0))
345 ALLOCATE (training_matrix%outputs(0, 0))
350 inp_size = 0; out_size = 0
351 IF (
ALLOCATED(training_list%head%input))
THEN
352 inp_size =
SIZE(training_list%head%input)
354 IF (
ALLOCATED(training_list%head%output))
THEN
355 out_size =
SIZE(training_list%head%output)
357 CALL para_env%sum(inp_size)
358 CALL para_env%sum(out_size)
361 ALLOCATE (training_matrix%inputs(inp_size, npoints))
362 ALLOCATE (training_matrix%outputs(out_size, npoints))
363 training_matrix%inputs(:, :) = 0.0_dp
364 training_matrix%outputs(:, :) = 0.0_dp
367 ninputs = 0; noutputs = 0
368 cur_point => training_list%head
369 NULLIFY (training_list%head)
371 IF (
ALLOCATED(cur_point%input))
THEN
372 training_matrix%inputs(:, i) = cur_point%input(:)
373 ninputs = ninputs + 1
375 IF (
ALLOCATED(cur_point%output))
THEN
376 training_matrix%outputs(:, i) = cur_point%output(:)
377 noutputs = noutputs + 1
380 prev_point => cur_point
381 cur_point => cur_point%next
382 DEALLOCATE (prev_point)
384 training_list%npoints = 0
387 CALL para_env%sum(training_matrix%inputs)
388 CALL para_env%sum(training_matrix%outputs)
391 CALL para_env%sum(noutputs)
392 CALL para_env%sum(ninputs)
393 cpassert(noutputs == npoints .AND. ninputs == npoints)
396 END SUBROUTINE training_list2matrix
403 SUBROUTINE pao_ml_substract_prior(ml_prior, training_matrices)
404 INTEGER,
INTENT(IN) :: ml_prior
407 INTEGER :: i, ikind, npoints, out_size
410 DO ikind = 1,
SIZE(training_matrices)
411 training_matrix => training_matrices(ikind)
412 out_size =
SIZE(training_matrix%outputs, 1)
413 npoints =
SIZE(training_matrix%outputs, 2)
414 IF (npoints == 0) cycle
415 ALLOCATE (training_matrix%prior(out_size))
418 SELECT CASE (ml_prior)
420 training_matrix%prior(:) = 0.0_dp
422 training_matrix%prior(:) = sum(training_matrix%outputs, 2)/real(npoints,
dp)
424 cpabort(
"PAO: unknown prior")
429 training_matrix%outputs(:, i) = training_matrix%outputs(:, i) - training_matrix%prior
433 END SUBROUTINE pao_ml_substract_prior
440 SUBROUTINE pao_ml_print(pao, training_matrices)
444 INTEGER :: i, ikind, n, npoints
448 IF (pao%iw_mldata > 0)
THEN
449 DO ikind = 1,
SIZE(training_matrices)
450 training_matrix => training_matrices(ikind)
451 npoints =
SIZE(training_matrix%outputs, 2)
453 WRITE (pao%iw_mldata, *)
"PAO|ML| training-point kind: ", trim(training_matrix%kindname), &
454 " point:", i,
" in:", training_matrix%inputs(:, i), &
455 " out:", training_matrix%outputs(:, i)
463 DO ikind = 1,
SIZE(training_matrices)
464 training_matrix => training_matrices(ikind)
465 n =
SIZE(training_matrix%inputs)
467 WRITE (pao%iw,
"(A,I3,A,E10.1,1X,E10.1,1X,E10.1)")
" PAO|ML| Descriptor for kind: "// &
468 trim(training_matrix%kindname)//
" size: ", &
469 SIZE(training_matrix%inputs, 1),
" min/mean/max: ", &
470 minval(training_matrix%inputs), &
471 sum(training_matrix%inputs)/real(n,
dp), &
472 maxval(training_matrix%inputs)
476 END SUBROUTINE pao_ml_print
482 SUBROUTINE pao_ml_train(pao)
485 CHARACTER(len=*),
PARAMETER :: routinen =
'pao_ml_train'
489 CALL timeset(routinen, handle)
491 SELECT CASE (pao%ml_method)
499 cpabort(
"PAO: unknown machine learning scheme")
502 CALL timestop(handle)
504 END SUBROUTINE pao_ml_train
515 CHARACTER(len=*),
PARAMETER :: routinen =
'pao_ml_predict'
517 INTEGER :: acol, arow, handle, iatom, ikind, natoms
518 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: descriptor, variances
519 REAL(
dp),
DIMENSION(:, :),
POINTER :: block_x
525 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
527 CALL timeset(routinen, handle)
532 particle_set=particle_set, &
533 atomic_kind_set=atomic_kind_set, &
534 qs_kind_set=qs_kind_set, &
538 ALLOCATE (variances(natoms))
539 variances(:) = 0.0_dp
545 iatom = arow; cpassert(arow == acol)
546 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
547 IF (
SIZE(block_x) == 0) cycle
558 CALL pao_ml_predict_low(pao, ikind=ikind, &
559 descriptor=descriptor, &
560 output=block_x(:, 1), &
561 variance=variances(iatom))
563 DEALLOCATE (descriptor)
566 block_x(:, 1) = block_x(:, 1) + pao%ml_training_matrices(ikind)%prior
572 CALL para_env%sum(variances)
573 IF (pao%iw_mlvar > 0)
THEN
575 WRITE (pao%iw_mlvar, *)
"PAO|ML| atom:", iatom,
" prediction variance:", variances(iatom)
581 IF (pao%iw > 0)
WRITE (pao%iw,
"(A,E20.10,A,T71,I10)")
" PAO|ML| max prediction variance:", &
582 maxval(variances),
" for atom:", maxloc(variances)
584 IF (maxval(variances) > pao%ml_tolerance)
THEN
585 cpabort(
"Variance of prediction above ML_TOLERANCE.")
588 DEALLOCATE (variances)
590 CALL timestop(handle)
602 SUBROUTINE pao_ml_predict_low(pao, ikind, descriptor, output, variance)
604 INTEGER,
INTENT(IN) :: ikind
605 REAL(
dp),
DIMENSION(:),
INTENT(IN) :: descriptor
606 REAL(
dp),
DIMENSION(:),
INTENT(OUT) :: output
607 REAL(
dp),
INTENT(OUT) :: variance
609 SELECT CASE (pao%ml_method)
618 cpabort(
"PAO: unknown machine learning scheme")
621 END SUBROUTINE pao_ml_predict_low
634 REAL(
dp),
DIMENSION(:, :),
INTENT(INOUT) :: forces
636 CHARACTER(len=*),
PARAMETER :: routinen =
'pao_ml_forces'
638 INTEGER :: acol, arow, handle, iatom, ikind
639 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: descr_grad, descriptor
640 REAL(
dp),
DIMENSION(:, :),
POINTER :: block_g
646 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
648 CALL timeset(routinen, handle)
653 particle_set=particle_set, &
654 atomic_kind_set=atomic_kind_set, &
655 qs_kind_set=qs_kind_set)
663 iatom = arow; cpassert(arow == acol)
664 CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
665 IF (
SIZE(block_g) == 0) cycle
673 descriptor=descriptor)
676 CALL pao_ml_gradient_low(pao, ikind=ikind, &
677 descriptor=descriptor, &
678 outer_deriv=block_g(:, 1), &
687 descr_grad=descr_grad, &
690 DEALLOCATE (descriptor, descr_grad)
695 CALL timestop(handle)
707 SUBROUTINE pao_ml_gradient_low(pao, ikind, descriptor, outer_deriv, gradient)
709 INTEGER,
INTENT(IN) :: ikind
710 REAL(
dp),
DIMENSION(:),
INTENT(IN) :: descriptor, outer_deriv
711 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: gradient
713 ALLOCATE (gradient(
SIZE(descriptor)))
715 SELECT CASE (pao%ml_method)
723 cpabort(
"PAO: unknown machine learning scheme")
726 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.
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
subroutine, public dbcsr_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset, transposed)
...
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, mimic, 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, sab_cneo, 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, matrix_vhxc, 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, xcint_weights, 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, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_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, do_rixs, tb_tblite)
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, cneo_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, hund_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, proj_shell_charge, lr_atom, do_mtlr, u_j_loop, ao_coef, init_u_ramping_each_scf, reltmat, ghost, monovalent, 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.