Skip to content

Commit

Permalink
Introduced m_cpuid_vlen
Browse files Browse the repository at this point in the history
- Show more relevant hint about missed optimization opportunity.
- Allow OPTIONAL arguments for convenience.
- Specified INTENT for several arguments.
  • Loading branch information
hfp committed Dec 4, 2024
1 parent c98fd6f commit 7442a40
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 42 deletions.
129 changes: 90 additions & 39 deletions src/base/machine.F
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ MODULE machine
m_getcwd, m_getlog, m_getpid, m_procrun, m_abort, &
m_chdir, m_mov, m_memory, m_memory_details, m_energy, &
m_cpuinfo, m_cpuid_static, m_cpuid, m_cpuid_name, &
m_omp_get_stacksize, m_omp_trace_issues
m_cpuid_vlen, m_omp_get_stacksize, m_omp_trace_issues

INTERFACE
! **********************************************************************************************
Expand Down Expand Up @@ -158,24 +158,24 @@ END FUNCTION m_walltime
!> \param model_name as obtained from the 'model name' field, UNKNOWN otherwise
! **************************************************************************************************
SUBROUTINE m_cpuinfo(model_name)
CHARACTER(LEN=default_string_length) :: model_name
CHARACTER(LEN=default_string_length), INTENT(OUT) :: model_name

INTEGER, PARAMETER :: bufferlen = 2048

CHARACTER(LEN=bufferlen) :: buffer
INTEGER :: i, icol, iline, imod, stat
INTEGER :: cpuid, i, icol, iline, stat

