(git:98357aa)
Loading...
Searching...
No Matches
pao_ml.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Main module for PAO Machine Learning
10!> \author Ole Schuett
11! **************************************************************************************************
12MODULE pao_ml
16 USE cell_methods, ONLY: cell_create
17 USE cell_types, ONLY: cell_type
24 USE kinds, ONLY: default_path_length,&
26 dp
27 USE machine, ONLY: m_flush
29 USE pao_input, ONLY: id2str,&
30 pao_ml_gp,&
32 pao_ml_nn,&
36 USE pao_io, ONLY: pao_ioblock_type,&
47 USE pao_types, ONLY: pao_env_type,&
52 USE qs_kind_types, ONLY: get_qs_kind,&
54#include "./base/base_uses.f90"
55
56 IMPLICIT NONE
57
58 PRIVATE
59
60 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'pao_ml'
61
63
64 ! linked list used to group training points by kind
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
70
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
76
77CONTAINS
78
79! **************************************************************************************************
80!> \brief Initializes the learning machinery
81!> \param pao ...
82!> \param qs_env ...
83! **************************************************************************************************
84 SUBROUTINE pao_ml_init(pao, qs_env)
85 TYPE(pao_env_type), POINTER :: pao
86 TYPE(qs_environment_type), POINTER :: qs_env
87
88 INTEGER :: i
89 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
90 TYPE(mp_para_env_type), POINTER :: para_env
91 TYPE(training_list_type), ALLOCATABLE, &
92 DIMENSION(:) :: training_lists
93
94 IF (SIZE(pao%ml_training_set) == 0) RETURN
95
96 IF (pao%iw > 0) WRITE (pao%iw, *) 'PAO|ML| Initializing maschine learning...'
97
98 IF (pao%parameterization /= pao_rotinv_param) THEN
99 cpabort("PAO maschine learning requires ROTINV parametrization")
100 END IF
101
102 CALL get_qs_env(qs_env, para_env=para_env, atomic_kind_set=atomic_kind_set)
103
104 ! create training-set data-structure
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)
108 END DO
109
110 ! parses training files, calculates descriptors and stores all training-points as linked lists
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)
113 END DO
114
115 ! ensure there there are training points for all kinds that use pao
116 CALL sanity_check(qs_env, training_lists)
117
118 ! turns linked lists into matrices and syncs them across ranks
119 CALL training_list2matrix(training_lists, pao%ml_training_matrices, para_env)
120
121 ! calculate and subtract prior
122 CALL pao_ml_substract_prior(pao%ml_prior, pao%ml_training_matrices)
123
124 ! print some statistics about the training set and dump it upon request
125 CALL pao_ml_print(pao, pao%ml_training_matrices)
126
127 ! use training-set to train model
128 CALL pao_ml_train(pao)
129
130 END SUBROUTINE pao_ml_init
131
132! **************************************************************************************************
133!> \brief Reads the given file and adds its training points to linked lists.
134!> \param pao ...
135!> \param qs_env ...
136!> \param training_lists ...
137!> \param filename ...
138! **************************************************************************************************
139 SUBROUTINE add_to_training_list(pao, qs_env, training_lists, filename)
140 TYPE(pao_env_type), POINTER :: pao
141 TYPE(qs_environment_type), POINTER :: qs_env
142 TYPE(training_list_type), DIMENSION(:) :: training_lists
143 CHARACTER(LEN=default_path_length) :: filename
144
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
150 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
151 TYPE(cell_type), POINTER :: cell
152 TYPE(mp_para_env_type), POINTER :: para_env
153 TYPE(pao_ioblock_type), ALLOCATABLE, DIMENSION(:) :: xblocks
154 TYPE(pao_iokind_type), ALLOCATABLE, DIMENSION(:) :: kinds
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
158
159 NULLIFY (new_point, cell)
160
161 IF (pao%iw > 0) WRITE (pao%iw, '(A,A)') " PAO|ML| Reading training frame from file: ", trim(filename)
162
163 CALL get_qs_env(qs_env, para_env=para_env)
164
165 ! parse training data on first rank
166 IF (para_env%is_source()) THEN
167 CALL pao_read_raw(filename, param, hmat, kinds, atom2kind, positions, xblocks, ml_range)
168
169 ! check parametrization
170 IF (trim(param) /= trim(adjustl(id2str(pao%parameterization)))) THEN
171 cpabort("Restart PAO parametrization does not match")
172 END IF
173
174 ! map read-in kinds onto kinds of this run
175 CALL match_kinds(pao, qs_env, kinds, kindsmap)
176 nkinds = SIZE(kindsmap)
177 natoms = SIZE(positions, 1)
178 END IF
179
180 ! broadcast parsed raw training data
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))
188 END IF
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)
194
195 IF (ml_range(1) /= 1 .OR. ml_range(2) /= natoms) THEN
196 cpwarn("Skipping some atoms for PAO-ML training.")
197 END IF
198
199 ! create cell from read-in h-matrix
200 CALL cell_create(cell, hmat)
201
202 ! create a particle_set based on read-in positions and refere to kinds of this run
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))
205 DO iatom = 1, 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, :)
209 END DO
210
211 ! fill linked list with training points
212 ! Afterwards all ranks will have lists with the same number of entries,
213 ! however the input and output arrays will only be allocated on one rank per entry.
214 ! We farm out the expensive calculation of the descriptor across ranks.
215 DO iatom = 1, natoms
216 IF (iatom < ml_range(1) .OR. ml_range(2) < iatom) cycle
217 ALLOCATE (new_point)
218
219 ! training-point input, calculate descriptor only on one rank
220 IF (mod(iatom - 1, para_env%num_pe) == para_env%mepos) THEN
221 CALL pao_ml_calc_descriptor(pao, &
222 my_particle_set, &
223 qs_kind_set, &
224 cell, &
225 iatom=iatom, &
226 descriptor=new_point%input)
227 END IF
228
229 ! copy training-point output on first rank
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)
234 END IF
235
236 ! add to linked list
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
241 END DO
242
243 DEALLOCATE (cell, my_particle_set, hmat, kindsmap, positions, atom2kind)
244
245 END SUBROUTINE add_to_training_list
246
247! **************************************************************************************************
248!> \brief Make read-in kinds on to atomic-kinds of this run
249!> \param pao ...
250!> \param qs_env ...
251!> \param kinds ...
252!> \param kindsmap ...
253! **************************************************************************************************
254 SUBROUTINE match_kinds(pao, qs_env, kinds, kindsmap)
255 TYPE(pao_env_type), POINTER :: pao
256 TYPE(qs_environment_type), POINTER :: qs_env
257 TYPE(pao_iokind_type), DIMENSION(:) :: kinds
258 INTEGER, ALLOCATABLE, DIMENSION(:) :: kindsmap
259
260 CHARACTER(LEN=default_string_length) :: name
261 INTEGER :: ikind, jkind
262 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
263
264 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set)
265
266 cpassert(.NOT. ALLOCATED(kindsmap))
267 ALLOCATE (kindsmap(SIZE(kinds)))
268 kindsmap(:) = -1
269
270 DO ikind = 1, SIZE(kinds)
271 DO jkind = 1, SIZE(atomic_kind_set)
272 CALL get_atomic_kind(atomic_kind_set(jkind), name=name)
273 ! match kinds via their name
274 IF (trim(kinds(ikind)%name) == trim(name)) THEN
275 CALL pao_kinds_ensure_equal(pao, qs_env, jkind, kinds(ikind))
276 kindsmap(ikind) = jkind
277 EXIT
278 END IF
279 END DO
280 END DO
281
282 IF (any(kindsmap < 1)) THEN
283 cpabort("PAO: Could not match all kinds from training set")
284 END IF
285 END SUBROUTINE match_kinds
286
287! **************************************************************************************************
288!> \brief Checks that there is at least one training point per pao-enabled kind
289!> \param qs_env ...
290!> \param training_lists ...
291! **************************************************************************************************
292 SUBROUTINE sanity_check(qs_env, training_lists)
293 TYPE(qs_environment_type), POINTER :: qs_env
294 TYPE(training_list_type), DIMENSION(:), TARGET :: training_lists
295
296 INTEGER :: ikind, pao_basis_size
297 TYPE(gto_basis_set_type), POINTER :: basis_set
298 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
299 TYPE(training_list_type), POINTER :: training_list
300
301 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set)
302
303 DO ikind = 1, SIZE(training_lists)
304 training_list => training_lists(ikind)
305 IF (training_list%npoints > 0) cycle ! it's ok
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
308 ! if this kind has pao enabled...
309 cpabort("Found no training-points for kind: "//trim(training_list%kindname))
310 END IF
311 END DO
312
313 END SUBROUTINE sanity_check
314
315! **************************************************************************************************
316!> \brief Turns the linked lists of training points into matrices
317!> \param training_lists ...
318!> \param training_matrices ...
319!> \param para_env ...
320! **************************************************************************************************
321 SUBROUTINE training_list2matrix(training_lists, training_matrices, para_env)
322 TYPE(training_list_type), ALLOCATABLE, &
323 DIMENSION(:), TARGET :: training_lists
324 TYPE(training_matrix_type), ALLOCATABLE, &
325 DIMENSION(:), TARGET :: training_matrices
326 TYPE(mp_para_env_type), POINTER :: para_env
327
328 INTEGER :: i, ikind, inp_size, ninputs, noutputs, &
329 npoints, out_size
330 TYPE(training_list_type), POINTER :: training_list
331 TYPE(training_matrix_type), POINTER :: training_matrix
332 TYPE(training_point_type), POINTER :: cur_point, prev_point
333
334 cpassert(ALLOCATED(training_lists) .AND. .NOT. ALLOCATED(training_matrices))
335
336 ALLOCATE (training_matrices(SIZE(training_lists)))
337
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 ! copy kindname
342 npoints = training_list%npoints ! number of points
343 IF (npoints == 0) THEN
344 ALLOCATE (training_matrix%inputs(0, 0))
345 ALLOCATE (training_matrix%outputs(0, 0))
346 cycle
347 END IF
348
349 ! figure out size of input and output
350 inp_size = 0; out_size = 0
351 IF (ALLOCATED(training_list%head%input)) THEN
352 inp_size = SIZE(training_list%head%input)
353 END IF
354 IF (ALLOCATED(training_list%head%output)) THEN
355 out_size = SIZE(training_list%head%output)
356 END IF
357 CALL para_env%sum(inp_size)
358 CALL para_env%sum(out_size)
359
360 ! allocate matices to hold all training points
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
365
366 ! loop over all training points, consume linked-list in the process
367 ninputs = 0; noutputs = 0
368 cur_point => training_list%head
369 NULLIFY (training_list%head)
370 DO i = 1, npoints
371 IF (ALLOCATED(cur_point%input)) THEN
372 training_matrix%inputs(:, i) = cur_point%input(:)
373 ninputs = ninputs + 1
374 END IF
375 IF (ALLOCATED(cur_point%output)) THEN
376 training_matrix%outputs(:, i) = cur_point%output(:)
377 noutputs = noutputs + 1
378 END IF
379 ! advance to next entry and deallocate the current one
380 prev_point => cur_point
381 cur_point => cur_point%next
382 DEALLOCATE (prev_point)
383 END DO
384 training_list%npoints = 0 ! list is now empty
385
386 ! sync training_matrix across ranks
387 CALL para_env%sum(training_matrix%inputs)
388 CALL para_env%sum(training_matrix%outputs)
389
390 ! sanity check
391 CALL para_env%sum(noutputs)
392 CALL para_env%sum(ninputs)
393 cpassert(noutputs == npoints .AND. ninputs == npoints)
394 END DO
395
396 END SUBROUTINE training_list2matrix
397
398! **************************************************************************************************
399!> \brief TODO
400!> \param ml_prior ...
401!> \param training_matrices ...
402! **************************************************************************************************
403 SUBROUTINE pao_ml_substract_prior(ml_prior, training_matrices)
404 INTEGER, INTENT(IN) :: ml_prior
405 TYPE(training_matrix_type), DIMENSION(:), TARGET :: training_matrices
406
407 INTEGER :: i, ikind, npoints, out_size
408 TYPE(training_matrix_type), POINTER :: training_matrix
409
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))
416
417 ! calculate prior
418 SELECT CASE (ml_prior)
419 CASE (pao_ml_prior_zero)
420 training_matrix%prior(:) = 0.0_dp
421 CASE (pao_ml_prior_mean)
422 training_matrix%prior(:) = sum(training_matrix%outputs, 2)/real(npoints, dp)
423 CASE DEFAULT
424 cpabort("PAO: unknown prior")
425 END SELECT
426
427 ! subtract prior from all training points
428 DO i = 1, npoints
429 training_matrix%outputs(:, i) = training_matrix%outputs(:, i) - training_matrix%prior
430 END DO
431 END DO
432
433 END SUBROUTINE pao_ml_substract_prior
434
435! **************************************************************************************************
436!> \brief Print some statistics about the training set and dump it upon request
437!> \param pao ...
438!> \param training_matrices ...
439! **************************************************************************************************
440 SUBROUTINE pao_ml_print(pao, training_matrices)
441 TYPE(pao_env_type), POINTER :: pao
442 TYPE(training_matrix_type), DIMENSION(:), TARGET :: training_matrices
443
444 INTEGER :: i, ikind, n, npoints
445 TYPE(training_matrix_type), POINTER :: training_matrix
446
447 ! dump training data
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)
452 DO i = 1, npoints
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)
456 END DO
457 END DO
458 CALL m_flush(pao%iw_mldata)
459 END IF
460
461 ! print stats
462 IF (pao%iw > 0) THEN
463 DO ikind = 1, SIZE(training_matrices)
464 training_matrix => training_matrices(ikind)
465 n = SIZE(training_matrix%inputs)
466 IF (n == 0) cycle
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)
473 END DO
474 END IF
475
476 END SUBROUTINE pao_ml_print
477
478! **************************************************************************************************
479!> \brief Calls the actual learning algorthim to traing on the given matrices
480!> \param pao ...
481! **************************************************************************************************
482 SUBROUTINE pao_ml_train(pao)
483 TYPE(pao_env_type), POINTER :: pao
484
485 CHARACTER(len=*), PARAMETER :: routinen = 'pao_ml_train'
486
487 INTEGER :: handle
488
489 CALL timeset(routinen, handle)
490
491 SELECT CASE (pao%ml_method)
492 CASE (pao_ml_gp)
493 CALL pao_ml_gp_train(pao)
494 CASE (pao_ml_nn)
495 CALL pao_ml_nn_train(pao)
496 CASE (pao_ml_lazy)
497 ! nothing to do
498 CASE DEFAULT
499 cpabort("PAO: unknown machine learning scheme")
500 END SELECT
501
502 CALL timestop(handle)
503
504 END SUBROUTINE pao_ml_train
505
506! **************************************************************************************************
507!> \brief Fills pao%matrix_X based on machine learning predictions
508!> \param pao ...
509!> \param qs_env ...
510! **************************************************************************************************
511 SUBROUTINE pao_ml_predict(pao, qs_env)
512 TYPE(pao_env_type), POINTER :: pao
513 TYPE(qs_environment_type), POINTER :: qs_env
514
515 CHARACTER(len=*), PARAMETER :: routinen = 'pao_ml_predict'
516
517 INTEGER :: acol, arow, handle, iatom, ikind, natoms
518 REAL(dp), ALLOCATABLE, DIMENSION(:) :: descriptor, variances
519 REAL(dp), DIMENSION(:, :), POINTER :: block_x
520 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
521 TYPE(cell_type), POINTER :: cell
522 TYPE(dbcsr_iterator_type) :: iter
523 TYPE(mp_para_env_type), POINTER :: para_env
524 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
525 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
526
527 CALL timeset(routinen, handle)
528
529 CALL get_qs_env(qs_env, &
530 para_env=para_env, &
531 cell=cell, &
532 particle_set=particle_set, &
533 atomic_kind_set=atomic_kind_set, &
534 qs_kind_set=qs_kind_set, &
535 natom=natoms)
536
537 ! fill matrix_X
538 ALLOCATE (variances(natoms))
539 variances(:) = 0.0_dp
540!$OMP PARALLEL DEFAULT(NONE) SHARED(pao,qs_env,particle_set,qs_kind_set,cell,variances) &
541!$OMP PRIVATE(iter,arow,acol,iatom,ikind,descriptor,block_X)
542 CALL dbcsr_iterator_start(iter, pao%matrix_X)
543 DO WHILE (dbcsr_iterator_blocks_left(iter))
544 CALL dbcsr_iterator_next_block(iter, arow, acol, block_x)
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 ! pao disabled for iatom
548
549 ! calculate descriptor
550 CALL pao_ml_calc_descriptor(pao, &
551 particle_set, &
552 qs_kind_set, &
553 cell, &
554 iatom, &
555 descriptor)
556
557 ! call actual machine learning for prediction
558 CALL pao_ml_predict_low(pao, ikind=ikind, &
559 descriptor=descriptor, &
560 output=block_x(:, 1), &
561 variance=variances(iatom))
562
563 DEALLOCATE (descriptor)
564
565 !add prior
566 block_x(:, 1) = block_x(:, 1) + pao%ml_training_matrices(ikind)%prior
567 END DO
568 CALL dbcsr_iterator_stop(iter)
569!$OMP END PARALLEL
570
571 ! print variances
572 CALL para_env%sum(variances)
573 IF (pao%iw_mlvar > 0) THEN
574 DO iatom = 1, natoms
575 WRITE (pao%iw_mlvar, *) "PAO|ML| atom:", iatom, " prediction variance:", variances(iatom)
576 END DO
577 CALL m_flush(pao%iw_mlvar)
578 END IF
579
580 ! one-line summary
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)
583
584 IF (maxval(variances) > pao%ml_tolerance) THEN
585 cpabort("Variance of prediction above ML_TOLERANCE.")
586 END IF
587
588 DEALLOCATE (variances)
589
590 CALL timestop(handle)
591
592 END SUBROUTINE pao_ml_predict
593
594! **************************************************************************************************
595!> \brief Queries the actual learning algorthim to make a prediction
596!> \param pao ...
597!> \param ikind ...
598!> \param descriptor ...
599!> \param output ...
600!> \param variance ...
601! **************************************************************************************************
602 SUBROUTINE pao_ml_predict_low(pao, ikind, descriptor, output, variance)
603 TYPE(pao_env_type), POINTER :: pao
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
608
609 SELECT CASE (pao%ml_method)
610 CASE (pao_ml_gp)
611 CALL pao_ml_gp_predict(pao, ikind, descriptor, output, variance)
612 CASE (pao_ml_nn)
613 CALL pao_ml_nn_predict(pao, ikind, descriptor, output, variance)
614 CASE (pao_ml_lazy)
615 output = 0.0_dp ! let's be really lazy and just rely on the prior
616 variance = 0
617 CASE DEFAULT
618 cpabort("PAO: unknown machine learning scheme")
619 END SELECT
620
621 END SUBROUTINE pao_ml_predict_low
622
623! **************************************************************************************************
624!> \brief Calculate forces contributed by machine learning
625!> \param pao ...
626!> \param qs_env ...
627!> \param matrix_G ...
628!> \param forces ...
629! **************************************************************************************************
630 SUBROUTINE pao_ml_forces(pao, qs_env, matrix_G, forces)
631 TYPE(pao_env_type), POINTER :: pao
632 TYPE(qs_environment_type), POINTER :: qs_env
633 TYPE(dbcsr_type) :: matrix_g
634 REAL(dp), DIMENSION(:, :), INTENT(INOUT) :: forces
635
636 CHARACTER(len=*), PARAMETER :: routinen = 'pao_ml_forces'
637
638 INTEGER :: acol, arow, handle, iatom, ikind
639 REAL(dp), ALLOCATABLE, DIMENSION(:) :: descr_grad, descriptor
640 REAL(dp), DIMENSION(:, :), POINTER :: block_g
641 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
642 TYPE(cell_type), POINTER :: cell
643 TYPE(dbcsr_iterator_type) :: iter
644 TYPE(mp_para_env_type), POINTER :: para_env
645 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
646 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
647
648 CALL timeset(routinen, handle)
649
650 CALL get_qs_env(qs_env, &
651 para_env=para_env, &
652 cell=cell, &
653 particle_set=particle_set, &
654 atomic_kind_set=atomic_kind_set, &
655 qs_kind_set=qs_kind_set)
656
657!$OMP PARALLEL DEFAULT(NONE) SHARED(pao,matrix_G,particle_set,qs_kind_set,cell) &
658!$OMP REDUCTION(+:forces) &
659!$OMP PRIVATE(iter,arow,acol,iatom,ikind,block_G,descriptor,descr_grad)
660 CALL dbcsr_iterator_start(iter, matrix_g)
661 DO WHILE (dbcsr_iterator_blocks_left(iter))
662 CALL dbcsr_iterator_next_block(iter, arow, acol, block_g)
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 ! pao disabled for iatom
666
667 ! calculate descriptor
668 CALL pao_ml_calc_descriptor(pao, &
669 particle_set, &
670 qs_kind_set, &
671 cell, &
672 iatom=iatom, &
673 descriptor=descriptor)
674
675 ! calcaulte derivate of machine learning prediction
676 CALL pao_ml_gradient_low(pao, ikind=ikind, &
677 descriptor=descriptor, &
678 outer_deriv=block_g(:, 1), &
679 gradient=descr_grad)
680
681 ! calculate force contributions from descriptor
682 CALL pao_ml_calc_descriptor(pao, &
683 particle_set, &
684 qs_kind_set, &
685 cell, &
686 iatom=iatom, &
687 descr_grad=descr_grad, &
688 forces=forces)
689
690 DEALLOCATE (descriptor, descr_grad)
691 END DO
692 CALL dbcsr_iterator_stop(iter)
693!$OMP END PARALLEL
694
695 CALL timestop(handle)
696
697 END SUBROUTINE pao_ml_forces
698
699! **************************************************************************************************
700!> \brief Calculate gradient of machine learning algorithm
701!> \param pao ...
702!> \param ikind ...
703!> \param descriptor ...
704!> \param outer_deriv ...
705!> \param gradient ...
706! **************************************************************************************************
707 SUBROUTINE pao_ml_gradient_low(pao, ikind, descriptor, outer_deriv, gradient)
708 TYPE(pao_env_type), POINTER :: pao
709 INTEGER, INTENT(IN) :: ikind
710 REAL(dp), DIMENSION(:), INTENT(IN) :: descriptor, outer_deriv
711 REAL(dp), ALLOCATABLE, DIMENSION(:) :: gradient
712
713 ALLOCATE (gradient(SIZE(descriptor)))
714
715 SELECT CASE (pao%ml_method)
716 CASE (pao_ml_gp)
717 CALL pao_ml_gp_gradient(pao, ikind, descriptor, outer_deriv, gradient)
718 CASE (pao_ml_nn)
719 CALL pao_ml_nn_gradient(pao, ikind, descriptor, outer_deriv, gradient)
720 CASE (pao_ml_lazy)
721 gradient = 0.0_dp
722 CASE DEFAULT
723 cpabort("PAO: unknown machine learning scheme")
724 END SELECT
725
726 END SUBROUTINE pao_ml_gradient_low
727
728END MODULE pao_ml
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.
Definition cell_types.F:15
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.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_string_length
Definition kinds.F:57
integer, parameter, public default_path_length
Definition kinds.F:58
Machine interface based on Fortran 2003 and POSIX.
Definition machine.F:17
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Definition machine.F:124
Interface to the message passing library MPI.
integer, parameter, public pao_ml_gp
Definition pao_input.F:45
integer, parameter, public pao_ml_prior_mean
Definition pao_input.F:45
integer, parameter, public pao_ml_lazy
Definition pao_input.F:45
integer, parameter, public pao_rotinv_param
Definition pao_input.F:45
integer, parameter, public pao_ml_prior_zero
Definition pao_input.F:45
integer, parameter, public pao_ml_nn
Definition pao_input.F:45
character(len=20) function, public id2str(id)
Helper routine.
Definition pao_input.F:219
Routines for reading and writing restart files.
Definition pao_io.F:12
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.
Definition pao_io.F:332
subroutine, public pao_read_raw(filename, param, hmat, kinds, atom2kind, positions, xblocks, ml_range)
Reads a restart file into temporary datastructures.
Definition pao_io.F:188
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.
Definition pao_ml.F:12
subroutine, public pao_ml_forces(pao, qs_env, matrix_g, forces)
Calculate forces contributed by machine learning.
Definition pao_ml.F:631
subroutine, public pao_ml_init(pao, qs_env)
Initializes the learning machinery.
Definition pao_ml.F:85
subroutine, public pao_ml_predict(pao, qs_env)
Fills paomatrix_X based on machine learning predictions.
Definition pao_ml.F:512
Types used by the PAO machinery.
Definition pao_types.F:12
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.
Definition cell_types.F:60
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.