Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
afd2659
Enhance MTLN performance by optimizing bundle processing and reducing…
lmdiazangulo May 4, 2026
ff98c0d
Merge branch '398-segfault-with-mtln' into 400-mtln-cpu-performance-i…
lmdiazangulo May 6, 2026
1080f1b
Adds openmp to MTLN but no improvements have been observed...
lmdiazangulo May 7, 2026
0050594
Merge remote-tracking branch 'origin/dev' into 400-mtln-cpu-performan…
lmdiazangulo May 12, 2026
f120bb8
Add hybrid termination handler for MTLN performance optimization
lmdiazangulo May 12, 2026
43312fd
Merge remote-tracking branch 'origin/dev' into 400-mtln-cpu-performan…
Alberto-o Jun 11, 2026
0c270e4
Merge remote-tracking branch 'origin/dev' into 400-mtln-cpu-performan…
Alberto-o Jun 12, 2026
f0bc711
Some changes to check performance reducing calls to ngspice
Alberto-o Jun 15, 2026
de4e5a0
Changes to make less loops and less calls to ngspice. towelHanger passes
Alberto-o Jun 16, 2026
62454ee
WIP performance. Simplifies bundle-nw-circuit interaction. Removes lo…
Alberto-o Jun 17, 2026
f708d42
Adds towelHanger case prepost
Alberto-o Jun 18, 2026
54f1d3a
Changes make MTLN 2x faster. Need to check MPI and fix some tests
Alberto-o Jun 18, 2026
b5f9ad9
Fixes spice unit tests. Needed due to changes in circuit module
Alberto-o Jun 18, 2026
77582e9
Replace GFortran-specific SYMLNK with portable create_symlink helper
Copilot Jun 18, 2026
b5862e7
Use ISO C binding for create_symlink: no shell, proper error reporting
Copilot Jun 18, 2026
98a3106
Fix in solver/nws for open nodes. Some other minor fixes. WIP test re…
Alberto-o Jun 19, 2026
e8115c3
Missing updated tests
Alberto-o Jun 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,12 @@ if (CMAKE_SYSTEM_NAME MATCHES "Linux")
if(CMAKE_Fortran_COMPILER_ID MATCHES "GNU")
message(STATUS "Using GNU flags")

set(CMAKE_CXX_FLAGS "-fopenmp")
set(CMAKE_Fortran_FLAGS "-fopenmp -ffree-form -ffree-line-length-none -fdec -fallow-argument-mismatch")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fopenmp -ffree-form -ffree-line-length-none -fdec -fallow-argument-mismatch")

set(CMAKE_C_FLAGS_RELEASE "-Ofast")
set(CMAKE_CXX_FLAGS_RELEASE "-Ofast")
set(CMAKE_Fortran_FLAGS_RELEASE "-Ofast")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Ofast")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast")
set(CMAKE_Fortran_FLAGS_RELEASE "${CMAKE_Fortran_FLAGS_RELEASE} -Ofast")