model_name = "UNKNOWN"
buffer = ""
OPEN (121245, FILE="/proc/cpuinfo", ACTION="READ", STATUS="OLD", ACCESS="STREAM", IOSTAT=stat)
IF (stat == 0) THEN
model_name = "UNKNOWN"
buffer = ""
OPEN(121245, FILE="/proc/cpuinfo", ACTION="READ", STATUS="OLD", ACCESS="STREAM", IOSTAT=stat)
IF (stat == 0) THEN
DO i = 1, bufferlen
READ (121245, END=999) buffer(I:I)
READ(121245, END=999) buffer(I:I)
END DO
999 CLOSE (121245)
imod = INDEX(buffer, "model name")
IF (imod > 0) THEN
icol = imod - 1 + INDEX(buffer(imod:), ":")
999 CLOSE(121245)
i = INDEX(buffer, "model name")
IF (i > 0) THEN
icol = i - 1 + INDEX(buffer(i:), ":")
iline = icol - 1 + INDEX(buffer(icol:), NEW_LINE('A'))
IF (iline == icol - 1) iline = bufferlen + 1
model_name = buffer(icol + 1:iline - 1)
Expand All @@ -190,46 +190,46 @@ END SUBROUTINE m_cpuinfo
!> 04.2019 created [Hans Pabst]
!> 09.2024 update+arm [Hans Pabst]
! **************************************************************************************************
PURE FUNCTION m_cpuid() RESULT(cpuid)
INTEGER :: cpuid
PURE FUNCTION m_cpuid()
INTEGER :: m_cpuid
#if defined(__LIBXSMM)
cpuid = libxsmm_get_target_archid()
IF (LIBXSMM_X86_SSE4 <= cpuid .AND. cpuid < LIBXSMM_X86_AVX) THEN
cpuid = MACHINE_X86_SSE4
ELSE IF (LIBXSMM_X86_AVX <= cpuid .AND. cpuid < LIBXSMM_X86_AVX2) THEN
cpuid = MACHINE_X86_AVX
ELSE IF (LIBXSMM_X86_AVX2 <= cpuid .AND. cpuid < LIBXSMM_X86_AVX512_SKX) THEN
cpuid = MACHINE_X86_AVX2
ELSE IF (LIBXSMM_X86_AVX512_SKX <= cpuid .AND. cpuid <= 1999) THEN
cpuid = MACHINE_X86_AVX512
m_cpuid = libxsmm_get_target_archid()
IF (LIBXSMM_X86_SSE4 <= m_cpuid .AND. m_cpuid < LIBXSMM_X86_AVX) THEN
m_cpuid = MACHINE_X86_SSE4
ELSE IF (LIBXSMM_X86_AVX <= m_cpuid .AND. m_cpuid < LIBXSMM_X86_AVX2) THEN
m_cpuid = MACHINE_X86_AVX
ELSE IF (LIBXSMM_X86_AVX2 <= m_cpuid .AND. m_cpuid < LIBXSMM_X86_AVX512_SKX) THEN
m_cpuid = MACHINE_X86_AVX2
ELSE IF (LIBXSMM_X86_AVX512_SKX <= m_cpuid .AND. m_cpuid <= 1999) THEN
m_cpuid = MACHINE_X86_AVX512
#if defined(__LIBXSMM2)
ELSE IF (LIBXSMM_AARCH64_V81 <= cpuid .AND. cpuid < LIBXSMM_AARCH64_SVE128) THEN
cpuid = MACHINE_ARM_ARCH64
ELSE IF (LIBXSMM_AARCH64_SVE128 <= cpuid .AND. cpuid < 2401) THEN ! LIBXSMM_AARCH64_SVE512
cpuid = MACHINE_ARM_SVE256
ELSE IF (2401 <= cpuid .AND. cpuid <= 2999) THEN
cpuid = MACHINE_ARM_SVE512
ELSE IF (LIBXSMM_AARCH64_V81 <= m_cpuid .AND. m_cpuid < LIBXSMM_AARCH64_SVE128) THEN
m_cpuid = MACHINE_ARM_ARCH64
ELSE IF (LIBXSMM_AARCH64_SVE128 <= m_cpuid .AND. m_cpuid < 2401) THEN ! LIBXSMM_AARCH64_SVE512
m_cpuid = MACHINE_ARM_SVE256
ELSE IF (2401 <= m_cpuid .AND. m_cpuid <= 2999) THEN
m_cpuid = MACHINE_ARM_SVE512
#endif
ELSE IF (LIBXSMM_TARGET_ARCH_GENERIC <= cpuid .AND. cpuid <= 2999) THEN
cpuid = MACHINE_CPU_GENERIC
ELSE IF (LIBXSMM_TARGET_ARCH_GENERIC <= m_cpuid .AND. m_cpuid <= 2999) THEN
m_cpuid = MACHINE_CPU_GENERIC
ELSE
cpuid = MACHINE_CPU_UNKNOWN
m_cpuid = MACHINE_CPU_UNKNOWN
END IF
#else
cpuid = m_cpuid_static()
m_cpuid = m_cpuid_static()
#endif
END FUNCTION m_cpuid

! **************************************************************************************************
!> \brief Determine name of target architecture for a given CPUID.
!> \param cpuid integer value (MACHINE_*)
!> \return name or short name.
!> \return short name of ISA extension.
!> \par History
!> 06.2019 created [Hans Pabst]
!> 09.2024 update+arm [Hans Pabst]
! **************************************************************************************************
FUNCTION m_cpuid_name(cpuid)
INTEGER :: cpuid
PURE FUNCTION m_cpuid_name(cpuid)
INTEGER, OPTIONAL, INTENT(IN) :: cpuid
CHARACTER(len=default_string_length), POINTER :: m_cpuid_name

CHARACTER(len=default_string_length), SAVE, TARGET :: name_arm_arch64 = "arm_arch64", &
Expand All @@ -242,8 +242,15 @@ FUNCTION m_cpuid_name(cpuid)
name_x86_avx2 = "x86_avx2", &
name_x86_avx512 = "x86_avx512", &
name_x86_sse4 = "x86_sse4"
INTEGER :: isa

SELECT CASE (cpuid)
IF (PRESENT(cpuid)) THEN
isa = cpuid
ELSE
isa = m_cpuid()
END IF

SELECT CASE (isa)
CASE (MACHINE_CPU_GENERIC)
m_cpuid_name => name_generic
CASE (MACHINE_X86_SSE4)
Expand All @@ -267,6 +274,52 @@ FUNCTION m_cpuid_name(cpuid)
END SELECT
END FUNCTION m_cpuid_name

