From 6d27a825f38eadff480e7f3876067f546529e1fe Mon Sep 17 00:00:00 2001 From: Hans Fangohr Date: Fri, 15 Mar 2024 17:55:08 +0100 Subject: [PATCH] Support to enable compilation of OOMMF on Linux with ARM64 hardware - readding the files developed in https://github.com/fangohr/oommf/pull/58 - those files will be released with the next oommf release but are not available yet for 21a0 --- oommf/config/names/linux-arm64.tcl | 43 +++ oommf/config/platforms/linux-arm64.tcl | 435 +++++++++++++++++++++++++ 2 files changed, 478 insertions(+) create mode 100644 oommf/config/names/linux-arm64.tcl create mode 100644 oommf/config/platforms/linux-arm64.tcl diff --git a/oommf/config/names/linux-arm64.tcl b/oommf/config/names/linux-arm64.tcl new file mode 100644 index 00000000..21ade854 --- /dev/null +++ b/oommf/config/names/linux-arm64.tcl @@ -0,0 +1,43 @@ +# linux-arm64.tcl +# +# Defines the Oc_Config name 'linux-arm64' to indicate the Linux +# operating system running on the arm64 architecture. + +Oc_Config New _ [string tolower [file rootname [file tail [info script]]]] { + global tcl_platform + + if {[llength [info commands LocalNameCheck]] == 0} { + # If local/mynames.tcl exists and defines LocalNameCheck, + # then use that. + set fn [file join \ + [file dirname [file dirname [file dirname [info script]]]] \ + config names local mynames.tcl] + if {[file readable $fn]} { + catch {source $fn} + } + } + if {[llength [info commands LocalNameCheck]] == 1} { + set localname [LocalNameCheck] + if {![string match {} $localname]} { + set checkname [$this GetValue platform_name] + return [expr {![string compare $checkname $localname]}] + } + } + + # Otherwise, fall back on default rules + if {![regexp -nocase -- linux $tcl_platform(os)]} { + return 0 + } + if {![string match aarch64 $tcl_platform(machine)]} { + return 0 + } + if {[info exists tcl_platform(wordSize)] && + $tcl_platform(wordSize) != 8} { + return 0 + } + if {[info exists tcl_platform(pointerSize)] && + $tcl_platform(pointerSize) != 8} { + return 0 + } + return 1 +} diff --git a/oommf/config/platforms/linux-arm64.tcl b/oommf/config/platforms/linux-arm64.tcl new file mode 100644 index 00000000..862fb628 --- /dev/null +++ b/oommf/config/platforms/linux-arm64.tcl @@ -0,0 +1,435 @@ +# FILE: linux-arm64.tcl +# +# Configuration feature definitions for the configuration 'linux-x86_64' +# +# Editing instructions begin at "START EDIT HERE" below. + +set config [Oc_Config RunPlatform] + +set scriptfn [Oc_DirectPathname [info script]] +if {![string match [string tolower [file rootname [file tail $scriptfn]]] \ + [$config GetValue platform_name]]} { + error "Configuration file '$scriptfn' +sourced by '[$config GetValue platform_name]'" +} + +set localfn [file join [file dirname $scriptfn] local \ + [file tail $scriptfn]] +if {[file readable $localfn]} { + if {[catch {source $localfn} msg]} { + global errorInfo errorCode + set msg [join [split $msg \n] \n\t] + error "Error sourcing local platform file:\n $localfn:\n\t$msg" \ + $errorInfo $errorCode + } +} + +if {[catch {$config GetValue program_compiler_c++_override}] \ + && ![catch {$config GetValue program_compiler_c++} _]} { + # If program_compiler_c++ is set, but program_compiler_c++_override + # is not, then assume user set the former instead of the latter, + # and so copy the former to the latter to preserve the setting + # across the setting of program_compiler_c++ in the "REQUIRED + # CONFIGURATION" section below. + $config SetValue program_compiler_c++_override $_ +} + +# Environment variable override for C++ compiler. The string OOMMF_C++ +# is an invalid name in Unix shells, so also allow OOMMF_CPP +if {[info exists env(OOMMF_C++)]} { + $config SetValue program_compiler_c++_override $env(OOMMF_C++) +} elseif {[info exists env(OOMMF_CPP)]} { + $config SetValue program_compiler_c++_override $env(OOMMF_CPP) +} + +# Support for the automated buildtest scripts +if {[info exists env(OOMMF_BUILDTEST)] && $env(OOMMF_BUILDTEST)} { + source [file join [file dirname [info script]] buildtest.tcl] +} + +######################################################################## +# START EDIT HERE +# OOMMF software cannot classify your computing platform type. See +# the Installation section of the OOMMF User Manual for instructions on +# how to add a new platform type to the collection of types recognized +# by OOMMF software. +# +# Say you add the new platform type 'foo' to describe your computing +# platform. Then copy this file to ./foo.tcl , and edit it to +# describe your computing platform. In its initial state, this file +# describes a rather generic Linux system, so there shouldn't be much +# editing required for any Unix-based platform. Other platforms may +# be more difficult or impossible. In any event, please e-mail the +# OOMMF developers for assistance setting up OOMMF for your particular +# circumstances. +######################################################################## +# In order to properly build, install, and run on your computing +# platform, the OOMMF software must know certain features of your +# computing environment. In this file are lines which set the value of +# certain features of your computing environment. Each line looks like: +# +# $config SetValue {} +# +# where each is the name of some feature of interest, +# and is the value which is assigned to that feature in a +# description of your computing environment. Your task is to edit +# the values as necessary to properly describe your computing +# environment. +# +# The character '#' at the beginning of a line is a comment character. +# It causes the contents of that line to be ignored. To select +# among lines providing alternative values for a feature, uncomment the +# line containing the proper value. +# +# The features in this file are divided into three sections. The +# first section (REQUIRED CONFIGURATION) includes features which +# require you to provide a value. The second section (LOCAL +# CONFIGURATION) includes features which have usable default values, +# but which you may wish to customize. These can be edited here, but +# it is recommended instead that you create a subdirectory named +# "local", put a copy of the LOCAL CONFIGURATION section there in a +# file with the same name as this file, and then edit that file. The +# third section (BUILD CONFIGURATION) contains features which you +# probably do not need or want to change without a good reason. +# +######################################################################## +# REQUIRED CONFIGURATION + +# Set the feature 'program_compiler_c++' to the program to run on this +# platform to compile source code files written in the language C++ into +# object files. Select from the choices below. If the compiler is not +# in your path, be sure to use the whole pathname. Also include any +# options required to instruct your compiler to only compile, not link. +# +# If your compiler is not listed below, additional features will have +# to be added in the BUILD CONFIGURATION section below to describe to +# the OOMMF software how to operate your compiler. Send e-mail to the +# OOMMF developers for assistance. +# +# The GNU C++ compiler 'g++' +# +# +$config SetValue program_compiler_c++ {g++ -c} + +######################################################################## +# SUPPORT PROCEDURES +# +source [file join [file dirname [Oc_DirectPathname [info script]]] \ + gcc-support.tcl] + +# Miscellaneous processing routines +source [file join [file dirname [Oc_DirectPathname [info script]]] \ + misc-support.tcl] + +######################################################################## +# LOCAL CONFIGURATION +# +# The following options may be defined in the a "local" file, which +# has the same name as this file but is stored in the +# platforms/local/ subdirectory. +# +## Set the feature 'path_directory_temporary' to the name of an existing +## directory on your computer in which OOMMF software should write +## temporary files. All OOMMF users must have write access to this +## directory. +# $config SetValue path_directory_temporary {/tmp} +# +## Specify whether or not to build in thread support. +## Thread support is included automatically if the tclsh interpreter used +## during the build process is threaded. If you have a thread enabled +## tclsh, but don't want oommf_threads, override here. +# $config SetValue oommf_threads 0 ;# 1 to force threaded build, +# ## 0 to force non-threaded build. +# +## Specify the number of default threads. This is only meaningful +## for builds with thread support. +# $config SetValue thread_count 4 ;# Replace '4' with desired thread count. +# +## Specify hard limit on the max number of threads per process. This is +## only meaningful for builds with thread support. If not set, then there +## is no limit. +# $config SetValue thread_limit 8 +# +## Use NUMA (non-uniform memory access) libraries? This is only +## supported on Linux systems that have both NUMA runtime (numactl) and +## NUMA development (numactl-devel) packages installed. +# $config SetValue use_numa 1 ;# 1 to enable, 0 (default) to disable. +# +## Override default C++ compiler. Note the "_override" suffix +## on the value name. +# $config SetValue program_compiler_c++_override {icpc -c} +# +## Processor architecture for compiling. The default is "generic" +## which should produce an executable that runs on any cpu model for +## the given platform. Optionally, one may specify "host", in which +## case the build scripts will try to automatically detect the +## processor type on the current system, and select compiler options +## specific to that processor model. The resulting binary will +## generally not run on other architectures. +# $config SetValue program_compiler_c++_cpu_arch host +# +## Variable type used for array indices, OC_INDEX. This is a signed +## type which by default is sized to match the pointer width. You can +## force the type by setting the following option. The value should +## be a three item list, where the first item is the name of the +## desired (signed) type, the second item is the name of the +## corresponding unsigned type, and the third is the width of these +## types, in bytes. It is assumed that both the signed and unsigned +## types are the same width, as otherwise significant code breakage is +## expected. Example: +# $config SetValue program_compiler_c++_oc_index_type {int {unsigned int} 4} +# +## For OC_INDEX type checks. If set to 1, then various segments in +## the code are activated which will detect some array index type +## mismatches at link time. These tests are not comprehensive, and +## will probably break most third party code, but may be useful during +## development testing. +# $config SetValue program_compiler_c++_oc_index_checks 1 +# +## Flags to remove from compiler "opts" string: +# $config SetValue program_compiler_c++_remove_flags \ +# {-fomit-frame-pointer -fprefetch-loop-arrays} +# +## Flags to add to compiler "opts" string: +# $config SetValue program_compiler_c++_add_flags \ +# {-funroll-loops} +# +## Flags to add (resp. remove) from "valuesafeopts" string: +# $config SetValue program_compiler_c++_remove_valuesafeflags \ +# {-fomit-frame-pointer -fprefetch-loop-arrays} +# $config SetValue program_compiler_c++_add_valuesafeflags \ +# {-funroll-loops} +# +### Options for Xp_DoubleDouble high precision package +## Select base variable type. One of auto (default), double, long double +# $config SetValue program_compiler_xp_doubledouble_basetype {long double} +# +### Perform range checks? Enable to pass vcv tests. Default follows NDEBUG. +# $config SetValue program_compiler_xp_doubledouble_rangecheck 1 +# +## Use alternative single variable option, with variable one of double, +## long double, or MPFR. The last requires installation of the Boost +## multiprecision C++ libraries. +# $config SetValue program_compiler_xp_doubledouble_altsingle {long double} +# +## Disable (0) or enable (1) use of std::fma (fused-multiply-add) in the +## Xp_DoubleDouble package. Only use this if your architecture supports +## a true fma instruction with a single rounding. Default is to +## auto-detect at build time and use fma if it is single rounding. +# $config SetValue program_compiler_xp_use_fma 0 +# +## Disable (1) or enable (0, default) testing of Xp_DoubleDouble package. +# $config SetValue program_pimake_xp_doubledouble_disable_test 1 +### +# +## EXTERNAL PACKAGE SUPPORT: +## Extra include directories for compiling: +# $config SetValue program_compiler_extra_include_dirs /opt/local/include +# +## Extra directories to search for libraries. +# $config SetValue program_linker_extra_lib_dirs [list "/opt/local/lib"] +# +## Script to form library full name from stem name, for external libraries. +## This is usually not needed, as default scripts suffice. +# $config SetValue program_linker_extra_lib_scripts [list {format "lib%s.lib"}] +# +## Extra library flags to throw onto link command. Use sparingly --- +## for most needs program_linker_extra_lib_dirs and +## program_linker_extra_lib_scripts should suffice. +# $config SetValue program_linker_extra_args +# {-L/opt/local/lib -lfftw3 -lsundials_cvode -lsundials_nvecserial} +# +# END LOCAL CONFIGURATION +######################################################################## +# +# Default handling of local defaults: +# +if {[catch {$config GetValue oommf_threads}]} { + # Value not set in platforms/local/linux-arm64.tcl, + # so use Tcl setting. + global tcl_platform + if {[info exists tcl_platform(threaded)] \ + && $tcl_platform(threaded)} { + $config SetValue oommf_threads 1 ;# Yes threads + } else { + $config SetValue oommf_threads 0 ;# No threads + } +} +$config SetValue thread_count_auto_max 4 ;# Arbitrarily limit +## maximum number of "auto" threads to 4. +if {[catch {$config GetValue thread_count}]} { + # Value not set in platforms/local/linux-x86_64.tcl, so use getconf + # to report the number of "online" processors. NOTE: Neither + # _NPROCESSORS_ONLN nor processor_count in /proc/cpuinfo + # distinguish between physical cores and logical cores introduced + # via hyperthreading. + if {[catch {exec getconf _NPROCESSORS_ONLN} processor_count]} { + # getconf call failed. Try using /proc/cpuinfo + unset processor_count + catch { + set threadchan [open "/proc/cpuinfo"] + set cpuinfo [split [read $threadchan] "\n"] + close $threadchan + set proclist [lsearch -all -regexp $cpuinfo \ + "^processor\[ \t\]*:\[ \t\]*\[0-9\]+$"] + if {[llength $proclist]>0} { + set processor_count [llength $proclist] + } + } + } + if {[info exists processor_count]} { + set auto_max [$config GetValue thread_count_auto_max] + if {$processor_count>$auto_max} { + # Limit automatically set thread count to auto_max + set processor_count $auto_max + } + $config SetValue thread_count $processor_count + } +} +if {[catch {$config GetValue program_compiler_c++_override} compiler] == 0} { + $config SetValue program_compiler_c++ $compiler +} + +# The absolute, native filename of the null device +$config SetValue path_device_null {/dev/null} + +# Are we building OOMMF, or running it? +if {![info exists env(OOMMF_BUILD_ENVIRONMENT_NEEDED)] \ + || !$env(OOMMF_BUILD_ENVIRONMENT_NEEDED)} { + # Remainder of script concerns the build environment only, + # none of which is not relevant at run time. + unset config + return +} + +######################################################################## +# BUILD CONFIGURATION + +# Compiler option processing... +if {[string match g++ [file tail [lindex \ + [$config GetValue program_compiler_c++] 0]]]} { + # ...for GNU g++ C++ compiler + set opts {} + set gccexec [lindex [$config GetValue program_compiler_c++] 0] + if {![info exists gcc_version]} { + set gcc_version [GuessGccVersion $gccexec] + } + + # User-requested optimization level + if {[catch {Oc_Option GetValue Platform optlevel} optlevel]} { + set optlevel 2 ;# Default + } + + # Default warnings disable + set nowarn [list -Wno-non-template-friend] + if {[info exists nowarn] && [llength $nowarn]>0} { + set opts [concat $opts $nowarn] + } + catch {unset nowarn} + + # Aggressive optimization flags, some of which are specific to + # particular gcc versions, but are all processor agnostic. + set valuesafeopts [concat $opts \ + [GetGccValueSafeOptFlags $gcc_version $optlevel]] + set opts [concat $opts [GetGccGeneralOptFlags $gcc_version $optlevel]] + + # Make user requested tweaks to compile line options + set opts [LocalTweakOptFlags $config $opts] + set valuesafeopts [LocalTweakValueSafeOptFlags $config $valuesafeopts] + + # NOTE: If you want good performance, be sure to edit ../options.tcl + # or ../local/options.tcl to include the line + # Oc_Option Add * Platform cflags {-def NDEBUG} + # so that the NDEBUG symbol is defined during compile. + $config SetValue program_compiler_c++_option_opt "format \"$opts\"" + $config SetValue program_compiler_c++_option_valuesafeopt \ + "format \"$valuesafeopts\"" + $config SetValue program_compiler_c++_option_out {format "-o \"%s\""} + $config SetValue program_compiler_c++_option_src {format \"%s\"} + $config SetValue program_compiler_c++_option_inc {format "\"-I%s\""} + $config SetValue program_compiler_c++_option_debug {format "-g"} + $config SetValue program_compiler_c++_option_def {format "\"-D%s\""} + + # Widest natively support floating point type + if {[catch {$config GetValue program_compiler_c++_typedef_realwide}]} { + $config SetValue program_compiler_c++_typedef_realwide "double" + } + + # Directories to exclude from explicit include search path, i.e., + # the -I list. Some versions of gcc complain if "system" directories + # appear in the -I list. + $config SetValue \ + program_compiler_c++_system_include_path [list /usr/include] +} + + +######################################################################## +# If we're linking to the Tcl and Tk shared libraries, we don't need to +# explicitly pull in the extra libraries set in the TCL_LIBS and TK_LIBS +# variables by tclConfig.sh and tkConfig.sh. Moreover, the TK_LIBS list +# may contain libraries such as -lXft that aren't installed on the oommf +# target. For Tcl/Tk 8.3 and latter, shared libraries are the default. +# Adjust as necessary. +set major [set minor [set serial 0]] +foreach {major minor serial} [split [info patchlevel] .] { break } +if {$major>8 || ($major==8 && $minor>=3)} { + $config SetValue TCL_LIBS {} + $config SetValue TK_LIBS {} +} +unset major ; unset minor ; unset serial + +######################################################################## +if {[catch {$config GetValue program_linker_extra_libs} extra_libs]} { + set extra_libs {} +} +if {[llength $extra_libs]>0} { + $config SetValue TCL_LIBS [concat [$config GetValue TCL_LIBS] $extra_libs] + $config SetValue TK_LIBS [concat [$config GetValue TK_LIBS] $extra_libs] +} + + +# The program to run on this platform to link together object files and +# library files to create an executable binary. +# +# Use the selected compiler to control the linking. +$config SetValue program_linker [lindex \ + [$config GetValue program_compiler_c++] 0] + +# Linker option processing... +if {[string match g++ [file tail [lindex \ + [$config GetValue program_linker] 0]]]} { + # ...for GNU g++ as linker + $config SetValue program_linker_option_obj {format \"%s\"} + $config SetValue program_linker_option_out {format "-o \"%s\""} + $config SetValue program_linker_option_lib {format \"%s\"} + $config SetValue program_linker_uses_-L-l {1} +} + +# The program to run on this platform to create a single library file out +# of many object files. +$config SetValue program_libmaker {ar cr} + +if {[string match ar [file tail [lindex \ + [$config GetValue program_libmaker] 0]]]} { + # Option processing for ar + $config SetValue program_libmaker_option_obj {format \"%s\"} + $config SetValue program_libmaker_option_out {format \"%s\"} +} + +# A partial Tcl command (or script) which when completed by lappending +# a file name stem and evaluated returns the corresponding file name for +# an executable on this platform +$config SetValue script_filename_executable {format %s} + +# A partial Tcl command (or script) which when completed by lappending +# a file name stem and evaluated returns the corresponding file name for +# an object file on this platform +$config SetValue script_filename_object {format %s.o} + +# A partial Tcl command (or script) which when completed by lappending +# a file name stem and evaluated returns the corresponding file name for +# a static library on this platform +$config SetValue script_filename_static_library {format lib%s.a} + +######################################################################## +unset config