(git:3f0d10b)
Loading...
Searching...
No Matches
torch_api.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!--------------------------------------------------------------------------------------------------!
8 USE iso_c_binding, ONLY: c_associated, &
9 c_bool, &
10 c_char, &
11 c_float, &
12 c_double, &
13 c_f_pointer, &
14 c_int, &
15 c_null_char, &
16 c_null_ptr, &
17 c_ptr, &
18 c_int32_t, &
19 c_int64_t
20
22
23#include "./base/base_uses.f90"
24
25 IMPLICIT NONE
26
27 PRIVATE
28
30 PRIVATE
31 TYPE(C_PTR) :: c_ptr = c_null_ptr
32 END TYPE torch_tensor_type
33
35 PRIVATE
36 TYPE(C_PTR) :: c_ptr = c_null_ptr
37 END TYPE torch_dict_type
38
40 PRIVATE
41 TYPE(C_PTR) :: c_ptr = c_null_ptr
42 END TYPE torch_model_type
43
45 MODULE PROCEDURE torch_tensor_from_array_int32_1d
46 MODULE PROCEDURE torch_tensor_from_array_float_1d
47 MODULE PROCEDURE torch_tensor_from_array_int64_1d
48 MODULE PROCEDURE torch_tensor_from_array_double_1d
49 MODULE PROCEDURE torch_tensor_from_array_int32_2d
50 MODULE PROCEDURE torch_tensor_from_array_float_2d
51 MODULE PROCEDURE torch_tensor_from_array_int64_2d
52 MODULE PROCEDURE torch_tensor_from_array_double_2d
53 MODULE PROCEDURE torch_tensor_from_array_int32_3d
54 MODULE PROCEDURE torch_tensor_from_array_float_3d
55 MODULE PROCEDURE torch_tensor_from_array_int64_3d
56 MODULE PROCEDURE torch_tensor_from_array_double_3d
57 END INTERFACE torch_tensor_from_array
58
60 MODULE PROCEDURE torch_tensor_reset_from_array_double_1d
61 MODULE PROCEDURE torch_tensor_reset_from_array_double_2d
62 MODULE PROCEDURE torch_tensor_reset_from_array_double_3d
64
66 MODULE PROCEDURE torch_tensor_data_ptr_int32_1d
67 MODULE PROCEDURE torch_tensor_data_ptr_float_1d
68 MODULE PROCEDURE torch_tensor_data_ptr_int64_1d
69 MODULE PROCEDURE torch_tensor_data_ptr_double_1d
70 MODULE PROCEDURE torch_tensor_data_ptr_int32_2d
71 MODULE PROCEDURE torch_tensor_data_ptr_float_2d
72 MODULE PROCEDURE torch_tensor_data_ptr_int64_2d
73 MODULE PROCEDURE torch_tensor_data_ptr_double_2d
74 MODULE PROCEDURE torch_tensor_data_ptr_int32_3d
75 MODULE PROCEDURE torch_tensor_data_ptr_float_3d
76 MODULE PROCEDURE torch_tensor_data_ptr_int64_3d
77 MODULE PROCEDURE torch_tensor_data_ptr_double_3d
78 END INTERFACE torch_tensor_data_ptr
79
81 MODULE PROCEDURE torch_model_get_attr_string
82 MODULE PROCEDURE torch_model_get_attr_double
83 MODULE PROCEDURE torch_model_get_attr_int64
84 MODULE PROCEDURE torch_model_get_attr_int32
85 MODULE PROCEDURE torch_model_get_attr_strlist
86 END INTERFACE torch_model_get_attr
87
106
107CONTAINS
108
109
110
111! **************************************************************************************************
112!> \brief Creates a Torch tensor from an array. The passed array has to outlive the tensor!
113!> The source must be an ALLOCATABLE to prevent passing a temporary array.
114!> \author Ole Schuett
115! **************************************************************************************************
116 SUBROUTINE torch_tensor_from_array_int32_1d(tensor, source, requires_grad)
117 TYPE(torch_tensor_type), INTENT(INOUT) :: tensor
118 INTEGER(kind=int_4), DIMENSION(:), ALLOCATABLE, INTENT(IN) :: source
119 LOGICAL, OPTIONAL, INTENT(IN) :: requires_grad
120
121#if defined(__LIBTORCH)
122 INTEGER(kind=int_8), DIMENSION(1) :: sizes_c
123 LOGICAL :: my_req_grad
124
125 INTERFACE
126 SUBROUTINE torch_c_tensor_from_array_int32 (tensor, req_grad, ndims, sizes, source) &
127 BIND(C, name="torch_c_tensor_from_array_int32")
128 IMPORT :: c_ptr, c_int, c_int32_t, c_int64_t, c_float, c_double, c_bool
129 TYPE(c_ptr) :: tensor
130 LOGICAL(kind=C_BOOL), VALUE :: req_grad
131 INTEGER(kind=C_INT), VALUE :: ndims
132 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
133 INTEGER(kind=C_INT32_T), DIMENSION(*) :: source
134 END SUBROUTINE torch_c_tensor_from_array_int32
135 END INTERFACE
136
137 my_req_grad = .false.
138 IF (PRESENT(requires_grad)) my_req_grad = requires_grad
139
140 sizes_c(1) = SIZE(source, 1) ! C arrays are stored row-major.
141
142 cpassert(.NOT. c_associated(tensor%c_ptr))
143 CALL torch_c_tensor_from_array_int32 (tensor=tensor%c_ptr, &
144 req_grad=LOGICAL(my_req_grad, C_BOOL), &
145 ndims=1, &
146 sizes=sizes_c, &
147 source=source)
148 cpassert(c_associated(tensor%c_ptr))
149#else
150 cpabort("CP2K compiled without the Torch library.")
151 mark_used(tensor)
152 mark_used(source)
153 mark_used(requires_grad)
154#endif
155 END SUBROUTINE torch_tensor_from_array_int32_1d
156
157! **************************************************************************************************
158!> \brief Copies data from a Torch tensor to an array.
159!> The returned pointer is only valide during the tensor's lifetime!
160!> \author Ole Schuett
161! **************************************************************************************************
162 SUBROUTINE torch_tensor_data_ptr_int32_1d(tensor, data_ptr)
163 TYPE(torch_tensor_type), INTENT(IN) :: tensor
164 INTEGER(kind=int_4), DIMENSION(:), POINTER :: data_ptr
165
166#if defined(__LIBTORCH)
167 INTEGER(kind=int_8), DIMENSION(1) :: sizes_f, sizes_c
168 TYPE(c_ptr) :: data_ptr_c
169
170 INTERFACE
171 SUBROUTINE torch_c_tensor_data_ptr_int32 (tensor, ndims, sizes, data_ptr) &
172 BIND(C, name="torch_c_tensor_data_ptr_int32")
173 IMPORT :: c_char, c_ptr, c_int, c_int32_t, c_int64_t
174 TYPE(c_ptr), VALUE :: tensor
175 INTEGER(kind=C_INT), VALUE :: ndims
176 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
177 TYPE(c_ptr) :: data_ptr
178 END SUBROUTINE torch_c_tensor_data_ptr_int32
179 END INTERFACE
180
181 sizes_c(:) = -1
182 data_ptr_c = c_null_ptr
183 cpassert(c_associated(tensor%c_ptr))
184 cpassert(.NOT. ASSOCIATED(data_ptr))
185 CALL torch_c_tensor_data_ptr_int32 (tensor=tensor%c_ptr, &
186 ndims=1, &
187 sizes=sizes_c, &
188 data_ptr=data_ptr_c)
189
190 sizes_f(1) = sizes_c(1) ! C arrays are stored row-major.
191
192 IF (all(sizes_f /= 0)) THEN ! Torch returns null pointer for zero-sized tensors.
193 cpassert(c_associated(data_ptr_c))
194 CALL c_f_pointer(data_ptr_c, data_ptr, shape=sizes_f)
195 END IF
196#else
197 cpabort("CP2K compiled without the Torch library.")
198 mark_used(tensor)
199 mark_used(data_ptr)
200#endif
201 END SUBROUTINE torch_tensor_data_ptr_int32_1d
202
203
204! **************************************************************************************************
205!> \brief Creates a Torch tensor from an array. The passed array has to outlive the tensor!
206!> The source must be an ALLOCATABLE to prevent passing a temporary array.
207!> \author Ole Schuett
208! **************************************************************************************************
209 SUBROUTINE torch_tensor_from_array_float_1d(tensor, source, requires_grad)
210 TYPE(torch_tensor_type), INTENT(INOUT) :: tensor
211 REAL(sp), DIMENSION(:), ALLOCATABLE, INTENT(IN) :: source
212 LOGICAL, OPTIONAL, INTENT(IN) :: requires_grad
213
214#if defined(__LIBTORCH)
215 INTEGER(kind=int_8), DIMENSION(1) :: sizes_c
216 LOGICAL :: my_req_grad
217
218 INTERFACE
219 SUBROUTINE torch_c_tensor_from_array_float (tensor, req_grad, ndims, sizes, source) &
220 BIND(C, name="torch_c_tensor_from_array_float")
221 IMPORT :: c_ptr, c_int, c_int32_t, c_int64_t, c_float, c_double, c_bool
222 TYPE(c_ptr) :: tensor
223 LOGICAL(kind=C_BOOL), VALUE :: req_grad
224 INTEGER(kind=C_INT), VALUE :: ndims
225 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
226 REAL(kind=c_float), DIMENSION(*) :: source
227 END SUBROUTINE torch_c_tensor_from_array_float
228 END INTERFACE
229
230 my_req_grad = .false.
231 IF (PRESENT(requires_grad)) my_req_grad = requires_grad
232
233 sizes_c(1) = SIZE(source, 1) ! C arrays are stored row-major.
234
235 cpassert(.NOT. c_associated(tensor%c_ptr))
236 CALL torch_c_tensor_from_array_float (tensor=tensor%c_ptr, &
237 req_grad=LOGICAL(my_req_grad, C_BOOL), &
238 ndims=1, &
239 sizes=sizes_c, &
240 source=source)
241 cpassert(c_associated(tensor%c_ptr))
242#else
243 cpabort("CP2K compiled without the Torch library.")
244 mark_used(tensor)
245 mark_used(source)
246 mark_used(requires_grad)
247#endif
248 END SUBROUTINE torch_tensor_from_array_float_1d
249
250! **************************************************************************************************
251!> \brief Copies data from a Torch tensor to an array.
252!> The returned pointer is only valide during the tensor's lifetime!
253!> \author Ole Schuett
254! **************************************************************************************************
255 SUBROUTINE torch_tensor_data_ptr_float_1d(tensor, data_ptr)
256 TYPE(torch_tensor_type), INTENT(IN) :: tensor
257 REAL(sp), DIMENSION(:), POINTER :: data_ptr
258
259#if defined(__LIBTORCH)
260 INTEGER(kind=int_8), DIMENSION(1) :: sizes_f, sizes_c
261 TYPE(c_ptr) :: data_ptr_c
262
263 INTERFACE
264 SUBROUTINE torch_c_tensor_data_ptr_float (tensor, ndims, sizes, data_ptr) &
265 BIND(C, name="torch_c_tensor_data_ptr_float")
266 IMPORT :: c_char, c_ptr, c_int, c_int32_t, c_int64_t
267 TYPE(c_ptr), VALUE :: tensor
268 INTEGER(kind=C_INT), VALUE :: ndims
269 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
270 TYPE(c_ptr) :: data_ptr
271 END SUBROUTINE torch_c_tensor_data_ptr_float
272 END INTERFACE
273
274 sizes_c(:) = -1
275 data_ptr_c = c_null_ptr
276 cpassert(c_associated(tensor%c_ptr))
277 cpassert(.NOT. ASSOCIATED(data_ptr))
278 CALL torch_c_tensor_data_ptr_float (tensor=tensor%c_ptr, &
279 ndims=1, &
280 sizes=sizes_c, &
281 data_ptr=data_ptr_c)
282
283 sizes_f(1) = sizes_c(1) ! C arrays are stored row-major.
284
285 IF (all(sizes_f /= 0)) THEN ! Torch returns null pointer for zero-sized tensors.
286 cpassert(c_associated(data_ptr_c))
287 CALL c_f_pointer(data_ptr_c, data_ptr, shape=sizes_f)
288 END IF
289#else
290 cpabort("CP2K compiled without the Torch library.")
291 mark_used(tensor)
292 mark_used(data_ptr)
293#endif
294 END SUBROUTINE torch_tensor_data_ptr_float_1d
295
296
297! **************************************************************************************************
298!> \brief Creates a Torch tensor from an array. The passed array has to outlive the tensor!
299!> The source must be an ALLOCATABLE to prevent passing a temporary array.
300!> \author Ole Schuett
301! **************************************************************************************************
302 SUBROUTINE torch_tensor_from_array_int64_1d(tensor, source, requires_grad)
303 TYPE(torch_tensor_type), INTENT(INOUT) :: tensor
304 INTEGER(kind=int_8), DIMENSION(:), ALLOCATABLE, INTENT(IN) :: source
305 LOGICAL, OPTIONAL, INTENT(IN) :: requires_grad
306
307#if defined(__LIBTORCH)
308 INTEGER(kind=int_8), DIMENSION(1) :: sizes_c
309 LOGICAL :: my_req_grad
310
311 INTERFACE
312 SUBROUTINE torch_c_tensor_from_array_int64 (tensor, req_grad, ndims, sizes, source) &
313 BIND(C, name="torch_c_tensor_from_array_int64")
314 IMPORT :: c_ptr, c_int, c_int32_t, c_int64_t, c_float, c_double, c_bool
315 TYPE(c_ptr) :: tensor
316 LOGICAL(kind=C_BOOL), VALUE :: req_grad
317 INTEGER(kind=C_INT), VALUE :: ndims
318 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
319 INTEGER(kind=C_INT64_T), DIMENSION(*) :: source
320 END SUBROUTINE torch_c_tensor_from_array_int64
321 END INTERFACE
322
323 my_req_grad = .false.
324 IF (PRESENT(requires_grad)) my_req_grad = requires_grad
325
326 sizes_c(1) = SIZE(source, 1) ! C arrays are stored row-major.
327
328 cpassert(.NOT. c_associated(tensor%c_ptr))
329 CALL torch_c_tensor_from_array_int64 (tensor=tensor%c_ptr, &
330 req_grad=LOGICAL(my_req_grad, C_BOOL), &
331 ndims=1, &
332 sizes=sizes_c, &
333 source=source)
334 cpassert(c_associated(tensor%c_ptr))
335#else
336 cpabort("CP2K compiled without the Torch library.")
337 mark_used(tensor)
338 mark_used(source)
339 mark_used(requires_grad)
340#endif
341 END SUBROUTINE torch_tensor_from_array_int64_1d
342
343! **************************************************************************************************
344!> \brief Copies data from a Torch tensor to an array.
345!> The returned pointer is only valide during the tensor's lifetime!
346!> \author Ole Schuett
347! **************************************************************************************************
348 SUBROUTINE torch_tensor_data_ptr_int64_1d(tensor, data_ptr)
349 TYPE(torch_tensor_type), INTENT(IN) :: tensor
350 INTEGER(kind=int_8), DIMENSION(:), POINTER :: data_ptr
351
352#if defined(__LIBTORCH)
353 INTEGER(kind=int_8), DIMENSION(1) :: sizes_f, sizes_c
354 TYPE(c_ptr) :: data_ptr_c
355
356 INTERFACE
357 SUBROUTINE torch_c_tensor_data_ptr_int64 (tensor, ndims, sizes, data_ptr) &
358 BIND(C, name="torch_c_tensor_data_ptr_int64")
359 IMPORT :: c_char, c_ptr, c_int, c_int32_t, c_int64_t
360 TYPE(c_ptr), VALUE :: tensor
361 INTEGER(kind=C_INT), VALUE :: ndims
362 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
363 TYPE(c_ptr) :: data_ptr
364 END SUBROUTINE torch_c_tensor_data_ptr_int64
365 END INTERFACE
366
367 sizes_c(:) = -1
368 data_ptr_c = c_null_ptr
369 cpassert(c_associated(tensor%c_ptr))
370 cpassert(.NOT. ASSOCIATED(data_ptr))
371 CALL torch_c_tensor_data_ptr_int64 (tensor=tensor%c_ptr, &
372 ndims=1, &
373 sizes=sizes_c, &
374 data_ptr=data_ptr_c)
375
376 sizes_f(1) = sizes_c(1) ! C arrays are stored row-major.
377
378 IF (all(sizes_f /= 0)) THEN ! Torch returns null pointer for zero-sized tensors.
379 cpassert(c_associated(data_ptr_c))
380 CALL c_f_pointer(data_ptr_c, data_ptr, shape=sizes_f)
381 END IF
382#else
383 cpabort("CP2K compiled without the Torch library.")
384 mark_used(tensor)
385 mark_used(data_ptr)
386#endif
387 END SUBROUTINE torch_tensor_data_ptr_int64_1d
388
389
390! **************************************************************************************************
391!> \brief Creates a Torch tensor from an array. The passed array has to outlive the tensor!
392!> The source must be an ALLOCATABLE to prevent passing a temporary array.
393!> \author Ole Schuett
394! **************************************************************************************************
395 SUBROUTINE torch_tensor_from_array_double_1d(tensor, source, requires_grad)
396 TYPE(torch_tensor_type), INTENT(INOUT) :: tensor
397 REAL(dp), DIMENSION(:), ALLOCATABLE, INTENT(IN) :: source
398 LOGICAL, OPTIONAL, INTENT(IN) :: requires_grad
399
400#if defined(__LIBTORCH)
401 INTEGER(kind=int_8), DIMENSION(1) :: sizes_c
402 LOGICAL :: my_req_grad
403
404 INTERFACE
405 SUBROUTINE torch_c_tensor_from_array_double (tensor, req_grad, ndims, sizes, source) &
406 BIND(C, name="torch_c_tensor_from_array_double")
407 IMPORT :: c_ptr, c_int, c_int32_t, c_int64_t, c_float, c_double, c_bool
408 TYPE(c_ptr) :: tensor
409 LOGICAL(kind=C_BOOL), VALUE :: req_grad
410 INTEGER(kind=C_INT), VALUE :: ndims
411 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
412 REAL(kind=c_double), DIMENSION(*) :: source
413 END SUBROUTINE torch_c_tensor_from_array_double
414 END INTERFACE
415
416 my_req_grad = .false.
417 IF (PRESENT(requires_grad)) my_req_grad = requires_grad
418
419 sizes_c(1) = SIZE(source, 1) ! C arrays are stored row-major.
420
421 cpassert(.NOT. c_associated(tensor%c_ptr))
422 CALL torch_c_tensor_from_array_double (tensor=tensor%c_ptr, &
423 req_grad=LOGICAL(my_req_grad, C_BOOL), &
424 ndims=1, &
425 sizes=sizes_c, &
426 source=source)
427 cpassert(c_associated(tensor%c_ptr))
428#else
429 cpabort("CP2K compiled without the Torch library.")
430 mark_used(tensor)
431 mark_used(source)
432 mark_used(requires_grad)
433#endif
434 END SUBROUTINE torch_tensor_from_array_double_1d
435
436! **************************************************************************************************
437!> \brief Copies data from a Torch tensor to an array.
438!> The returned pointer is only valide during the tensor's lifetime!
439!> \author Ole Schuett
440! **************************************************************************************************
441 SUBROUTINE torch_tensor_data_ptr_double_1d(tensor, data_ptr)
442 TYPE(torch_tensor_type), INTENT(IN) :: tensor
443 REAL(dp), DIMENSION(:), POINTER :: data_ptr
444
445#if defined(__LIBTORCH)
446 INTEGER(kind=int_8), DIMENSION(1) :: sizes_f, sizes_c
447 TYPE(c_ptr) :: data_ptr_c
448
449 INTERFACE
450 SUBROUTINE torch_c_tensor_data_ptr_double (tensor, ndims, sizes, data_ptr) &
451 BIND(C, name="torch_c_tensor_data_ptr_double")
452 IMPORT :: c_char, c_ptr, c_int, c_int32_t, c_int64_t
453 TYPE(c_ptr), VALUE :: tensor
454 INTEGER(kind=C_INT), VALUE :: ndims
455 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
456 TYPE(c_ptr) :: data_ptr
457 END SUBROUTINE torch_c_tensor_data_ptr_double
458 END INTERFACE
459
460 sizes_c(:) = -1
461 data_ptr_c = c_null_ptr
462 cpassert(c_associated(tensor%c_ptr))
463 cpassert(.NOT. ASSOCIATED(data_ptr))
464 CALL torch_c_tensor_data_ptr_double (tensor=tensor%c_ptr, &
465 ndims=1, &
466 sizes=sizes_c, &
467 data_ptr=data_ptr_c)
468
469 sizes_f(1) = sizes_c(1) ! C arrays are stored row-major.
470
471 IF (all(sizes_f /= 0)) THEN ! Torch returns null pointer for zero-sized tensors.
472 cpassert(c_associated(data_ptr_c))
473 CALL c_f_pointer(data_ptr_c, data_ptr, shape=sizes_f)
474 END IF
475#else
476 cpabort("CP2K compiled without the Torch library.")
477 mark_used(tensor)
478 mark_used(data_ptr)
479#endif
480 END SUBROUTINE torch_tensor_data_ptr_double_1d
481
482
483! **************************************************************************************************
484!> \brief Creates a Torch tensor from an array. The passed array has to outlive the tensor!
485!> The source must be an ALLOCATABLE to prevent passing a temporary array.
486!> \author Ole Schuett
487! **************************************************************************************************
488 SUBROUTINE torch_tensor_from_array_int32_2d(tensor, source, requires_grad)
489 TYPE(torch_tensor_type), INTENT(INOUT) :: tensor
490 INTEGER(kind=int_4), DIMENSION(:, :), ALLOCATABLE, INTENT(IN) :: source
491 LOGICAL, OPTIONAL, INTENT(IN) :: requires_grad
492
493#if defined(__LIBTORCH)
494 INTEGER(kind=int_8), DIMENSION(2) :: sizes_c
495 LOGICAL :: my_req_grad
496
497 INTERFACE
498 SUBROUTINE torch_c_tensor_from_array_int32 (tensor, req_grad, ndims, sizes, source) &
499 BIND(C, name="torch_c_tensor_from_array_int32")
500 IMPORT :: c_ptr, c_int, c_int32_t, c_int64_t, c_float, c_double, c_bool
501 TYPE(c_ptr) :: tensor
502 LOGICAL(kind=C_BOOL), VALUE :: req_grad
503 INTEGER(kind=C_INT), VALUE :: ndims
504 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
505 INTEGER(kind=C_INT32_T), DIMENSION(*) :: source
506 END SUBROUTINE torch_c_tensor_from_array_int32
507 END INTERFACE
508
509 my_req_grad = .false.
510 IF (PRESENT(requires_grad)) my_req_grad = requires_grad
511
512 sizes_c(1) = SIZE(source, 2) ! C arrays are stored row-major.
513 sizes_c(2) = SIZE(source, 1) ! C arrays are stored row-major.
514
515 cpassert(.NOT. c_associated(tensor%c_ptr))
516 CALL torch_c_tensor_from_array_int32 (tensor=tensor%c_ptr, &
517 req_grad=LOGICAL(my_req_grad, C_BOOL), &
518 ndims=2, &
519 sizes=sizes_c, &
520 source=source)
521 cpassert(c_associated(tensor%c_ptr))
522#else
523 cpabort("CP2K compiled without the Torch library.")
524 mark_used(tensor)
525 mark_used(source)
526 mark_used(requires_grad)
527#endif
528 END SUBROUTINE torch_tensor_from_array_int32_2d
529
530! **************************************************************************************************
531!> \brief Copies data from a Torch tensor to an array.
532!> The returned pointer is only valide during the tensor's lifetime!
533!> \author Ole Schuett
534! **************************************************************************************************
535 SUBROUTINE torch_tensor_data_ptr_int32_2d(tensor, data_ptr)
536 TYPE(torch_tensor_type), INTENT(IN) :: tensor
537 INTEGER(kind=int_4), DIMENSION(:, :), POINTER :: data_ptr
538
539#if defined(__LIBTORCH)
540 INTEGER(kind=int_8), DIMENSION(2) :: sizes_f, sizes_c
541 TYPE(c_ptr) :: data_ptr_c
542
543 INTERFACE
544 SUBROUTINE torch_c_tensor_data_ptr_int32 (tensor, ndims, sizes, data_ptr) &
545 BIND(C, name="torch_c_tensor_data_ptr_int32")
546 IMPORT :: c_char, c_ptr, c_int, c_int32_t, c_int64_t
547 TYPE(c_ptr), VALUE :: tensor
548 INTEGER(kind=C_INT), VALUE :: ndims
549 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
550 TYPE(c_ptr) :: data_ptr
551 END SUBROUTINE torch_c_tensor_data_ptr_int32
552 END INTERFACE
553
554 sizes_c(:) = -1
555 data_ptr_c = c_null_ptr
556 cpassert(c_associated(tensor%c_ptr))
557 cpassert(.NOT. ASSOCIATED(data_ptr))
558 CALL torch_c_tensor_data_ptr_int32 (tensor=tensor%c_ptr, &
559 ndims=2, &
560 sizes=sizes_c, &
561 data_ptr=data_ptr_c)
562
563 sizes_f(1) = sizes_c(2) ! C arrays are stored row-major.
564 sizes_f(2) = sizes_c(1) ! C arrays are stored row-major.
565
566 IF (all(sizes_f /= 0)) THEN ! Torch returns null pointer for zero-sized tensors.
567 cpassert(c_associated(data_ptr_c))
568 CALL c_f_pointer(data_ptr_c, data_ptr, shape=sizes_f)
569 END IF
570#else
571 cpabort("CP2K compiled without the Torch library.")
572 mark_used(tensor)
573 mark_used(data_ptr)
574#endif
575 END SUBROUTINE torch_tensor_data_ptr_int32_2d
576
577
578! **************************************************************************************************
579!> \brief Creates a Torch tensor from an array. The passed array has to outlive the tensor!
580!> The source must be an ALLOCATABLE to prevent passing a temporary array.
581!> \author Ole Schuett
582! **************************************************************************************************
583 SUBROUTINE torch_tensor_from_array_float_2d(tensor, source, requires_grad)
584 TYPE(torch_tensor_type), INTENT(INOUT) :: tensor
585 REAL(sp), DIMENSION(:, :), ALLOCATABLE, INTENT(IN) :: source
586 LOGICAL, OPTIONAL, INTENT(IN) :: requires_grad
587
588#if defined(__LIBTORCH)
589 INTEGER(kind=int_8), DIMENSION(2) :: sizes_c
590 LOGICAL :: my_req_grad
591
592 INTERFACE
593 SUBROUTINE torch_c_tensor_from_array_float (tensor, req_grad, ndims, sizes, source) &
594 BIND(C, name="torch_c_tensor_from_array_float")
595 IMPORT :: c_ptr, c_int, c_int32_t, c_int64_t, c_float, c_double, c_bool
596 TYPE(c_ptr) :: tensor
597 LOGICAL(kind=C_BOOL), VALUE :: req_grad
598 INTEGER(kind=C_INT), VALUE :: ndims
599 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
600 REAL(kind=c_float), DIMENSION(*) :: source
601 END SUBROUTINE torch_c_tensor_from_array_float
602 END INTERFACE
603
604 my_req_grad = .false.
605 IF (PRESENT(requires_grad)) my_req_grad = requires_grad
606
607 sizes_c(1) = SIZE(source, 2) ! C arrays are stored row-major.
608 sizes_c(2) = SIZE(source, 1) ! C arrays are stored row-major.
609
610 cpassert(.NOT. c_associated(tensor%c_ptr))
611 CALL torch_c_tensor_from_array_float (tensor=tensor%c_ptr, &
612 req_grad=LOGICAL(my_req_grad, C_BOOL), &
613 ndims=2, &
614 sizes=sizes_c, &
615 source=source)
616 cpassert(c_associated(tensor%c_ptr))
617#else
618 cpabort("CP2K compiled without the Torch library.")
619 mark_used(tensor)
620 mark_used(source)
621 mark_used(requires_grad)
622#endif
623 END SUBROUTINE torch_tensor_from_array_float_2d
624
625! **************************************************************************************************
626!> \brief Copies data from a Torch tensor to an array.
627!> The returned pointer is only valide during the tensor's lifetime!
628!> \author Ole Schuett
629! **************************************************************************************************
630 SUBROUTINE torch_tensor_data_ptr_float_2d(tensor, data_ptr)
631 TYPE(torch_tensor_type), INTENT(IN) :: tensor
632 REAL(sp), DIMENSION(:, :), POINTER :: data_ptr
633
634#if defined(__LIBTORCH)
635 INTEGER(kind=int_8), DIMENSION(2) :: sizes_f, sizes_c
636 TYPE(c_ptr) :: data_ptr_c
637
638 INTERFACE
639 SUBROUTINE torch_c_tensor_data_ptr_float (tensor, ndims, sizes, data_ptr) &
640 BIND(C, name="torch_c_tensor_data_ptr_float")
641 IMPORT :: c_char, c_ptr, c_int, c_int32_t, c_int64_t
642 TYPE(c_ptr), VALUE :: tensor
643 INTEGER(kind=C_INT), VALUE :: ndims
644 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
645 TYPE(c_ptr) :: data_ptr
646 END SUBROUTINE torch_c_tensor_data_ptr_float
647 END INTERFACE
648
649 sizes_c(:) = -1
650 data_ptr_c = c_null_ptr
651 cpassert(c_associated(tensor%c_ptr))
652 cpassert(.NOT. ASSOCIATED(data_ptr))
653 CALL torch_c_tensor_data_ptr_float (tensor=tensor%c_ptr, &
654 ndims=2, &
655 sizes=sizes_c, &
656 data_ptr=data_ptr_c)
657
658 sizes_f(1) = sizes_c(2) ! C arrays are stored row-major.
659 sizes_f(2) = sizes_c(1) ! C arrays are stored row-major.
660
661 IF (all(sizes_f /= 0)) THEN ! Torch returns null pointer for zero-sized tensors.
662 cpassert(c_associated(data_ptr_c))
663 CALL c_f_pointer(data_ptr_c, data_ptr, shape=sizes_f)
664 END IF
665#else
666 cpabort("CP2K compiled without the Torch library.")
667 mark_used(tensor)
668 mark_used(data_ptr)
669#endif
670 END SUBROUTINE torch_tensor_data_ptr_float_2d
671
672
673! **************************************************************************************************
674!> \brief Creates a Torch tensor from an array. The passed array has to outlive the tensor!
675!> The source must be an ALLOCATABLE to prevent passing a temporary array.
676!> \author Ole Schuett
677! **************************************************************************************************
678 SUBROUTINE torch_tensor_from_array_int64_2d(tensor, source, requires_grad)
679 TYPE(torch_tensor_type), INTENT(INOUT) :: tensor
680 INTEGER(kind=int_8), DIMENSION(:, :), ALLOCATABLE, INTENT(IN) :: source
681 LOGICAL, OPTIONAL, INTENT(IN) :: requires_grad
682
683#if defined(__LIBTORCH)
684 INTEGER(kind=int_8), DIMENSION(2) :: sizes_c
685 LOGICAL :: my_req_grad
686
687 INTERFACE
688 SUBROUTINE torch_c_tensor_from_array_int64 (tensor, req_grad, ndims, sizes, source) &
689 BIND(C, name="torch_c_tensor_from_array_int64")
690 IMPORT :: c_ptr, c_int, c_int32_t, c_int64_t, c_float, c_double, c_bool
691 TYPE(c_ptr) :: tensor
692 LOGICAL(kind=C_BOOL), VALUE :: req_grad
693 INTEGER(kind=C_INT), VALUE :: ndims
694 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
695 INTEGER(kind=C_INT64_T), DIMENSION(*) :: source
696 END SUBROUTINE torch_c_tensor_from_array_int64
697 END INTERFACE
698
699 my_req_grad = .false.
700 IF (PRESENT(requires_grad)) my_req_grad = requires_grad
701
702 sizes_c(1) = SIZE(source, 2) ! C arrays are stored row-major.
703 sizes_c(2) = SIZE(source, 1) ! C arrays are stored row-major.
704
705 cpassert(.NOT. c_associated(tensor%c_ptr))
706 CALL torch_c_tensor_from_array_int64 (tensor=tensor%c_ptr, &
707 req_grad=LOGICAL(my_req_grad, C_BOOL), &
708 ndims=2, &
709 sizes=sizes_c, &
710 source=source)
711 cpassert(c_associated(tensor%c_ptr))
712#else
713 cpabort("CP2K compiled without the Torch library.")
714 mark_used(tensor)
715 mark_used(source)
716 mark_used(requires_grad)
717#endif
718 END SUBROUTINE torch_tensor_from_array_int64_2d
719
720! **************************************************************************************************
721!> \brief Copies data from a Torch tensor to an array.
722!> The returned pointer is only valide during the tensor's lifetime!
723!> \author Ole Schuett
724! **************************************************************************************************
725 SUBROUTINE torch_tensor_data_ptr_int64_2d(tensor, data_ptr)
726 TYPE(torch_tensor_type), INTENT(IN) :: tensor
727 INTEGER(kind=int_8), DIMENSION(:, :), POINTER :: data_ptr
728
729#if defined(__LIBTORCH)
730 INTEGER(kind=int_8), DIMENSION(2) :: sizes_f, sizes_c
731 TYPE(c_ptr) :: data_ptr_c
732
733 INTERFACE
734 SUBROUTINE torch_c_tensor_data_ptr_int64 (tensor, ndims, sizes, data_ptr) &
735 BIND(C, name="torch_c_tensor_data_ptr_int64")
736 IMPORT :: c_char, c_ptr, c_int, c_int32_t, c_int64_t
737 TYPE(c_ptr), VALUE :: tensor
738 INTEGER(kind=C_INT), VALUE :: ndims
739 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
740 TYPE(c_ptr) :: data_ptr
741 END SUBROUTINE torch_c_tensor_data_ptr_int64
742 END INTERFACE
743
744 sizes_c(:) = -1
745 data_ptr_c = c_null_ptr
746 cpassert(c_associated(tensor%c_ptr))
747 cpassert(.NOT. ASSOCIATED(data_ptr))
748 CALL torch_c_tensor_data_ptr_int64 (tensor=tensor%c_ptr, &
749 ndims=2, &
750 sizes=sizes_c, &
751 data_ptr=data_ptr_c)
752
753 sizes_f(1) = sizes_c(2) ! C arrays are stored row-major.
754 sizes_f(2) = sizes_c(1) ! C arrays are stored row-major.
755
756 IF (all(sizes_f /= 0)) THEN ! Torch returns null pointer for zero-sized tensors.
757 cpassert(c_associated(data_ptr_c))
758 CALL c_f_pointer(data_ptr_c, data_ptr, shape=sizes_f)
759 END IF
760#else
761 cpabort("CP2K compiled without the Torch library.")
762 mark_used(tensor)
763 mark_used(data_ptr)
764#endif
765 END SUBROUTINE torch_tensor_data_ptr_int64_2d
766
767
768! **************************************************************************************************
769!> \brief Creates a Torch tensor from an array. The passed array has to outlive the tensor!
770!> The source must be an ALLOCATABLE to prevent passing a temporary array.
771!> \author Ole Schuett
772! **************************************************************************************************
773 SUBROUTINE torch_tensor_from_array_double_2d(tensor, source, requires_grad)
774 TYPE(torch_tensor_type), INTENT(INOUT) :: tensor
775 REAL(dp), DIMENSION(:, :), ALLOCATABLE, INTENT(IN) :: source
776 LOGICAL, OPTIONAL, INTENT(IN) :: requires_grad
777
778#if defined(__LIBTORCH)
779 INTEGER(kind=int_8), DIMENSION(2) :: sizes_c
780 LOGICAL :: my_req_grad
781
782 INTERFACE
783 SUBROUTINE torch_c_tensor_from_array_double (tensor, req_grad, ndims, sizes, source) &
784 BIND(C, name="torch_c_tensor_from_array_double")
785 IMPORT :: c_ptr, c_int, c_int32_t, c_int64_t, c_float, c_double, c_bool
786 TYPE(c_ptr) :: tensor
787 LOGICAL(kind=C_BOOL), VALUE :: req_grad
788 INTEGER(kind=C_INT), VALUE :: ndims
789 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
790 REAL(kind=c_double), DIMENSION(*) :: source
791 END SUBROUTINE torch_c_tensor_from_array_double
792 END INTERFACE
793
794 my_req_grad = .false.
795 IF (PRESENT(requires_grad)) my_req_grad = requires_grad
796
797 sizes_c(1) = SIZE(source, 2) ! C arrays are stored row-major.
798 sizes_c(2) = SIZE(source, 1) ! C arrays are stored row-major.
799
800 cpassert(.NOT. c_associated(tensor%c_ptr))
801 CALL torch_c_tensor_from_array_double (tensor=tensor%c_ptr, &
802 req_grad=LOGICAL(my_req_grad, C_BOOL), &
803 ndims=2, &
804 sizes=sizes_c, &
805 source=source)
806 cpassert(c_associated(tensor%c_ptr))
807#else
808 cpabort("CP2K compiled without the Torch library.")
809 mark_used(tensor)
810 mark_used(source)
811 mark_used(requires_grad)
812#endif
813 END SUBROUTINE torch_tensor_from_array_double_2d
814
815! **************************************************************************************************
816!> \brief Copies data from a Torch tensor to an array.
817!> The returned pointer is only valide during the tensor's lifetime!
818!> \author Ole Schuett
819! **************************************************************************************************
820 SUBROUTINE torch_tensor_data_ptr_double_2d(tensor, data_ptr)
821 TYPE(torch_tensor_type), INTENT(IN) :: tensor
822 REAL(dp), DIMENSION(:, :), POINTER :: data_ptr
823
824#if defined(__LIBTORCH)
825 INTEGER(kind=int_8), DIMENSION(2) :: sizes_f, sizes_c
826 TYPE(c_ptr) :: data_ptr_c
827
828 INTERFACE
829 SUBROUTINE torch_c_tensor_data_ptr_double (tensor, ndims, sizes, data_ptr) &
830 BIND(C, name="torch_c_tensor_data_ptr_double")
831 IMPORT :: c_char, c_ptr, c_int, c_int32_t, c_int64_t
832 TYPE(c_ptr), VALUE :: tensor
833 INTEGER(kind=C_INT), VALUE :: ndims
834 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
835 TYPE(c_ptr) :: data_ptr
836 END SUBROUTINE torch_c_tensor_data_ptr_double
837 END INTERFACE
838
839 sizes_c(:) = -1
840 data_ptr_c = c_null_ptr
841 cpassert(c_associated(tensor%c_ptr))
842 cpassert(.NOT. ASSOCIATED(data_ptr))
843 CALL torch_c_tensor_data_ptr_double (tensor=tensor%c_ptr, &
844 ndims=2, &
845 sizes=sizes_c, &
846 data_ptr=data_ptr_c)
847
848 sizes_f(1) = sizes_c(2) ! C arrays are stored row-major.
849 sizes_f(2) = sizes_c(1) ! C arrays are stored row-major.
850
851 IF (all(sizes_f /= 0)) THEN ! Torch returns null pointer for zero-sized tensors.
852 cpassert(c_associated(data_ptr_c))
853 CALL c_f_pointer(data_ptr_c, data_ptr, shape=sizes_f)
854 END IF
855#else
856 cpabort("CP2K compiled without the Torch library.")
857 mark_used(tensor)
858 mark_used(data_ptr)
859#endif
860 END SUBROUTINE torch_tensor_data_ptr_double_2d
861
862
863! **************************************************************************************************
864!> \brief Creates a Torch tensor from an array. The passed array has to outlive the tensor!
865!> The source must be an ALLOCATABLE to prevent passing a temporary array.
866!> \author Ole Schuett
867! **************************************************************************************************
868 SUBROUTINE torch_tensor_from_array_int32_3d(tensor, source, requires_grad)
869 TYPE(torch_tensor_type), INTENT(INOUT) :: tensor
870 INTEGER(kind=int_4), DIMENSION(:, :, :), ALLOCATABLE, INTENT(IN) :: source
871 LOGICAL, OPTIONAL, INTENT(IN) :: requires_grad
872
873#if defined(__LIBTORCH)
874 INTEGER(kind=int_8), DIMENSION(3) :: sizes_c
875 LOGICAL :: my_req_grad
876
877 INTERFACE
878 SUBROUTINE torch_c_tensor_from_array_int32 (tensor, req_grad, ndims, sizes, source) &
879 BIND(C, name="torch_c_tensor_from_array_int32")
880 IMPORT :: c_ptr, c_int, c_int32_t, c_int64_t, c_float, c_double, c_bool
881 TYPE(c_ptr) :: tensor
882 LOGICAL(kind=C_BOOL), VALUE :: req_grad
883 INTEGER(kind=C_INT), VALUE :: ndims
884 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
885 INTEGER(kind=C_INT32_T), DIMENSION(*) :: source
886 END SUBROUTINE torch_c_tensor_from_array_int32
887 END INTERFACE
888
889 my_req_grad = .false.
890 IF (PRESENT(requires_grad)) my_req_grad = requires_grad
891
892 sizes_c(1) = SIZE(source, 3) ! C arrays are stored row-major.
893 sizes_c(2) = SIZE(source, 2) ! C arrays are stored row-major.
894 sizes_c(3) = SIZE(source, 1) ! C arrays are stored row-major.
895
896 cpassert(.NOT. c_associated(tensor%c_ptr))
897 CALL torch_c_tensor_from_array_int32 (tensor=tensor%c_ptr, &
898 req_grad=LOGICAL(my_req_grad, C_BOOL), &
899 ndims=3, &
900 sizes=sizes_c, &
901 source=source)
902 cpassert(c_associated(tensor%c_ptr))
903#else
904 cpabort("CP2K compiled without the Torch library.")
905 mark_used(tensor)
906 mark_used(source)
907 mark_used(requires_grad)
908#endif
909 END SUBROUTINE torch_tensor_from_array_int32_3d
910
911! **************************************************************************************************
912!> \brief Copies data from a Torch tensor to an array.
913!> The returned pointer is only valide during the tensor's lifetime!
914!> \author Ole Schuett
915! **************************************************************************************************
916 SUBROUTINE torch_tensor_data_ptr_int32_3d(tensor, data_ptr)
917 TYPE(torch_tensor_type), INTENT(IN) :: tensor
918 INTEGER(kind=int_4), DIMENSION(:, :, :), POINTER :: data_ptr
919
920#if defined(__LIBTORCH)
921 INTEGER(kind=int_8), DIMENSION(3) :: sizes_f, sizes_c
922 TYPE(c_ptr) :: data_ptr_c
923
924 INTERFACE
925 SUBROUTINE torch_c_tensor_data_ptr_int32 (tensor, ndims, sizes, data_ptr) &
926 BIND(C, name="torch_c_tensor_data_ptr_int32")
927 IMPORT :: c_char, c_ptr, c_int, c_int32_t, c_int64_t
928 TYPE(c_ptr), VALUE :: tensor
929 INTEGER(kind=C_INT), VALUE :: ndims
930 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
931 TYPE(c_ptr) :: data_ptr
932 END SUBROUTINE torch_c_tensor_data_ptr_int32
933 END INTERFACE
934
935 sizes_c(:) = -1
936 data_ptr_c = c_null_ptr
937 cpassert(c_associated(tensor%c_ptr))
938 cpassert(.NOT. ASSOCIATED(data_ptr))
939 CALL torch_c_tensor_data_ptr_int32 (tensor=tensor%c_ptr, &
940 ndims=3, &
941 sizes=sizes_c, &
942 data_ptr=data_ptr_c)
943
944 sizes_f(1) = sizes_c(3) ! C arrays are stored row-major.
945 sizes_f(2) = sizes_c(2) ! C arrays are stored row-major.
946 sizes_f(3) = sizes_c(1) ! C arrays are stored row-major.
947
948 IF (all(sizes_f /= 0)) THEN ! Torch returns null pointer for zero-sized tensors.
949 cpassert(c_associated(data_ptr_c))
950 CALL c_f_pointer(data_ptr_c, data_ptr, shape=sizes_f)
951 END IF
952#else
953 cpabort("CP2K compiled without the Torch library.")
954 mark_used(tensor)
955 mark_used(data_ptr)
956#endif
957 END SUBROUTINE torch_tensor_data_ptr_int32_3d
958
959
960! **************************************************************************************************
961!> \brief Creates a Torch tensor from an array. The passed array has to outlive the tensor!
962!> The source must be an ALLOCATABLE to prevent passing a temporary array.
963!> \author Ole Schuett
964! **************************************************************************************************
965 SUBROUTINE torch_tensor_from_array_float_3d(tensor, source, requires_grad)
966 TYPE(torch_tensor_type), INTENT(INOUT) :: tensor
967 REAL(sp), DIMENSION(:, :, :), ALLOCATABLE, INTENT(IN) :: source
968 LOGICAL, OPTIONAL, INTENT(IN) :: requires_grad
969
970#if defined(__LIBTORCH)
971 INTEGER(kind=int_8), DIMENSION(3) :: sizes_c
972 LOGICAL :: my_req_grad
973
974 INTERFACE
975 SUBROUTINE torch_c_tensor_from_array_float (tensor, req_grad, ndims, sizes, source) &
976 BIND(C, name="torch_c_tensor_from_array_float")
977 IMPORT :: c_ptr, c_int, c_int32_t, c_int64_t, c_float, c_double, c_bool
978 TYPE(c_ptr) :: tensor
979 LOGICAL(kind=C_BOOL), VALUE :: req_grad
980 INTEGER(kind=C_INT), VALUE :: ndims
981 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
982 REAL(kind=c_float), DIMENSION(*) :: source
983 END SUBROUTINE torch_c_tensor_from_array_float
984 END INTERFACE
985
986 my_req_grad = .false.
987 IF (PRESENT(requires_grad)) my_req_grad = requires_grad
988
989 sizes_c(1) = SIZE(source, 3) ! C arrays are stored row-major.
990 sizes_c(2) = SIZE(source, 2) ! C arrays are stored row-major.
991 sizes_c(3) = SIZE(source, 1) ! C arrays are stored row-major.
992
993 cpassert(.NOT. c_associated(tensor%c_ptr))
994 CALL torch_c_tensor_from_array_float (tensor=tensor%c_ptr, &
995 req_grad=LOGICAL(my_req_grad, C_BOOL), &
996 ndims=3, &
997 sizes=sizes_c, &
998 source=source)
999 cpassert(c_associated(tensor%c_ptr))
1000#else
1001 cpabort("CP2K compiled without the Torch library.")
1002 mark_used(tensor)
1003 mark_used(source)
1004 mark_used(requires_grad)
1005#endif
1006 END SUBROUTINE torch_tensor_from_array_float_3d
1007
1008! **************************************************************************************************
1009!> \brief Copies data from a Torch tensor to an array.
1010!> The returned pointer is only valide during the tensor's lifetime!
1011!> \author Ole Schuett
1012! **************************************************************************************************
1013 SUBROUTINE torch_tensor_data_ptr_float_3d(tensor, data_ptr)
1014 TYPE(torch_tensor_type), INTENT(IN) :: tensor
1015 REAL(sp), DIMENSION(:, :, :), POINTER :: data_ptr
1016
1017#if defined(__LIBTORCH)
1018 INTEGER(kind=int_8), DIMENSION(3) :: sizes_f, sizes_c
1019 TYPE(c_ptr) :: data_ptr_c
1020
1021 INTERFACE
1022 SUBROUTINE torch_c_tensor_data_ptr_float (tensor, ndims, sizes, data_ptr) &
1023 BIND(C, name="torch_c_tensor_data_ptr_float")
1024 IMPORT :: c_char, c_ptr, c_int, c_int32_t, c_int64_t
1025 TYPE(c_ptr), VALUE :: tensor
1026 INTEGER(kind=C_INT), VALUE :: ndims
1027 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
1028 TYPE(c_ptr) :: data_ptr
1029 END SUBROUTINE torch_c_tensor_data_ptr_float
1030 END INTERFACE
1031
1032 sizes_c(:) = -1
1033 data_ptr_c = c_null_ptr
1034 cpassert(c_associated(tensor%c_ptr))
1035 cpassert(.NOT. ASSOCIATED(data_ptr))
1036 CALL torch_c_tensor_data_ptr_float (tensor=tensor%c_ptr, &
1037 ndims=3, &
1038 sizes=sizes_c, &
1039 data_ptr=data_ptr_c)
1040
1041 sizes_f(1) = sizes_c(3) ! C arrays are stored row-major.
1042 sizes_f(2) = sizes_c(2) ! C arrays are stored row-major.
1043 sizes_f(3) = sizes_c(1) ! C arrays are stored row-major.
1044
1045 IF (all(sizes_f /= 0)) THEN ! Torch returns null pointer for zero-sized tensors.
1046 cpassert(c_associated(data_ptr_c))
1047 CALL c_f_pointer(data_ptr_c, data_ptr, shape=sizes_f)
1048 END IF
1049#else
1050 cpabort("CP2K compiled without the Torch library.")
1051 mark_used(tensor)
1052 mark_used(data_ptr)
1053#endif
1054 END SUBROUTINE torch_tensor_data_ptr_float_3d
1055
1056
1057! **************************************************************************************************
1058!> \brief Creates a Torch tensor from an array. The passed array has to outlive the tensor!
1059!> The source must be an ALLOCATABLE to prevent passing a temporary array.
1060!> \author Ole Schuett
1061! **************************************************************************************************
1062 SUBROUTINE torch_tensor_from_array_int64_3d(tensor, source, requires_grad)
1063 TYPE(torch_tensor_type), INTENT(INOUT) :: tensor
1064 INTEGER(kind=int_8), DIMENSION(:, :, :), ALLOCATABLE, INTENT(IN) :: source
1065 LOGICAL, OPTIONAL, INTENT(IN) :: requires_grad
1066
1067#if defined(__LIBTORCH)
1068 INTEGER(kind=int_8), DIMENSION(3) :: sizes_c
1069 LOGICAL :: my_req_grad
1070
1071 INTERFACE
1072 SUBROUTINE torch_c_tensor_from_array_int64 (tensor, req_grad, ndims, sizes, source) &
1073 BIND(C, name="torch_c_tensor_from_array_int64")
1074 IMPORT :: c_ptr, c_int, c_int32_t, c_int64_t, c_float, c_double, c_bool
1075 TYPE(c_ptr) :: tensor
1076 LOGICAL(kind=C_BOOL), VALUE :: req_grad
1077 INTEGER(kind=C_INT), VALUE :: ndims
1078 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
1079 INTEGER(kind=C_INT64_T), DIMENSION(*) :: source
1080 END SUBROUTINE torch_c_tensor_from_array_int64
1081 END INTERFACE
1082
1083 my_req_grad = .false.
1084 IF (PRESENT(requires_grad)) my_req_grad = requires_grad
1085
1086 sizes_c(1) = SIZE(source, 3) ! C arrays are stored row-major.
1087 sizes_c(2) = SIZE(source, 2) ! C arrays are stored row-major.
1088 sizes_c(3) = SIZE(source, 1) ! C arrays are stored row-major.
1089
1090 cpassert(.NOT. c_associated(tensor%c_ptr))
1091 CALL torch_c_tensor_from_array_int64 (tensor=tensor%c_ptr, &
1092 req_grad=LOGICAL(my_req_grad, C_BOOL), &
1093 ndims=3, &
1094 sizes=sizes_c, &
1095 source=source)
1096 cpassert(c_associated(tensor%c_ptr))
1097#else
1098 cpabort("CP2K compiled without the Torch library.")
1099 mark_used(tensor)
1100 mark_used(source)
1101 mark_used(requires_grad)
1102#endif
1103 END SUBROUTINE torch_tensor_from_array_int64_3d
1104
1105! **************************************************************************************************
1106!> \brief Copies data from a Torch tensor to an array.
1107!> The returned pointer is only valide during the tensor's lifetime!
1108!> \author Ole Schuett
1109! **************************************************************************************************
1110 SUBROUTINE torch_tensor_data_ptr_int64_3d(tensor, data_ptr)
1111 TYPE(torch_tensor_type), INTENT(IN) :: tensor
1112 INTEGER(kind=int_8), DIMENSION(:, :, :), POINTER :: data_ptr
1113
1114#if defined(__LIBTORCH)
1115 INTEGER(kind=int_8), DIMENSION(3) :: sizes_f, sizes_c
1116 TYPE(c_ptr) :: data_ptr_c
1117
1118 INTERFACE
1119 SUBROUTINE torch_c_tensor_data_ptr_int64 (tensor, ndims, sizes, data_ptr) &
1120 BIND(C, name="torch_c_tensor_data_ptr_int64")
1121 IMPORT :: c_char, c_ptr, c_int, c_int32_t, c_int64_t
1122 TYPE(c_ptr), VALUE :: tensor
1123 INTEGER(kind=C_INT), VALUE :: ndims
1124 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
1125 TYPE(c_ptr) :: data_ptr
1126 END SUBROUTINE torch_c_tensor_data_ptr_int64
1127 END INTERFACE
1128
1129 sizes_c(:) = -1
1130 data_ptr_c = c_null_ptr
1131 cpassert(c_associated(tensor%c_ptr))
1132 cpassert(.NOT. ASSOCIATED(data_ptr))
1133 CALL torch_c_tensor_data_ptr_int64 (tensor=tensor%c_ptr, &
1134 ndims=3, &
1135 sizes=sizes_c, &
1136 data_ptr=data_ptr_c)
1137
1138 sizes_f(1) = sizes_c(3) ! C arrays are stored row-major.
1139 sizes_f(2) = sizes_c(2) ! C arrays are stored row-major.
1140 sizes_f(3) = sizes_c(1) ! C arrays are stored row-major.
1141
1142 IF (all(sizes_f /= 0)) THEN ! Torch returns null pointer for zero-sized tensors.
1143 cpassert(c_associated(data_ptr_c))
1144 CALL c_f_pointer(data_ptr_c, data_ptr, shape=sizes_f)
1145 END IF
1146#else
1147 cpabort("CP2K compiled without the Torch library.")
1148 mark_used(tensor)
1149 mark_used(data_ptr)
1150#endif
1151 END SUBROUTINE torch_tensor_data_ptr_int64_3d
1152
1153
1154! **************************************************************************************************
1155!> \brief Creates a Torch tensor from an array. The passed array has to outlive the tensor!
1156!> The source must be an ALLOCATABLE to prevent passing a temporary array.
1157!> \author Ole Schuett
1158! **************************************************************************************************
1159 SUBROUTINE torch_tensor_from_array_double_3d(tensor, source, requires_grad)
1160 TYPE(torch_tensor_type), INTENT(INOUT) :: tensor
1161 REAL(dp), DIMENSION(:, :, :), ALLOCATABLE, INTENT(IN) :: source
1162 LOGICAL, OPTIONAL, INTENT(IN) :: requires_grad
1163
1164#if defined(__LIBTORCH)
1165 INTEGER(kind=int_8), DIMENSION(3) :: sizes_c
1166 LOGICAL :: my_req_grad
1167
1168 INTERFACE
1169 SUBROUTINE torch_c_tensor_from_array_double (tensor, req_grad, ndims, sizes, source) &
1170 BIND(C, name="torch_c_tensor_from_array_double")
1171 IMPORT :: c_ptr, c_int, c_int32_t, c_int64_t, c_float, c_double, c_bool
1172 TYPE(c_ptr) :: tensor
1173 LOGICAL(kind=C_BOOL), VALUE :: req_grad
1174 INTEGER(kind=C_INT), VALUE :: ndims
1175 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
1176 REAL(kind=c_double), DIMENSION(*) :: source
1177 END SUBROUTINE torch_c_tensor_from_array_double
1178 END INTERFACE
1179
1180 my_req_grad = .false.
1181 IF (PRESENT(requires_grad)) my_req_grad = requires_grad
1182
1183 sizes_c(1) = SIZE(source, 3) ! C arrays are stored row-major.
1184 sizes_c(2) = SIZE(source, 2) ! C arrays are stored row-major.
1185 sizes_c(3) = SIZE(source, 1) ! C arrays are stored row-major.
1186
1187 cpassert(.NOT. c_associated(tensor%c_ptr))
1188 CALL torch_c_tensor_from_array_double (tensor=tensor%c_ptr, &
1189 req_grad=LOGICAL(my_req_grad, C_BOOL), &
1190 ndims=3, &
1191 sizes=sizes_c, &
1192 source=source)
1193 cpassert(c_associated(tensor%c_ptr))
1194#else
1195 cpabort("CP2K compiled without the Torch library.")
1196 mark_used(tensor)
1197 mark_used(source)
1198 mark_used(requires_grad)
1199#endif
1200 END SUBROUTINE torch_tensor_from_array_double_3d
1201
1202! **************************************************************************************************
1203!> \brief Copies data from a Torch tensor to an array.
1204!> The returned pointer is only valide during the tensor's lifetime!
1205!> \author Ole Schuett
1206! **************************************************************************************************
1207 SUBROUTINE torch_tensor_data_ptr_double_3d(tensor, data_ptr)
1208 TYPE(torch_tensor_type), INTENT(IN) :: tensor
1209 REAL(dp), DIMENSION(:, :, :), POINTER :: data_ptr
1210
1211#if defined(__LIBTORCH)
1212 INTEGER(kind=int_8), DIMENSION(3) :: sizes_f, sizes_c
1213 TYPE(c_ptr) :: data_ptr_c
1214
1215 INTERFACE
1216 SUBROUTINE torch_c_tensor_data_ptr_double (tensor, ndims, sizes, data_ptr) &
1217 BIND(C, name="torch_c_tensor_data_ptr_double")
1218 IMPORT :: c_char, c_ptr, c_int, c_int32_t, c_int64_t
1219 TYPE(c_ptr), VALUE :: tensor
1220 INTEGER(kind=C_INT), VALUE :: ndims
1221 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
1222 TYPE(c_ptr) :: data_ptr
1223 END SUBROUTINE torch_c_tensor_data_ptr_double
1224 END INTERFACE
1225
1226 sizes_c(:) = -1
1227 data_ptr_c = c_null_ptr
1228 cpassert(c_associated(tensor%c_ptr))
1229 cpassert(.NOT. ASSOCIATED(data_ptr))
1230 CALL torch_c_tensor_data_ptr_double (tensor=tensor%c_ptr, &
1231 ndims=3, &
1232 sizes=sizes_c, &
1233 data_ptr=data_ptr_c)
1234
1235 sizes_f(1) = sizes_c(3) ! C arrays are stored row-major.
1236 sizes_f(2) = sizes_c(2) ! C arrays are stored row-major.
1237 sizes_f(3) = sizes_c(1) ! C arrays are stored row-major.
1238
1239 IF (all(sizes_f /= 0)) THEN ! Torch returns null pointer for zero-sized tensors.
1240 cpassert(c_associated(data_ptr_c))
1241 CALL c_f_pointer(data_ptr_c, data_ptr, shape=sizes_f)
1242 END IF
1243#else
1244 cpabort("CP2K compiled without the Torch library.")
1245 mark_used(tensor)
1246 mark_used(data_ptr)
1247#endif
1248 END SUBROUTINE torch_tensor_data_ptr_double_3d
1249
1250
1251
1252! **************************************************************************************************
1253!> \brief Reuses or creates a device leaf tensor and copies data into it.
1254!> The source must be an ALLOCATABLE to prevent passing a temporary array.
1255! **************************************************************************************************
1256 SUBROUTINE torch_tensor_reset_from_array_double_1d(tensor, source, requires_grad)
1257 TYPE(torch_tensor_type), INTENT(INOUT) :: tensor
1258 REAL(dp), DIMENSION(:), ALLOCATABLE, INTENT(IN) :: source
1259 LOGICAL, OPTIONAL, INTENT(IN) :: requires_grad
1260
1261#if defined(__LIBTORCH)
1262 INTEGER(kind=int_8), DIMENSION(1) :: sizes_c
1263 LOGICAL :: my_req_grad
1264
1265 INTERFACE
1266 SUBROUTINE torch_c_tensor_reset_from_array_double(tensor, req_grad, ndims, sizes, source) &
1267 BIND(C, name="torch_c_tensor_reset_from_array_double")
1268 IMPORT :: c_ptr, c_int, c_int64_t, c_double, c_bool
1269 TYPE(c_ptr) :: tensor
1270 LOGICAL(kind=C_BOOL), VALUE :: req_grad
1271 INTEGER(kind=C_INT), VALUE :: ndims
1272 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
1273 REAL(kind=c_double), DIMENSION(*) :: source
1274 END SUBROUTINE torch_c_tensor_reset_from_array_double
1275 END INTERFACE
1276
1277 my_req_grad = .false.
1278 IF (PRESENT(requires_grad)) my_req_grad = requires_grad
1279
1280 sizes_c(1) = SIZE(source, 1) ! C arrays are stored row-major.
1281
1282 CALL torch_c_tensor_reset_from_array_double(tensor=tensor%c_ptr, &
1283 req_grad=LOGICAL(my_req_grad, C_BOOL), &
1284 ndims=1, &
1285 sizes=sizes_c, &
1286 source=source)
1287 cpassert(c_associated(tensor%c_ptr))
1288#else
1289 cpabort("CP2K compiled without the Torch library.")
1290 mark_used(tensor)
1291 mark_used(source)
1292 mark_used(requires_grad)
1293#endif
1294 END SUBROUTINE torch_tensor_reset_from_array_double_1d
1295
1296
1297! **************************************************************************************************
1298!> \brief Reuses or creates a device leaf tensor and copies data into it.
1299!> The source must be an ALLOCATABLE to prevent passing a temporary array.
1300! **************************************************************************************************
1301 SUBROUTINE torch_tensor_reset_from_array_double_2d(tensor, source, requires_grad)
1302 TYPE(torch_tensor_type), INTENT(INOUT) :: tensor
1303 REAL(dp), DIMENSION(:, :), ALLOCATABLE, INTENT(IN) :: source
1304 LOGICAL, OPTIONAL, INTENT(IN) :: requires_grad
1305
1306#if defined(__LIBTORCH)
1307 INTEGER(kind=int_8), DIMENSION(2) :: sizes_c
1308 LOGICAL :: my_req_grad
1309
1310 INTERFACE
1311 SUBROUTINE torch_c_tensor_reset_from_array_double(tensor, req_grad, ndims, sizes, source) &
1312 BIND(C, name="torch_c_tensor_reset_from_array_double")
1313 IMPORT :: c_ptr, c_int, c_int64_t, c_double, c_bool
1314 TYPE(c_ptr) :: tensor
1315 LOGICAL(kind=C_BOOL), VALUE :: req_grad
1316 INTEGER(kind=C_INT), VALUE :: ndims
1317 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
1318 REAL(kind=c_double), DIMENSION(*) :: source
1319 END SUBROUTINE torch_c_tensor_reset_from_array_double
1320 END INTERFACE
1321
1322 my_req_grad = .false.
1323 IF (PRESENT(requires_grad)) my_req_grad = requires_grad
1324
1325 sizes_c(1) = SIZE(source, 2) ! C arrays are stored row-major.
1326 sizes_c(2) = SIZE(source, 1) ! C arrays are stored row-major.
1327
1328 CALL torch_c_tensor_reset_from_array_double(tensor=tensor%c_ptr, &
1329 req_grad=LOGICAL(my_req_grad, C_BOOL), &
1330 ndims=2, &
1331 sizes=sizes_c, &
1332 source=source)
1333 cpassert(c_associated(tensor%c_ptr))
1334#else
1335 cpabort("CP2K compiled without the Torch library.")
1336 mark_used(tensor)
1337 mark_used(source)
1338 mark_used(requires_grad)
1339#endif
1340 END SUBROUTINE torch_tensor_reset_from_array_double_2d
1341
1342
1343! **************************************************************************************************
1344!> \brief Reuses or creates a device leaf tensor and copies data into it.
1345!> The source must be an ALLOCATABLE to prevent passing a temporary array.
1346! **************************************************************************************************
1347 SUBROUTINE torch_tensor_reset_from_array_double_3d(tensor, source, requires_grad)
1348 TYPE(torch_tensor_type), INTENT(INOUT) :: tensor
1349 REAL(dp), DIMENSION(:, :, :), ALLOCATABLE, INTENT(IN) :: source
1350 LOGICAL, OPTIONAL, INTENT(IN) :: requires_grad
1351
1352#if defined(__LIBTORCH)
1353 INTEGER(kind=int_8), DIMENSION(3) :: sizes_c
1354 LOGICAL :: my_req_grad
1355
1356 INTERFACE
1357 SUBROUTINE torch_c_tensor_reset_from_array_double(tensor, req_grad, ndims, sizes, source) &
1358 BIND(C, name="torch_c_tensor_reset_from_array_double")
1359 IMPORT :: c_ptr, c_int, c_int64_t, c_double, c_bool
1360 TYPE(c_ptr) :: tensor
1361 LOGICAL(kind=C_BOOL), VALUE :: req_grad
1362 INTEGER(kind=C_INT), VALUE :: ndims
1363 INTEGER(kind=C_INT64_T), DIMENSION(*) :: sizes
1364 REAL(kind=c_double), DIMENSION(*) :: source
1365 END SUBROUTINE torch_c_tensor_reset_from_array_double
1366 END INTERFACE
1367
1368 my_req_grad = .false.
1369 IF (PRESENT(requires_grad)) my_req_grad = requires_grad
1370
1371 sizes_c(1) = SIZE(source, 3) ! C arrays are stored row-major.
1372 sizes_c(2) = SIZE(source, 2) ! C arrays are stored row-major.
1373 sizes_c(3) = SIZE(source, 1) ! C arrays are stored row-major.
1374
1375 CALL torch_c_tensor_reset_from_array_double(tensor=tensor%c_ptr, &
1376 req_grad=LOGICAL(my_req_grad, C_BOOL), &
1377 ndims=3, &
1378 sizes=sizes_c, &
1379 source=source)
1380 cpassert(c_associated(tensor%c_ptr))
1381#else
1382 cpabort("CP2K compiled without the Torch library.")
1383 mark_used(tensor)
1384 mark_used(source)
1385 mark_used(requires_grad)
1386#endif
1387 END SUBROUTINE torch_tensor_reset_from_array_double_3d
1388
1389
1390! **************************************************************************************************
1391!> \brief Creates an expanded tensor view along one singleton dimension.
1392! **************************************************************************************************
1393 SUBROUTINE torch_tensor_expand_dim(tensor, dim, extent, result)
1394 TYPE(torch_tensor_type), INTENT(IN) :: tensor
1395 INTEGER, INTENT(IN) :: dim, extent
1396 TYPE(torch_tensor_type), INTENT(INOUT) :: result
1397
1398#if defined(__LIBTORCH)
1399 INTERFACE
1400 SUBROUTINE torch_c_tensor_expand_dim(tensor, dim, extent, result) &
1401 BIND(C, name="torch_c_tensor_expand_dim")
1402 IMPORT :: c_int64_t, c_ptr
1403 TYPE(c_ptr), VALUE :: tensor
1404 INTEGER(kind=C_INT64_T), VALUE :: dim, extent
1405 TYPE(c_ptr) :: result
1406 END SUBROUTINE torch_c_tensor_expand_dim
1407 END INTERFACE
1408
1409 cpassert(c_associated(tensor%c_ptr))
1410 cpassert(.NOT. c_associated(result%c_ptr))
1411 cpassert(dim >= 0)
1412 cpassert(extent >= 0)
1413 CALL torch_c_tensor_expand_dim(tensor=tensor%c_ptr, &
1414 dim=int(dim, c_int64_t), &
1415 extent=int(extent, c_int64_t), &
1416 result=result%c_ptr)
1417 cpassert(c_associated(result%c_ptr))
1418#else
1419 cpabort("CP2K compiled without the Torch library.")
1420 mark_used(tensor)
1421 mark_used(dim)
1422 mark_used(extent)
1423 mark_used(result)
1424#endif
1425 END SUBROUTINE torch_tensor_expand_dim
1426
1427! **************************************************************************************************
1428!> \brief Creates a view of a contiguous tensor slice.
1429! **************************************************************************************************
1430 SUBROUTINE torch_tensor_narrow(tensor, dim, start_index, length, result)
1431 TYPE(torch_tensor_type), INTENT(IN) :: tensor
1432 INTEGER, INTENT(IN) :: dim, start_index, length
1433 TYPE(torch_tensor_type), INTENT(INOUT) :: result
1434
1435#if defined(__LIBTORCH)
1436 INTERFACE
1437 SUBROUTINE torch_c_tensor_narrow(tensor, dim, start_index, length, result) &
1438 BIND(C, name="torch_c_tensor_narrow")
1439 IMPORT :: c_int64_t, c_ptr
1440 TYPE(c_ptr), VALUE :: tensor
1441 INTEGER(kind=C_INT64_T), VALUE :: dim, start_index, length
1442 TYPE(c_ptr) :: result
1443 END SUBROUTINE torch_c_tensor_narrow
1444 END INTERFACE
1445
1446 cpassert(c_associated(tensor%c_ptr))
1447 cpassert(.NOT. c_associated(result%c_ptr))
1448 cpassert(dim >= 0)
1449 cpassert(start_index >= 0)
1450 cpassert(length >= 0)
1451 CALL torch_c_tensor_narrow(tensor=tensor%c_ptr, &
1452 dim=int(dim, c_int64_t), &
1453 start_index=int(start_index, c_int64_t), &
1454 length=int(length, c_int64_t), &
1455 result=result%c_ptr)
1456 cpassert(c_associated(result%c_ptr))
1457#else
1458 cpabort("CP2K compiled without the Torch library.")
1459 mark_used(tensor)
1460 mark_used(dim)
1461 mark_used(start_index)
1462 mark_used(length)
1463 mark_used(result)
1464#endif
1465 END SUBROUTINE torch_tensor_narrow
1466
1467! **************************************************************************************************
1468!> \brief Runs autograd on a Torch tensor.
1469!> \author Ole Schuett
1470! **************************************************************************************************
1471 SUBROUTINE torch_tensor_backward(tensor, outer_grad)
1472 TYPE(torch_tensor_type), INTENT(IN) :: tensor
1473 TYPE(torch_tensor_type), INTENT(IN) :: outer_grad
1474
1475#if defined(__LIBTORCH)
1476 CHARACTER(len=*), PARAMETER :: routinen = 'torch_tensor_backward'
1477 INTEGER :: handle
1478
1479 INTERFACE
1480 SUBROUTINE torch_c_tensor_backward(tensor, outer_grad) &
1481 BIND(C, name="torch_c_tensor_backward")
1482 IMPORT :: c_char, c_ptr
1483 TYPE(c_ptr), VALUE :: tensor
1484 TYPE(c_ptr), VALUE :: outer_grad
1485 END SUBROUTINE torch_c_tensor_backward
1486 END INTERFACE
1487
1488 CALL timeset(routinen, handle)
1489 cpassert(c_associated(tensor%c_ptr))
1490 cpassert(c_associated(outer_grad%c_ptr))
1491 CALL torch_c_tensor_backward(tensor=tensor%c_ptr, outer_grad=outer_grad%c_ptr)
1492 CALL timestop(handle)
1493#else
1494 cpabort("CP2K compiled without the Torch library.")
1495 mark_used(tensor)
1496 mark_used(outer_grad)
1497#endif
1498 END SUBROUTINE torch_tensor_backward
1499
1500! **************************************************************************************************
1501!> \brief Runs autograd on a scalar Torch tensor.
1502! **************************************************************************************************
1504 TYPE(torch_tensor_type), INTENT(IN) :: tensor
1505
1506#if defined(__LIBTORCH)
1507 INTERFACE
1508 SUBROUTINE torch_c_tensor_backward_scalar(tensor) &
1509 BIND(C, name="torch_c_tensor_backward_scalar")
1510 IMPORT :: c_ptr
1511 TYPE(c_ptr), VALUE :: tensor
1512 END SUBROUTINE torch_c_tensor_backward_scalar
1513 END INTERFACE
1514
1515 cpassert(c_associated(tensor%c_ptr))
1516 CALL torch_c_tensor_backward_scalar(tensor=tensor%c_ptr)
1517#else
1518 cpabort("CP2K compiled without the Torch library.")
1519 mark_used(tensor)
1520#endif
1521 END SUBROUTINE torch_tensor_backward_scalar
1522
1523! **************************************************************************************************
1524!> \brief Moves a tensor to the active Torch device and makes it an autograd leaf.
1525! **************************************************************************************************
1526 SUBROUTINE torch_tensor_to_device_leaf(tensor, requires_grad)
1527 TYPE(torch_tensor_type), INTENT(INOUT) :: tensor
1528 LOGICAL, INTENT(IN) :: requires_grad
1529
1530#if defined(__LIBTORCH)
1531 INTERFACE
1532 SUBROUTINE torch_c_tensor_to_device_leaf(tensor, req_grad) &
1533 BIND(C, name="torch_c_tensor_to_device_leaf")
1534 IMPORT :: c_bool, c_ptr
1535 TYPE(c_ptr) :: tensor
1536 LOGICAL(kind=C_BOOL), VALUE :: req_grad
1537 END SUBROUTINE torch_c_tensor_to_device_leaf
1538 END INTERFACE
1539
1540 cpassert(c_associated(tensor%c_ptr))
1541 CALL torch_c_tensor_to_device_leaf(tensor=tensor%c_ptr, &
1542 req_grad=LOGICAL(requires_grad, c_bool))
1543 cpassert(c_associated(tensor%c_ptr))
1544#else
1545 cpabort("CP2K compiled without the Torch library.")
1546 mark_used(tensor)
1547 mark_used(requires_grad)
1548#endif
1549 END SUBROUTINE torch_tensor_to_device_leaf
1550
1551! **************************************************************************************************
1552!> \brief Select whether Torch wrappers should use CUDA when available.
1553! **************************************************************************************************
1554 SUBROUTINE torch_use_cuda(use_cuda)
1555 LOGICAL, INTENT(IN) :: use_cuda
1556
1557#if defined(__LIBTORCH)
1558 INTERFACE
1559 SUBROUTINE torch_c_use_cuda(use_cuda) BIND(C, name="torch_c_use_cuda")
1560 IMPORT :: c_bool
1561 LOGICAL(kind=C_BOOL), VALUE :: use_cuda
1562 END SUBROUTINE torch_c_use_cuda
1563 END INTERFACE
1564
1565 CALL torch_c_use_cuda(use_cuda=LOGICAL(use_cuda, c_bool))
1566#else
1567 mark_used(use_cuda)
1568#endif
1569 END SUBROUTINE torch_use_cuda
1570
1571! **************************************************************************************************
1572!> \brief Returns the gradient of a Torch tensor which was computed by autograd.
1573!> \author Ole Schuett
1574! **************************************************************************************************
1575 SUBROUTINE torch_tensor_grad(tensor, grad)
1576 TYPE(torch_tensor_type), INTENT(IN) :: tensor
1577 TYPE(torch_tensor_type), INTENT(INOUT) :: grad
1578
1579#if defined(__LIBTORCH)
1580 INTERFACE
1581 SUBROUTINE torch_c_tensor_grad(tensor, grad) &
1582 BIND(C, name="torch_c_tensor_grad")
1583 IMPORT :: c_ptr
1584 TYPE(c_ptr), VALUE :: tensor
1585 TYPE(c_ptr) :: grad
1586 END SUBROUTINE torch_c_tensor_grad
1587 END INTERFACE
1588
1589 cpassert(c_associated(tensor%c_ptr))
1590 cpassert(.NOT. c_associated(grad%c_ptr))
1591 CALL torch_c_tensor_grad(tensor=tensor%c_ptr, grad=grad%c_ptr)
1592 cpassert(c_associated(grad%c_ptr))
1593#else
1594 cpabort("CP2K compiled without the Torch library.")
1595 mark_used(tensor)
1596 mark_used(grad)
1597#endif
1598 END SUBROUTINE torch_tensor_grad
1599
1600! **************************************************************************************************
1601!> \brief Copies three autograd gradients to CPU memory.
1602! **************************************************************************************************
1603 SUBROUTINE torch_tensor_grad_batch3(tensor1, tensor2, tensor3, grad1, grad2, grad3)
1604 TYPE(torch_tensor_type), INTENT(IN) :: tensor1, tensor2, tensor3
1605 TYPE(torch_tensor_type), INTENT(INOUT) :: grad1, grad2, grad3
1606
1607#if defined(__LIBTORCH)
1608 INTERFACE
1609 SUBROUTINE torch_c_tensor_grad_batch3(tensor1, tensor2, tensor3, grad1, grad2, grad3) &
1610 BIND(C, name="torch_c_tensor_grad_batch3")
1611 IMPORT :: c_ptr
1612 TYPE(c_ptr), VALUE :: tensor1, tensor2, tensor3
1613 TYPE(c_ptr) :: grad1, grad2, grad3
1614 END SUBROUTINE torch_c_tensor_grad_batch3
1615 END INTERFACE
1616
1617 cpassert(c_associated(tensor1%c_ptr))
1618 cpassert(c_associated(tensor2%c_ptr))
1619 cpassert(c_associated(tensor3%c_ptr))
1620 cpassert(.NOT. c_associated(grad1%c_ptr))
1621 cpassert(.NOT. c_associated(grad2%c_ptr))
1622 cpassert(.NOT. c_associated(grad3%c_ptr))
1623 CALL torch_c_tensor_grad_batch3(tensor1=tensor1%c_ptr, tensor2=tensor2%c_ptr, &
1624 tensor3=tensor3%c_ptr, grad1=grad1%c_ptr, &
1625 grad2=grad2%c_ptr, grad3=grad3%c_ptr)
1626 cpassert(c_associated(grad1%c_ptr))
1627 cpassert(c_associated(grad2%c_ptr))
1628 cpassert(c_associated(grad3%c_ptr))
1629#else
1630 cpabort("CP2K compiled without the Torch library.")
1631 mark_used(tensor1)
1632 mark_used(tensor2)
1633 mark_used(tensor3)
1634 mark_used(grad1)
1635 mark_used(grad2)
1636 mark_used(grad3)
1637#endif
1638 END SUBROUTINE torch_tensor_grad_batch3
1639
1640! **************************************************************************************************
1641!> \brief Returns the weighted sum of two Torch tensors.
1642! **************************************************************************************************
1643 SUBROUTINE torch_tensor_weighted_sum(values, weights, result)
1644 TYPE(torch_tensor_type), INTENT(IN) :: values, weights
1645 TYPE(torch_tensor_type), INTENT(INOUT) :: result
1646
1647#if defined(__LIBTORCH)
1648 INTERFACE
1649 SUBROUTINE torch_c_tensor_weighted_sum(values, weights, result) &
1650 BIND(C, name="torch_c_tensor_weighted_sum")
1651 IMPORT :: c_ptr
1652 TYPE(c_ptr), VALUE :: values
1653 TYPE(c_ptr), VALUE :: weights
1654 TYPE(c_ptr) :: result
1655 END SUBROUTINE torch_c_tensor_weighted_sum
1656 END INTERFACE
1657
1658 cpassert(c_associated(values%c_ptr))
1659 cpassert(c_associated(weights%c_ptr))
1660 cpassert(.NOT. c_associated(result%c_ptr))
1661 CALL torch_c_tensor_weighted_sum(values=values%c_ptr, weights=weights%c_ptr, result=result%c_ptr)
1662 cpassert(c_associated(result%c_ptr))
1663#else
1664 cpabort("CP2K compiled without the Torch library.")
1665 mark_used(values)
1666 mark_used(weights)
1667 mark_used(result)
1668#endif
1669 END SUBROUTINE torch_tensor_weighted_sum
1670
1671! **************************************************************************************************
1672!> \brief Returns a scalar double value from a Torch tensor.
1673! **************************************************************************************************
1674 FUNCTION torch_tensor_item_double(tensor) RESULT(value)
1675 TYPE(torch_tensor_type), INTENT(IN) :: tensor
1676 REAL(kind=dp) :: value
1677
1678#if defined(__LIBTORCH)
1679 INTERFACE
1680 FUNCTION torch_c_tensor_item_double(tensor) RESULT(value) &
1681 BIND(C, name="torch_c_tensor_item_double")
1682 IMPORT :: c_double, c_ptr
1683 TYPE(c_ptr), VALUE :: tensor
1684 REAL(kind=c_double) :: value
1685 END FUNCTION torch_c_tensor_item_double
1686 END INTERFACE
1687
1688 cpassert(c_associated(tensor%c_ptr))
1689 value = torch_c_tensor_item_double(tensor=tensor%c_ptr)
1690#else
1691 value = 0.0_dp
1692 cpabort("CP2K compiled without the Torch library.")
1693 mark_used(tensor)
1694#endif
1695 END FUNCTION torch_tensor_item_double
1696
1697! **************************************************************************************************
1698!> \brief Releases a Torch tensor and all its ressources.
1699!> \author Ole Schuett
1700! **************************************************************************************************
1701 SUBROUTINE torch_tensor_release(tensor)
1702 TYPE(torch_tensor_type), INTENT(INOUT) :: tensor
1703
1704#if defined(__LIBTORCH)
1705 INTERFACE
1706 SUBROUTINE torch_c_tensor_release(tensor) BIND(C, name="torch_c_tensor_release")
1707 IMPORT :: c_ptr
1708 TYPE(c_ptr), VALUE :: tensor
1709 END SUBROUTINE torch_c_tensor_release
1710 END INTERFACE
1711
1712 cpassert(c_associated(tensor%c_ptr))
1713 CALL torch_c_tensor_release(tensor=tensor%c_ptr)
1714 tensor%c_ptr = c_null_ptr
1715#else
1716 cpabort("CP2K was compiled without Torch library.")
1717 mark_used(tensor)
1718#endif
1719 END SUBROUTINE torch_tensor_release
1720
1721! **************************************************************************************************
1722!> \brief Creates an empty Torch dictionary.
1723!> \author Ole Schuett
1724! **************************************************************************************************
1725 SUBROUTINE torch_dict_create(dict)
1726 TYPE(torch_dict_type), INTENT(INOUT) :: dict
1727
1728#if defined(__LIBTORCH)
1729 INTERFACE
1730 SUBROUTINE torch_c_dict_create(dict) BIND(C, name="torch_c_dict_create")
1731 IMPORT :: c_ptr
1732 TYPE(c_ptr) :: dict
1733 END SUBROUTINE torch_c_dict_create
1734 END INTERFACE
1735
1736 cpassert(.NOT. c_associated(dict%c_ptr))
1737 CALL torch_c_dict_create(dict=dict%c_ptr)
1738 cpassert(c_associated(dict%c_ptr))
1739#else
1740 cpabort("CP2K was compiled without Torch library.")
1741 mark_used(dict)
1742#endif
1743 END SUBROUTINE torch_dict_create
1744
1745! **************************************************************************************************
1746!> \brief Clones a Torch dictionary.
1747! **************************************************************************************************
1748 SUBROUTINE torch_dict_clone(source, target)
1749 TYPE(torch_dict_type), INTENT(IN) :: source
1750 TYPE(torch_dict_type), INTENT(INOUT) :: target
1751
1752#if defined(__LIBTORCH)
1753 INTERFACE
1754 SUBROUTINE torch_c_dict_clone(source, target) BIND(C, name="torch_c_dict_clone")
1755 IMPORT :: c_ptr
1756 TYPE(c_ptr), VALUE :: source
1757 TYPE(c_ptr) :: target
1758 END SUBROUTINE torch_c_dict_clone
1759 END INTERFACE
1760
1761 cpassert(c_associated(source%c_ptr))
1762 cpassert(.NOT. c_associated(target%c_ptr))
1763 CALL torch_c_dict_clone(source=source%c_ptr, target=target%c_ptr)
1764 cpassert(c_associated(target%c_ptr))
1765#else
1766 cpabort("CP2K was compiled without Torch library.")
1767 mark_used(source)
1768 mark_used(target)
1769#endif
1770 END SUBROUTINE torch_dict_clone
1771
1772! **************************************************************************************************
1773!> \brief Inserts a Torch tensor into a Torch dictionary.
1774!> \author Ole Schuett
1775! **************************************************************************************************
1776 SUBROUTINE torch_dict_insert(dict, key, tensor)
1777 TYPE(torch_dict_type), INTENT(INOUT) :: dict
1778 CHARACTER(len=*), INTENT(IN) :: key
1779 TYPE(torch_tensor_type), INTENT(IN) :: tensor
1780
1781#if defined(__LIBTORCH)
1782
1783 INTERFACE
1784 SUBROUTINE torch_c_dict_insert(dict, key, tensor) &
1785 BIND(C, name="torch_c_dict_insert")
1786 IMPORT :: c_char, c_ptr
1787 TYPE(c_ptr), VALUE :: dict
1788 CHARACTER(kind=C_CHAR), DIMENSION(*) :: key
1789 TYPE(c_ptr), VALUE :: tensor
1790 END SUBROUTINE torch_c_dict_insert
1791 END INTERFACE
1792
1793 cpassert(c_associated(dict%c_ptr))
1794 cpassert(c_associated(tensor%c_ptr))
1795 CALL torch_c_dict_insert(dict=dict%c_ptr, key=trim(key)//c_null_char, tensor=tensor%c_ptr)
1796#else
1797 cpabort("CP2K compiled without the Torch library.")
1798 mark_used(dict)
1799 mark_used(key)
1800 mark_used(tensor)
1801#endif
1802 END SUBROUTINE torch_dict_insert
1803
1804! **************************************************************************************************
1805!> \brief Retrieves a Torch tensor from a Torch dictionary.
1806!> \author Ole Schuett
1807! **************************************************************************************************
1808 SUBROUTINE torch_dict_get(dict, key, tensor)
1809 TYPE(torch_dict_type), INTENT(IN) :: dict
1810 CHARACTER(len=*), INTENT(IN) :: key
1811 TYPE(torch_tensor_type), INTENT(INOUT) :: tensor
1812
1813#if defined(__LIBTORCH)
1814
1815 INTERFACE
1816 SUBROUTINE torch_c_dict_get(dict, key, tensor) &
1817 BIND(C, name="torch_c_dict_get")
1818 IMPORT :: c_char, c_ptr
1819 TYPE(c_ptr), VALUE :: dict
1820 CHARACTER(kind=C_CHAR), DIMENSION(*) :: key
1821 TYPE(c_ptr) :: tensor
1822 END SUBROUTINE torch_c_dict_get
1823 END INTERFACE
1824
1825 cpassert(c_associated(dict%c_ptr))
1826 cpassert(.NOT. c_associated(tensor%c_ptr))
1827 CALL torch_c_dict_get(dict=dict%c_ptr, key=trim(key)//c_null_char, tensor=tensor%c_ptr)
1828 cpassert(c_associated(tensor%c_ptr))
1829
1830#else
1831 cpabort("CP2K compiled without the Torch library.")
1832 mark_used(dict)
1833 mark_used(key)
1834 mark_used(tensor)
1835#endif
1836 END SUBROUTINE torch_dict_get
1837
1838! **************************************************************************************************
1839!> \brief Releases a Torch dictionary and all its ressources.
1840!> \author Ole Schuett
1841! **************************************************************************************************
1842 SUBROUTINE torch_dict_release(dict)
1843 TYPE(torch_dict_type), INTENT(INOUT) :: dict
1844
1845#if defined(__LIBTORCH)
1846 INTERFACE
1847 SUBROUTINE torch_c_dict_release(dict) BIND(C, name="torch_c_dict_release")
1848 IMPORT :: c_ptr
1849 TYPE(c_ptr), VALUE :: dict
1850 END SUBROUTINE torch_c_dict_release
1851 END INTERFACE
1852
1853 cpassert(c_associated(dict%c_ptr))
1854 CALL torch_c_dict_release(dict=dict%c_ptr)
1855 dict%c_ptr = c_null_ptr
1856#else
1857 cpabort("CP2K was compiled without Torch library.")
1858 mark_used(dict)
1859#endif
1860 END SUBROUTINE torch_dict_release
1861
1862! **************************************************************************************************
1863!> \brief Loads a Torch model from given "*.pth" file. (In Torch lingo models are called modules)
1864!> \author Ole Schuett
1865! **************************************************************************************************
1866 SUBROUTINE torch_model_load(model, filename)
1867 TYPE(torch_model_type), INTENT(INOUT) :: model
1868 CHARACTER(len=*), INTENT(IN) :: filename
1869
1870#if defined(__LIBTORCH)
1871 CHARACTER(len=*), PARAMETER :: routinen = 'torch_model_load'
1872 INTEGER :: handle
1873
1874 INTERFACE
1875 SUBROUTINE torch_c_model_load(model, filename) BIND(C, name="torch_c_model_load")
1876 IMPORT :: c_ptr, c_char
1877 TYPE(c_ptr) :: model
1878 CHARACTER(kind=C_CHAR), DIMENSION(*) :: filename
1879 END SUBROUTINE torch_c_model_load
1880 END INTERFACE
1881
1882 CALL timeset(routinen, handle)
1883 cpassert(.NOT. c_associated(model%c_ptr))
1884 CALL torch_c_model_load(model=model%c_ptr, filename=trim(filename)//c_null_char)
1885 cpassert(c_associated(model%c_ptr))
1886 CALL timestop(handle)
1887#else
1888 cpabort("CP2K was compiled without Torch library.")
1889 mark_used(model)
1890 mark_used(filename)
1891#endif
1892 END SUBROUTINE torch_model_load
1893
1894! **************************************************************************************************
1895!> \brief Loads a Torch model and reads two metadata entries in the same archive pass.
1896! **************************************************************************************************
1897 SUBROUTINE torch_model_load_with_metadata(model, filename, key1, value1, key2, value2)
1898 TYPE(torch_model_type), INTENT(INOUT) :: model
1899 CHARACTER(len=*), INTENT(IN) :: filename, key1, key2
1900 CHARACTER(:), ALLOCATABLE, INTENT(OUT) :: value1, value2
1901
1902#if defined(__LIBTORCH)
1903 CHARACTER(len=*), PARAMETER :: routinen = 'torch_model_load_with_metadata'
1904 INTEGER :: handle, length1, length2
1905 TYPE(c_ptr) :: content1_c, content2_c
1906
1907 INTERFACE
1908 SUBROUTINE torch_c_model_load_with_metadata(model, filename, key1, key2, &
1909 content1, length1, content2, length2) &
1910 BIND(C, name="torch_c_model_load_with_metadata")
1911 IMPORT :: c_char, c_int, c_ptr
1912 TYPE(c_ptr) :: model
1913 CHARACTER(kind=C_CHAR), DIMENSION(*) :: filename, key1, key2
1914 TYPE(c_ptr) :: content1, content2
1915 INTEGER(kind=C_INT) :: length1, length2
1916 END SUBROUTINE torch_c_model_load_with_metadata
1917 END INTERFACE
1918
1919 CALL timeset(routinen, handle)
1920 cpassert(.NOT. c_associated(model%c_ptr))
1921 content1_c = c_null_ptr
1922 content2_c = c_null_ptr
1923 length1 = -1
1924 length2 = -1
1925 CALL torch_c_model_load_with_metadata(model=model%c_ptr, &
1926 filename=trim(filename)//c_null_char, &
1927 key1=trim(key1)//c_null_char, &
1928 key2=trim(key2)//c_null_char, &
1929 content1=content1_c, length1=length1, &
1930 content2=content2_c, length2=length2)
1931 cpassert(c_associated(model%c_ptr))
1932 CALL c_string_to_allocatable(content1_c, length1, value1)
1933 CALL c_string_to_allocatable(content2_c, length2, value2)
1934 CALL timestop(handle)
1935#else
1936 cpabort("CP2K was compiled without Torch library.")
1937 mark_used(model)
1938 mark_used(filename)
1939 mark_used(key1)
1940 mark_used(value1)
1941 mark_used(key2)
1942 mark_used(value2)
1943#endif
1944 END SUBROUTINE torch_model_load_with_metadata
1945
1946! **************************************************************************************************
1947!> \brief Maps serialized TorchScript device constants to the active Torch device.
1948! **************************************************************************************************
1950 TYPE(torch_model_type), INTENT(INOUT) :: model
1951
1952#if defined(__LIBTORCH)
1953 INTERFACE
1954 SUBROUTINE torch_c_model_remap_device_constants(model) &
1955 BIND(C, name="torch_c_model_remap_device_constants")
1956 IMPORT :: c_ptr
1957 TYPE(c_ptr), VALUE :: model
1958 END SUBROUTINE torch_c_model_remap_device_constants
1959 END INTERFACE
1960
1961 cpassert(c_associated(model%c_ptr))
1962 CALL torch_c_model_remap_device_constants(model=model%c_ptr)
1963#else
1964 cpabort("CP2K was compiled without Torch library.")
1965 mark_used(model)
1966#endif
1968
1969! **************************************************************************************************
1970!> \brief Promote float32 model state and explicit floating-point casts to double precision.
1971! **************************************************************************************************
1973 TYPE(torch_model_type), INTENT(INOUT) :: model
1974
1975#if defined(__LIBTORCH)
1976 INTERFACE
1977 SUBROUTINE torch_c_model_promote_float32(model) BIND(C, name="torch_c_model_promote_float32")
1978 IMPORT :: c_ptr
1979 TYPE(c_ptr), VALUE :: model
1980 END SUBROUTINE torch_c_model_promote_float32
1981 END INTERFACE
1982
1983 cpassert(c_associated(model%c_ptr))
1984 CALL torch_c_model_promote_float32(model%c_ptr)
1985#else
1986 cpabort("CP2K was compiled without Torch library.")
1987 mark_used(model)
1988#endif
1989 END SUBROUTINE torch_model_promote_float32
1990
1991! **************************************************************************************************
1992!> \brief Disable gradients for inference-only model parameters.
1993! **************************************************************************************************
1995 TYPE(torch_model_type), INTENT(INOUT) :: model
1996
1997#if defined(__LIBTORCH)
1998 INTERFACE
1999 SUBROUTINE torch_c_model_disable_parameter_gradients(model) &
2000 BIND(C, name="torch_c_model_disable_parameter_gradients")
2001 IMPORT :: c_ptr
2002 TYPE(c_ptr), VALUE :: model
2003 END SUBROUTINE torch_c_model_disable_parameter_gradients
2004 END INTERFACE
2005
2006 cpassert(c_associated(model%c_ptr))
2007 CALL torch_c_model_disable_parameter_gradients(model=model%c_ptr)
2008#else
2009 cpabort("CP2K was compiled without Torch library.")
2010 mark_used(model)
2011#endif
2013
2014! **************************************************************************************************
2015!> \brief Evaluates the given Torch model.
2016!> \author Ole Schuett
2017! **************************************************************************************************
2018 SUBROUTINE torch_model_forward(model, inputs, outputs)
2019 TYPE(torch_model_type), INTENT(INOUT) :: model
2020 TYPE(torch_dict_type), INTENT(IN) :: inputs
2021 TYPE(torch_dict_type), INTENT(INOUT) :: outputs
2022
2023#if defined(__LIBTORCH)
2024 CHARACTER(len=*), PARAMETER :: routinen = 'torch_model_forward'
2025 INTEGER :: handle
2026
2027 INTERFACE
2028 SUBROUTINE torch_c_model_forward(model, inputs, outputs) BIND(C, name="torch_c_model_forward")
2029 IMPORT :: c_ptr
2030 TYPE(c_ptr), VALUE :: model
2031 TYPE(c_ptr), VALUE :: inputs
2032 TYPE(c_ptr), VALUE :: outputs
2033 END SUBROUTINE torch_c_model_forward
2034 END INTERFACE
2035
2036 CALL timeset(routinen, handle)
2037 cpassert(c_associated(model%c_ptr))
2038 cpassert(c_associated(inputs%c_ptr))
2039 cpassert(c_associated(outputs%c_ptr))
2040 CALL torch_c_model_forward(model=model%c_ptr, inputs=inputs%c_ptr, outputs=outputs%c_ptr)
2041 CALL timestop(handle)
2042#else
2043 cpabort("CP2K was compiled without Torch library.")
2044 mark_used(model)
2045 mark_used(inputs)
2046 mark_used(outputs)
2047#endif
2048 END SUBROUTINE torch_model_forward
2049
2050! **************************************************************************************************
2051!> \brief Evaluates a TorchScript model method expecting keyword argument "mol".
2052! **************************************************************************************************
2053 SUBROUTINE torch_model_forward_mol_tensor(model, method_name, inputs, output)
2054 TYPE(torch_model_type), INTENT(INOUT) :: model
2055 CHARACTER(len=*), INTENT(IN) :: method_name
2056 TYPE(torch_dict_type), INTENT(IN) :: inputs
2057 TYPE(torch_tensor_type), INTENT(INOUT) :: output
2058
2059#if defined(__LIBTORCH)
2060 CHARACTER(len=*), PARAMETER :: routinen = 'torch_model_forward_mol_tensor'
2061 INTEGER :: handle
2062
2063 INTERFACE
2064 SUBROUTINE torch_c_model_forward_mol_tensor(model, method_name, inputs, output) &
2065 BIND(C, name="torch_c_model_forward_mol_tensor")
2066 IMPORT :: c_char, c_ptr
2067 TYPE(c_ptr), VALUE :: model
2068 CHARACTER(kind=C_CHAR), DIMENSION(*) :: method_name
2069 TYPE(c_ptr), VALUE :: inputs
2070 TYPE(c_ptr) :: output
2071 END SUBROUTINE torch_c_model_forward_mol_tensor
2072 END INTERFACE
2073
2074 CALL timeset(routinen, handle)
2075 cpassert(c_associated(model%c_ptr))
2076 cpassert(c_associated(inputs%c_ptr))
2077 cpassert(.NOT. c_associated(output%c_ptr))
2078 CALL torch_c_model_forward_mol_tensor(model=model%c_ptr, &
2079 method_name=trim(method_name)//c_null_char, &
2080 inputs=inputs%c_ptr, &
2081 output=output%c_ptr)
2082 cpassert(c_associated(output%c_ptr))
2083 CALL timestop(handle)
2084#else
2085 cpabort("CP2K was compiled without Torch library.")
2086 mark_used(model)
2087 mark_used(method_name)
2088 mark_used(inputs)
2089 mark_used(output)
2090#endif
2091 END SUBROUTINE torch_model_forward_mol_tensor
2092
2093! **************************************************************************************************
2094!> \brief Releases a Torch model and all its ressources.
2095!> \author Ole Schuett
2096! **************************************************************************************************
2097 SUBROUTINE torch_model_release(model)
2098 TYPE(torch_model_type), INTENT(INOUT) :: model
2099
2100#if defined(__LIBTORCH)
2101 INTERFACE
2102 SUBROUTINE torch_c_model_release(model) BIND(C, name="torch_c_model_release")
2103 IMPORT :: c_ptr
2104 TYPE(c_ptr), VALUE :: model
2105 END SUBROUTINE torch_c_model_release
2106 END INTERFACE
2107
2108 cpassert(c_associated(model%c_ptr))
2109 CALL torch_c_model_release(model=model%c_ptr)
2110 model%c_ptr = c_null_ptr
2111#else
2112 cpabort("CP2K was compiled without Torch library.")
2113 mark_used(model)
2114#endif
2115 END SUBROUTINE torch_model_release
2116
2117! **************************************************************************************************
2118!> \brief Reads metadata entry from given "*.pth" file. (In Torch lingo they are called extra files)
2119!> \author Ole Schuett
2120! **************************************************************************************************
2121 FUNCTION torch_model_read_metadata(filename, key) RESULT(res)
2122 CHARACTER(len=*), INTENT(IN) :: filename, key
2123 CHARACTER(:), ALLOCATABLE :: res
2124
2125#if defined(__LIBTORCH)
2126 CHARACTER(len=*), PARAMETER :: routinen = 'torch_model_read_metadata'
2127 INTEGER :: handle
2128
2129 INTEGER :: length
2130 TYPE(c_ptr) :: content_c
2131
2132 INTERFACE
2133 SUBROUTINE torch_c_model_read_metadata(filename, key, content, length) &
2134 BIND(C, name="torch_c_model_read_metadata")
2135 IMPORT :: c_char, c_ptr, c_int
2136 CHARACTER(kind=C_CHAR), DIMENSION(*) :: filename, key
2137 TYPE(c_ptr) :: content
2138 INTEGER(kind=C_INT) :: length
2139 END SUBROUTINE torch_c_model_read_metadata
2140 END INTERFACE
2141
2142 CALL timeset(routinen, handle)
2143 content_c = c_null_ptr
2144 length = -1
2145 CALL torch_c_model_read_metadata(filename=trim(filename)//c_null_char, &
2146 key=trim(key)//c_null_char, &
2147 content=content_c, &
2148 length=length)
2149 CALL c_string_to_allocatable(content_c, length, res)
2150 CALL timestop(handle)
2151#else
2152 res = ""
2153 mark_used(filename)
2154 mark_used(key)
2155 cpabort("CP2K was compiled without Torch library.")
2156#endif
2157 END FUNCTION torch_model_read_metadata
2158
2159! **************************************************************************************************
2160!> \brief Move a C-allocated null-terminated string into an allocatable Fortran string.
2161! **************************************************************************************************
2162 SUBROUTINE c_string_to_allocatable(content_c, length, res)
2163 TYPE(c_ptr), INTENT(INOUT) :: content_c
2164 INTEGER, INTENT(IN) :: length
2165 CHARACTER(:), ALLOCATABLE, INTENT(OUT) :: res
2166
2167#if defined(__LIBTORCH)
2168 CHARACTER(LEN=1, KIND=C_CHAR), DIMENSION(:), &
2169 POINTER :: content_f
2170 INTEGER :: i
2171
2172 INTERFACE
2173 SUBROUTINE torch_c_free_string(content) BIND(C, name="torch_c_free_string")
2174 IMPORT :: c_ptr
2175 TYPE(c_ptr), VALUE :: content
2176 END SUBROUTINE torch_c_free_string
2177 END INTERFACE
2178
2179 cpassert(c_associated(content_c))
2180 cpassert(length >= 0)
2181
2182 CALL c_f_pointer(content_c, content_f, shape=[length + 1])
2183 cpassert(content_f(length + 1) == c_null_char)
2184
2185 ALLOCATE (CHARACTER(LEN=length) :: res)
2186 DO i = 1, length
2187 cpassert(content_f(i) /= c_null_char)
2188 res(i:i) = content_f(i)
2189 END DO
2190
2191 NULLIFY (content_f)
2192 CALL torch_c_free_string(content_c)
2193 content_c = c_null_ptr
2194
2195#else
2196 res = ""
2197 mark_used(content_c)
2198 mark_used(length)
2199 cpabort("CP2K was compiled without Torch library.")
2200#endif
2201 END SUBROUTINE c_string_to_allocatable
2202
2203! **************************************************************************************************
2204!> \brief Returns true iff the Torch CUDA backend is available.
2205!> \author Ole Schuett
2206! **************************************************************************************************
2207 FUNCTION torch_cuda_is_available() RESULT(res)
2208 LOGICAL :: res
2209
2210#if defined(__LIBTORCH)
2211 INTERFACE
2212 FUNCTION torch_c_cuda_is_available() BIND(C, name="torch_c_cuda_is_available")
2213 IMPORT :: c_bool
2214 LOGICAL(C_BOOL) :: torch_c_cuda_is_available
2215 END FUNCTION torch_c_cuda_is_available
2216 END INTERFACE
2217
2218 res = torch_c_cuda_is_available()
2219#else
2220 cpabort("CP2K was compiled without Torch library.")
2221 res = .false.
2222#endif
2223 END FUNCTION torch_cuda_is_available
2224
2225! **************************************************************************************************
2226!> \brief Return the number of CUDA devices visible to Torch.
2227! **************************************************************************************************
2228 FUNCTION torch_cuda_device_count() RESULT(count)
2229 INTEGER :: count
2230
2231#if defined(__LIBTORCH)
2232 INTERFACE
2233 FUNCTION torch_c_cuda_device_count() BIND(C, name="torch_c_cuda_device_count")
2234 IMPORT :: c_int
2235 INTEGER(C_INT) :: torch_c_cuda_device_count
2236 END FUNCTION torch_c_cuda_device_count
2237 END INTERFACE
2238
2239 count = torch_c_cuda_device_count()
2240#else
2241 cpabort("CP2K was compiled without Torch library.")
2242 count = 0
2243#endif
2244 END FUNCTION torch_cuda_device_count
2245
2246! **************************************************************************************************
2247!> \brief Set whether to allow the use of TF32.
2248!> Needed due to changes in defaults from pytorch 1.7 to 1.11 to >=1.12
2249!> See https://pytorch.org/docs/stable/notes/cuda.html
2250!> \author Gabriele Tocci
2251! **************************************************************************************************
2252 SUBROUTINE torch_allow_tf32(allow_tf32)
2253 LOGICAL, INTENT(IN) :: allow_tf32
2254
2255#if defined(__LIBTORCH)
2256 INTERFACE
2257 SUBROUTINE torch_c_allow_tf32(allow_tf32) BIND(C, name="torch_c_allow_tf32")
2258 IMPORT :: c_bool
2259 LOGICAL(C_BOOL), VALUE :: allow_tf32
2260 END SUBROUTINE torch_c_allow_tf32
2261 END INTERFACE
2262
2263 CALL torch_c_allow_tf32(allow_tf32=LOGICAL(allow_tf32, c_bool))
2264#else
2265 cpabort("CP2K was compiled without Torch library.")
2266 mark_used(allow_tf32)
2267#endif
2268 END SUBROUTINE torch_allow_tf32
2269
2270! **************************************************************************************************
2271!> \brief Freeze the given Torch model: applies generic optimization that speed up model.
2272!> See https://pytorch.org/docs/stable/generated/torch.jit.freeze.html
2273!> \author Gabriele Tocci
2274! **************************************************************************************************
2275 SUBROUTINE torch_model_freeze(model)
2276 TYPE(torch_model_type), INTENT(INOUT) :: model
2277
2278#if defined(__LIBTORCH)
2279 CHARACTER(len=*), PARAMETER :: routinen = 'torch_model_freeze'
2280 INTEGER :: handle
2281
2282 INTERFACE
2283 SUBROUTINE torch_c_model_freeze(model) BIND(C, name="torch_c_model_freeze")
2284 IMPORT :: c_ptr
2285 TYPE(c_ptr), VALUE :: model
2286 END SUBROUTINE torch_c_model_freeze
2287 END INTERFACE
2288
2289 CALL timeset(routinen, handle)
2290 cpassert(c_associated(model%c_ptr))
2291 CALL torch_c_model_freeze(model=model%c_ptr)
2292 CALL timestop(handle)
2293#else
2294 cpabort("CP2K was compiled without Torch library.")
2295 mark_used(model)
2296#endif
2297 END SUBROUTINE torch_model_freeze
2298
2299! **************************************************************************************************
2300!> \brief Freeze a Torch model while preserving one exported method.
2301!> \param model ...
2302!> \param method_name ...
2303! **************************************************************************************************
2304 SUBROUTINE torch_model_freeze_preserving_method(model, method_name)
2305 TYPE(torch_model_type), INTENT(INOUT) :: model
2306 CHARACTER(len=*), INTENT(IN) :: method_name
2307
2308#if defined(__LIBTORCH)
2309 CHARACTER(len=*), PARAMETER :: routinen = &
2310 'torch_model_freeze_preserving_method'
2311 INTEGER :: handle
2312
2313 INTERFACE
2314 SUBROUTINE torch_c_model_freeze_preserving_method(model, method_name) &
2315 BIND(C, name="torch_c_model_freeze_preserving_method")
2316 IMPORT :: c_char, c_ptr
2317 TYPE(c_ptr), VALUE :: model
2318 CHARACTER(kind=C_CHAR), DIMENSION(*) :: method_name
2319 END SUBROUTINE torch_c_model_freeze_preserving_method
2320 END INTERFACE
2321
2322 CALL timeset(routinen, handle)
2323 cpassert(c_associated(model%c_ptr))
2324 CALL torch_c_model_freeze_preserving_method( &
2325 model=model%c_ptr, method_name=trim(method_name)//c_null_char)
2326 CALL timestop(handle)
2327#else
2328 cpabort("CP2K was compiled without Torch library.")
2329 mark_used(method_name)
2330 mark_used(model)
2331#endif
2333
2334
2335! **************************************************************************************************
2336!> \brief Retrieves an attribute from a Torch model. Must be called before torch_model_freeze.
2337!> \author Ole Schuett
2338! **************************************************************************************************
2339 SUBROUTINE torch_model_get_attr_int64 (model, key, dest)
2340 TYPE(torch_model_type), INTENT(IN) :: model
2341 CHARACTER(len=*), INTENT(IN) :: key
2342 INTEGER(kind=int_8), INTENT(OUT) :: dest
2343
2344#if defined(__LIBTORCH)
2345
2346 INTERFACE
2347 SUBROUTINE torch_c_model_get_attr_int64 (model, key, dest) &
2348 BIND(C, name="torch_c_model_get_attr_int64")
2349 IMPORT :: c_ptr, c_char, c_int64_t, c_double
2350 TYPE(c_ptr), VALUE :: model
2351 CHARACTER(kind=C_CHAR), DIMENSION(*) :: key
2352 INTEGER(kind=C_INT64_T) :: dest
2353 END SUBROUTINE torch_c_model_get_attr_int64
2354 END INTERFACE
2355
2356 CALL torch_c_model_get_attr_int64 (model=model%c_ptr, &
2357 key=trim(key)//c_null_char, &
2358 dest=dest)
2359#else
2360 dest = 0
2361 mark_used(model)
2362 mark_used(key)
2363 cpabort("CP2K compiled without the Torch library.")
2364#endif
2365 END SUBROUTINE torch_model_get_attr_int64
2366! **************************************************************************************************
2367!> \brief Retrieves an attribute from a Torch model. Must be called before torch_model_freeze.
2368!> \author Ole Schuett
2369! **************************************************************************************************
2370 SUBROUTINE torch_model_get_attr_double (model, key, dest)
2371 TYPE(torch_model_type), INTENT(IN) :: model
2372 CHARACTER(len=*), INTENT(IN) :: key
2373 REAL(dp), INTENT(OUT) :: dest
2374
2375#if defined(__LIBTORCH)
2376
2377 INTERFACE
2378 SUBROUTINE torch_c_model_get_attr_double (model, key, dest) &
2379 BIND(C, name="torch_c_model_get_attr_double")
2380 IMPORT :: c_ptr, c_char, c_int64_t, c_double
2381 TYPE(c_ptr), VALUE :: model
2382 CHARACTER(kind=C_CHAR), DIMENSION(*) :: key
2383 REAL(kind=c_double) :: dest
2384 END SUBROUTINE torch_c_model_get_attr_double
2385 END INTERFACE
2386
2387 CALL torch_c_model_get_attr_double (model=model%c_ptr, &
2388 key=trim(key)//c_null_char, &
2389 dest=dest)
2390#else
2391 dest = 0.0_dp
2392 mark_used(model)
2393 mark_used(key)
2394 cpabort("CP2K compiled without the Torch library.")
2395#endif
2396 END SUBROUTINE torch_model_get_attr_double
2397! **************************************************************************************************
2398!> \brief Retrieves an attribute from a Torch model. Must be called before torch_model_freeze.
2399!> \author Ole Schuett
2400! **************************************************************************************************
2401 SUBROUTINE torch_model_get_attr_string (model, key, dest)
2402 TYPE(torch_model_type), INTENT(IN) :: model
2403 CHARACTER(len=*), INTENT(IN) :: key
2404 CHARACTER(LEN=default_string_length), INTENT(OUT) :: dest
2405
2406#if defined(__LIBTORCH)
2407
2408 INTERFACE
2409 SUBROUTINE torch_c_model_get_attr_string (model, key, dest) &
2410 BIND(C, name="torch_c_model_get_attr_string")
2411 IMPORT :: c_ptr, c_char, c_int64_t, c_double
2412 TYPE(c_ptr), VALUE :: model
2413 CHARACTER(kind=C_CHAR), DIMENSION(*) :: key
2414 CHARACTER(kind=C_CHAR), DIMENSION(*) :: dest
2415 END SUBROUTINE torch_c_model_get_attr_string
2416 END INTERFACE
2417
2418 CALL torch_c_model_get_attr_string (model=model%c_ptr, &
2419 key=trim(key)//c_null_char, &
2420 dest=dest)
2421#else
2422 dest = ""
2423 mark_used(model)
2424 mark_used(key)
2425 cpabort("CP2K compiled without the Torch library.")
2426#endif
2427 END SUBROUTINE torch_model_get_attr_string
2428
2429! **************************************************************************************************
2430!> \brief Retrieves an attribute from a Torch model. Must be called before torch_model_freeze.
2431!> \author Ole Schuett
2432! **************************************************************************************************
2433 SUBROUTINE torch_model_get_attr_int32(model, key, dest)
2434 TYPE(torch_model_type), INTENT(IN) :: model
2435 CHARACTER(len=*), INTENT(IN) :: key
2436 INTEGER, INTENT(OUT) :: dest
2437
2438 INTEGER(kind=int_8) :: temp
2439 CALL torch_model_get_attr_int64(model, key, temp)
2440 cpassert(abs(temp) < huge(dest))
2441 dest = int(temp)
2442 END SUBROUTINE torch_model_get_attr_int32
2443
2444! **************************************************************************************************
2445!> \brief Retrieves a list attribute from a Torch model. Must be called before torch_model_freeze.
2446!> \author Ole Schuett
2447! **************************************************************************************************
2448 SUBROUTINE torch_model_get_attr_strlist(model, key, dest)
2449 TYPE(torch_model_type), INTENT(IN) :: model
2450 CHARACTER(len=*), INTENT(IN) :: key
2451 CHARACTER(LEN=default_string_length), &
2452 ALLOCATABLE, DIMENSION(:) :: dest
2453
2454#if defined(__LIBTORCH)
2455
2456 INTEGER :: num_items, i
2457
2458 INTERFACE
2459 SUBROUTINE torch_c_model_get_attr_list_size(model, key, size) &
2460 BIND(C, name="torch_c_model_get_attr_list_size")
2461 IMPORT :: c_ptr, c_char, c_int
2462 TYPE(c_ptr), VALUE :: model
2463 CHARACTER(kind=C_CHAR), DIMENSION(*) :: key
2464 INTEGER(kind=C_INT) :: size
2465 END SUBROUTINE torch_c_model_get_attr_list_size
2466 END INTERFACE
2467
2468 INTERFACE
2469 SUBROUTINE torch_c_model_get_attr_strlist(model, key, index, dest) &
2470 BIND(C, name="torch_c_model_get_attr_strlist")
2471 IMPORT :: c_ptr, c_char, c_int
2472 TYPE(c_ptr), VALUE :: model
2473 CHARACTER(kind=C_CHAR), DIMENSION(*) :: key
2474 INTEGER(kind=C_INT), VALUE :: index
2475 CHARACTER(kind=C_CHAR), DIMENSION(*) :: dest
2476 END SUBROUTINE torch_c_model_get_attr_strlist
2477 END INTERFACE
2478
2479 CALL torch_c_model_get_attr_list_size(model=model%c_ptr, &
2480 key=trim(key)//c_null_char, &
2481 size=num_items)
2482 ALLOCATE (dest(num_items))
2483 dest(:) = ""
2484
2485 DO i = 1, num_items
2486 CALL torch_c_model_get_attr_strlist(model=model%c_ptr, &
2487 key=trim(key)//c_null_char, &
2488 index=i - 1, &
2489 dest=dest(i))
2490
2491 END DO
2492#else
2493 cpabort("CP2K compiled without the Torch library.")
2494 mark_used(model)
2495 mark_used(key)
2496 mark_used(dest)
2497#endif
2498
2499 END SUBROUTINE torch_model_get_attr_strlist
2500
2501END MODULE torch_api
struct tensor_ tensor
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public int_8
Definition kinds.F:54
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_string_length
Definition kinds.F:57
integer, parameter, public sp
Definition kinds.F:33
integer, parameter, public int_4
Definition kinds.F:51
subroutine, public torch_dict_release(dict)
Releases a Torch dictionary and all its ressources.
Definition torch_api.F:1843
subroutine, public torch_tensor_backward(tensor, outer_grad)
Runs autograd on a Torch tensor.
Definition torch_api.F:1472
subroutine, public torch_model_promote_float32(model)
Promote float32 model state and explicit floating-point casts to double precision.
Definition torch_api.F:1973
subroutine, public torch_use_cuda(use_cuda)
Select whether Torch wrappers should use CUDA when available.
Definition torch_api.F:1555
subroutine, public torch_dict_get(dict, key, tensor)
Retrieves a Torch tensor from a Torch dictionary.
Definition torch_api.F:1809
subroutine, public torch_model_freeze_preserving_method(model, method_name)
Freeze a Torch model while preserving one exported method.
Definition torch_api.F:2305
real(kind=dp) function, public torch_tensor_item_double(tensor)
Returns a scalar double value from a Torch tensor.
Definition torch_api.F:1675
subroutine, public torch_tensor_backward_scalar(tensor)
Runs autograd on a scalar Torch tensor.
Definition torch_api.F:1504
subroutine, public torch_model_load_with_metadata(model, filename, key1, value1, key2, value2)
Loads a Torch model and reads two metadata entries in the same archive pass.
Definition torch_api.F:1898
subroutine, public torch_model_load(model, filename)
Loads a Torch model from given "*.pth" file. (In Torch lingo models are called modules).
Definition torch_api.F:1867
subroutine, public torch_tensor_narrow(tensor, dim, start_index, length, result)
Creates a view of a contiguous tensor slice.
Definition torch_api.F:1431
subroutine, public torch_model_remap_device_constants(model)
Maps serialized TorchScript device constants to the active Torch device.
Definition torch_api.F:1950
subroutine, public torch_tensor_to_device_leaf(tensor, requires_grad)
Moves a tensor to the active Torch device and makes it an autograd leaf.
Definition torch_api.F:1527
subroutine, public torch_dict_create(dict)
Creates an empty Torch dictionary.
Definition torch_api.F:1726
subroutine, public torch_model_forward_mol_tensor(model, method_name, inputs, output)
Evaluates a TorchScript model method expecting keyword argument "mol".
Definition torch_api.F:2054
subroutine, public torch_model_disable_parameter_gradients(model)
Disable gradients for inference-only model parameters.
Definition torch_api.F:1995
subroutine, public torch_model_release(model)
Releases a Torch model and all its ressources.
Definition torch_api.F:2098
subroutine, public torch_tensor_grad(tensor, grad)
Returns the gradient of a Torch tensor which was computed by autograd.
Definition torch_api.F:1576
subroutine, public torch_allow_tf32(allow_tf32)
Set whether to allow the use of TF32. Needed due to changes in defaults from pytorch 1....
Definition torch_api.F:2253
subroutine, public torch_tensor_weighted_sum(values, weights, result)
Returns the weighted sum of two Torch tensors.
Definition torch_api.F:1644
subroutine, public torch_tensor_grad_batch3(tensor1, tensor2, tensor3, grad1, grad2, grad3)
Copies three autograd gradients to CPU memory.
Definition torch_api.F:1604
subroutine, public torch_model_freeze(model)
Freeze the given Torch model: applies generic optimization that speed up model. See https://pytorch....
Definition torch_api.F:2276
integer function, public torch_cuda_device_count()
Return the number of CUDA devices visible to Torch.
Definition torch_api.F:2229
character(:) function, allocatable, public torch_model_read_metadata(filename, key)
Reads metadata entry from given "*.pth" file. (In Torch lingo they are called extra files).
Definition torch_api.F:2122
subroutine, public torch_tensor_expand_dim(tensor, dim, extent, result)
Creates an expanded tensor view along one singleton dimension.
Definition torch_api.F:1394
subroutine, public torch_dict_insert(dict, key, tensor)
Inserts a Torch tensor into a Torch dictionary.
Definition torch_api.F:1777
logical function, public torch_cuda_is_available()
Returns true iff the Torch CUDA backend is available.
Definition torch_api.F:2208
subroutine, public torch_dict_clone(source, target)
Clones a Torch dictionary.
Definition torch_api.F:1749
subroutine, public torch_tensor_release(tensor)
Releases a Torch tensor and all its ressources.
Definition torch_api.F:1702
subroutine, public torch_model_forward(model, inputs, outputs)
Evaluates the given Torch model.
Definition torch_api.F:2019