! **************************************************************************************************
!> \brief Determine vector-length for a given CPUID.
!> \param cpuid integer value (MACHINE_*)
!> \param typesize number of bytes of scalar type
!> \return vector-length in number of elements.
!> \par History
!> 12.2024 created [Hans Pabst]
! **************************************************************************************************
PURE FUNCTION m_cpuid_vlen(cpuid, typesize)
INTEGER, OPTIONAL, INTENT(IN) :: cpuid, typesize

INTEGER :: isa, m_cpuid_vlen, nbytes

IF (PRESENT(typesize)) THEN
nbytes = typesize
ELSE
nbytes = 8 ! double-precision
END IF

IF (0 < nbytes .AND. nbytes <= 16) THEN ! sanity check
IF (PRESENT(cpuid)) THEN
isa = cpuid
ELSE
isa = m_cpuid()
END IF

SELECT CASE (isa)
CASE (MACHINE_X86_SSE4)
CASE (MACHINE_ARM_ARCH64) ! NEON
CASE (MACHINE_ARM_SVE128)
m_cpuid_vlen = 16 / nbytes
CASE (MACHINE_X86_AVX)
CASE (MACHINE_X86_AVX2)
CASE (MACHINE_ARM_SVE256)
m_cpuid_vlen = 32 / nbytes
CASE (MACHINE_X86_AVX512)
CASE (MACHINE_ARM_SVE512)
m_cpuid_vlen = 64 / nbytes
CASE DEFAULT ! unknown or generic
m_cpuid_vlen = 1 ! scalar
END SELECT
ELSE ! fallback
m_cpuid_vlen = 1 ! scalar
END IF
END FUNCTION m_cpuid_vlen

! **************************************************************************************************
!> \brief returns the energy used since some time in the past.
!> The precise meaning depends on the infrastructure is available.
Expand Down Expand Up @@ -394,7 +447,6 @@ SUBROUTINE m_memory(mem)
INTEGER(KIND=int_8), OPTIONAL, INTENT(OUT) :: mem
INTEGER(KIND=int_8) :: mem_local

!
! __NO_STATM_ACCESS can be used to disable the stuff, if getpagesize
! lead to linking errors or /proc/self/statm can not be opened
!
Expand All @@ -413,7 +465,6 @@ FUNCTION getpagesize() BIND(C, name="getpagesize") RESULT(RES)
END FUNCTION
END INTERFACE

!
! reading from statm
!
mem_local = -1
Expand Down
7 changes: 4 additions & 3 deletions src/environment.F
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ MODULE environment
print_kind_info
USE local_gemm_api, ONLY: local_gemm_set_library
USE machine, ONLY: &
flush_should_flush, m_cpuid, m_cpuid_name, m_cpuid_static, m_cpuinfo, m_energy, &
m_memory_details, m_omp_get_stacksize, m_omp_trace_issues, m_procrun
flush_should_flush, m_cpuid, m_cpuid_name, m_cpuid_static, m_cpuid_vlen, m_cpuinfo, &
m_energy, m_memory_details, m_omp_get_stacksize, m_omp_trace_issues, m_procrun
USE message_passing, ONLY: mp_collect_timings,&
mp_para_env_type
USE mp_perf_env, ONLY: add_mp_perf_env,&
Expand Down Expand Up @@ -922,7 +922,8 @@ SUBROUTINE read_global_section(root_section, para_env, globenv)
END IF
END IF

IF (cpuid_static < cpuid) THEN
! filter cpuids by vlen to show more relevant information
IF (m_cpuid_vlen(cpuid_static) < m_cpuid_vlen(cpuid)) THEN
! base/machine_cpuid.c relies on the (same) target flags as the Fortran code
CALL cp_hint(__LOCATION__, "The compiler target flags ("// &
TRIM(m_cpuid_name(cpuid_static))//") used to build this binary cannot exploit "// &
Expand Down

0 comments on commit 7442a40

Please sign in to comment.