set(CMAKE_C_FLAGS_DEBUG "-g -O0")
set(CMAKE_CXX_FLAGS_DEBUG "-g -O0")
Expand Down
16 changes: 9 additions & 7 deletions src_main_pub/observation.F90
Original file line number Diff line number Diff line change
Expand Up @@ -743,13 +743,15 @@ subroutine InitObservation(sgg, media, tag_numbers, &
type(mtln_solver_t), pointer :: mtln_solver
integer :: i, j
mtln_solver => GetSolverPtr()
do i = 1, ubound(mtln_solver%bundles, 1)
if (ubound(mtln_solver%bundles(i)%probes, 1) /= 0) then
do j = 1, ubound(mtln_solver%bundles(i)%probes, 1)
if (mtln_solver%bundles(i)%probes(j)%in_layer) ThereAreObservation = .true.
end do
end if
end do
if (allocated(mtln_solver%bundles)) then
do i = 1, ubound(mtln_solver%bundles, 1)
if (ubound(mtln_solver%bundles(i)%probes, 1) /= 0) then
do j = 1, ubound(mtln_solver%bundles(i)%probes, 1)
if (mtln_solver%bundles(i)%probes(j)%in_layer) ThereAreObservation = .true.
end do
end if
end do
end if
end block
#endif
!
Expand Down
2 changes: 2 additions & 0 deletions src_main_pub/timestepping.F90
Original file line number Diff line number Diff line change
Expand Up @@ -2587,7 +2587,9 @@ subroutine solver_advanceWiresE(this)
character(len=bufsize) :: buff

#ifdef CompileWithMTLN
if (this%thereAre%MTLNbundles) then
call AdvanceWiresE_mtln(this%sgg,this%Idxh,this%Idyh,this%Idzh,this%eps0,this%mu0)
end if
#else

if (( (trim(adjustl(this%control%wiresflavor))=='holland') .or. &
Expand Down
2 changes: 2 additions & 0 deletions src_mtln/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ add_library(mtlnsolver
"circuit.F90"
"ngspice_interface.F90"
"preprocess.F90"
"termination_handler.F90"
"benchmark.F90"
)

target_link_libraries(mtlnsolver PRIVATE
Expand Down
123 changes: 123 additions & 0 deletions src_mtln/benchmark.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
module benchmark_m

use FDETYPES_m, only: RKIND
implicit none

private
public :: benchmark_t

type benchmark_t
real(kind=rkind) :: total_time
real(kind=rkind) :: min_time
real(kind=rkind) :: max_time
real(kind=rkind) :: last_time
integer :: count
logical :: running
real(kind=rkind) :: start_time
character(len=128) :: name
contains
procedure :: benchmark_init
procedure :: benchmark_start
procedure :: benchmark_stop
procedure :: benchmark_get_elapsed
procedure :: benchmark_reset
procedure :: benchmark_report
end type benchmark_t

contains

subroutine benchmark_init(this, name)
class(benchmark_t) :: this
character(*), intent(in), optional :: name

this%total_time = 0.0_rkind
this%min_time = huge(1.0_rkind)
this%max_time = 0.0_rkind
this%last_time = 0.0_rkind
this%count = 0
this%running = .false.
this%start_time = 0.0_rkind
if (present(name)) then
this%name = trim(name)
else
this%name = 'benchmark'
end if
end subroutine benchmark_init

subroutine benchmark_start(this)
class(benchmark_t) :: this
integer :: i, n

call system_clock(count=i, count_rate=n)
this%start_time = real(i, kind=rkind) / real(n, kind=rkind)
this%running = .true.
end subroutine benchmark_start

subroutine benchmark_stop(this)
class(benchmark_t) :: this
integer :: i, n
real(kind=rkind) :: elapsed

call system_clock(count=i, count_rate=n)
elapsed = real(i, kind=rkind) / real(n, kind=rkind) - this%start_time

if (elapsed < 0.0_rkind) elapsed = 0.0_rkind

this%last_time = elapsed
this%total_time = this%total_time + elapsed
this%count = this%count + 1

if (elapsed < this%min_time) this%min_time = elapsed
if (elapsed > this%max_time) this%max_time = elapsed

this%running = .false.
end subroutine benchmark_stop

function benchmark_get_elapsed(this) result(elapsed)
class(benchmark_t) :: this
real(kind=rkind) :: elapsed
integer :: i, n

if (this%running) then
call system_clock(count=i, count_rate=n)
elapsed = real(i, kind=rkind) / real(n, kind=rkind) - this%start_time
if (elapsed < 0.0_rkind) elapsed = 0.0_rkind
else
elapsed = this%last_time
end if
end function benchmark_get_elapsed

subroutine benchmark_reset(this)
class(benchmark_t) :: this

this%total_time = 0.0_rkind
this%min_time = huge(1.0_rkind)
this%max_time = 0.0_rkind
this%last_time = 0.0_rkind
this%count = 0
this%running = .false.
this%start_time = 0.0_rkind
end subroutine benchmark_reset

subroutine benchmark_report(this, unit)
class(benchmark_t) :: this
integer, intent(in), optional :: unit
integer :: u

u = 6
if (present(unit)) u = unit

if (this%count > 0) then
write(u, '(A, A, I5)') 'Benchmark: ', trim(this%name), this%count
write(u, '(A, ES12.4)') ' Total time (s): ', this%total_time
write(u, '(A, ES12.4)') ' Average time (s): ', this%total_time / this%count
write(u, '(A, ES12.4)') ' Min time (s): ', this%min_time
write(u, '(A, ES12.4)') ' Max time (s): ', this%max_time
write(u, '(A, F10.2, A)') ' Calls per second: ', &
real(this%count, kind=rkind) / this%total_time, ' Hz'
else
write(u, '(A, A)') 'No measurements for benchmark: ', trim(this%name)
end if
end subroutine benchmark_report

end module benchmark_m
Loading
Loading