nvfortran(1)

๐Ÿ“ฆ version 26.9, in arch rolling

๐ŸŽ€ nvfortran(1) ๐ŸŽ€

okay so real talk, this page comes straight out of the General Commands Manual, and it's the full spec for nvfortran. grab a snack, we're going in ๐Ÿ’–

โœจ NAME โœจ

nvfortran โ€” The NVIDIA Fortran compiler. that's her. that's the whole name section. iconic.

โœจ SYNOPSIS โœจ

nvfortran [ -flag ]...  sourcefile...

โœจ DESCRIPTION โœจ

pgfortran is an alias for nvfortran โ€” same compiler, different name, iykyk ๐Ÿซถ

nvfortran is a Fortran compiler for NVIDIA GPUs and AMD and Intel CPUs. it supports ISO Fortran 2003 (yes, all of it) plus a bunch of Fortran 2008 features, it does GPU parallel programming with OpenACC, and it does multicore CPU programming with OpenACC and OpenMP. she's versatile like that. nvfortran invokes the Fortran compiler, assembler, and linker, with options derived from its command line arguments โ€” so the flags you type literally steer the whole pipeline ๐ŸŒˆ

so, the suffix of your source file name tells her what to do with it. no guessing, the extension is the vibe check:

  • .f, .for, .ftn โ€” fixed-format Fortran source; compile
  • .f90, .f95, .f03 โ€” free-format Fortran source; compile
  • .F, .FOR, .FTN, .fpp, .FPP โ€” fixed-format Fortran source; preprocess, compile
  • .F90, .F95, .F03 โ€” free-format Fortran source; preprocess, compile
  • .cuf โ€” free-format CUDA Fortran source; compile
  • .CUF โ€” free-format CUDA Fortran source; preprocess, compile
  • .s โ€” assembler source; assemble
  • .S โ€” assembler source; preprocess, assemble
  • .o โ€” object file; passed to linker
  • .a โ€” library archive file; passed to linker

C file suffixes are also recognized and compiled with the NVC compiler; see NVC and NVIDIA User's Guide. anything else gets passed to the linker (if linking is requested) with a warning message โ€” so like, she'll do it, but she's gonna be vocal about it ๐Ÿ™ˆ

Unless you override the default action using a command-line option, nvfortran deletes the intermediate preprocessor and assembler files (see the options -c, -E, -F, and -Mkeepasm). and if a single Fortran program is compiled and linked with one nvfortran command, the intermediate object file is also deleted. linking is the last stage of the compile process โ€” unless you use one of the -c, -E, -F, or -S options, or unless compilation errors stop the whole process. so if the build dies halfway, bestie, nothing is getting cleaned up nicely ๐Ÿ˜ญ


โœจ OPTIONS โœจ

โš ๏ธ options must be separate โ€” -cs is different from -c -s. do not combine, do not pass go. she will not read your mind ๐Ÿ’€

here's the full list of all the options, grouped by type. the detailed explanations live in the sections that follow.

๐ŸŒธ Overall Options

  • --
  • -#
  • -###
  • -c
  • -[no]defaultoptions
  • -dryrun
  • -drystdinc
  • -dumpversion
  • -echo
  • --flagcheck
  • -flags
  • -fmax-errors=<n>
  • --gcc-toolchain=path
  • -help[=option]
  • -Manno
  • -Minform=level
  • -Mdetail
  • -Mkeepasm
  • -M[no]list
  • -noswitcherror
  • -o file
  • -rc rcfile
  • -S
  • -show
  • -silent
  • -time
  • -V
  • -V<ver>
  • -v
  • --version
  • -w
  • -Werror
  • -x language
  • -x none
  • -Wpass,option
  • -Ypass,directory

๐Ÿ”ฅ Optimization Options

  • -fast
  • -f[no-]cx-limited-range
  • -fastsse
  • -fPIC
  • -fpic
  • -KPIC
  • -Kpic
  • -Mcache_align
  • -Mconcur=option
  • -M[no]depchk
  • -M[no]dse
  • -Mextract=option
  • -M[no]fma
  • -M[no]frame
  • -M[no]idiom
  • -M[no]info=option
  • -Minline=option
  • -Minstrument=option
  • -M[no]ipa=option
  • -M[no]lre[=assoc|noassoc]
  • -M[no]movnt
  • -Mneginfo=option
  • -Mnoopenmp
  • -Mnosgimp
  • -Mnovintr
  • -Mpfi[=option]
  • -Mpfo[=option]
  • -M[no]pre
  • -M[no]prefetch=option
  • -Mprof=option
  • -M[no]propcond
  • -Mquad
  • -Msafe_lastval
  • -M[no-]signed-zeros
  • -M[no]stride0
  • -M[no]unroll=option
  • -M[no]unsafe_par_align
  • -M[no]vect=option
  • -M[no]zerotrip
  • -mp[=option]
  • -nomp
  • -Olevel
  • -pg

๐Ÿฆ‹ Debugging Options

  • -C
  • -g
  • -gopt
  • -M[no]bounds
  • -Mchkptr
  • -Mchkstk
  • -Mcoff
  • -Mdwarf2
  • -Mdwarf3
  • -Melf
  • -Mnodwarf
  • -[no]traceback

๐Ÿ’œ Preprocessor Options

  • -Dmacro
  • -E
  • -F
  • -Idirectory
  • -isystem directory
  • -Mcpp=[[no]comment|m|md|mm|mmd|mq:target|mt:target|suffix:suff]
  • -Mnostddef
  • -Mnostdinc
  • -Mpreprocess
  • -Umacro
  • -YI,directory
  • -Yp,directory

๐Ÿงš Assembler Options

  • -Wa,argument[,argument]...
  • -Ya,directory

๐Ÿ“ Linker Options

  • -acclibs
  • --[no-]as-needed
  • -Bdynamic
  • -Bstatic
  • -Bstatic-nvidia
  • -c++libs
  • -cudaforlibs
  • -cudalib=libname
  • -cudalibs
  • -fortranlibs
  • -g77libs
  • -Ldirectory
  • -llibrary
  • -m
  • -Mcudalib=libname
  • -M[no]eh_frame
  • -Mnostartup
  • -Mnostdlib
  • -M[no]rpath
  • -Mmkl
  • -nvmalloc
  • -pthread
  • -Rdirectory
  • -r
  • -rpath directory
  • -s
  • -shared
  • -soname name
  • -static
  • -static-nvidia
  • -uname
  • --[no-]whole-archive
  • -Wl,option[,option]...
  • -Xlinker option[,option]...
  • -YC,directory
  • -Yl,directory
  • -YL,directory
  • -YS,directory
  • -YU,directory

โญ Language Options

  • -asmsuffix=suffix
  • -byteswapio
  • -csuffix=suffix
  • -fsuffix=suffix
  • -FSUFFIX=suffix
  • -cuda=option
  • -i2
  • -i4
  • -i8
  • -i8storage
  • -Mallocatable[=95|03]
  • -M[no]backslash
  • -Mbyteswapio
  • -Mcray=pointer
  • -Mcuda=option
  • -M[no]dalign
  • -M[no]dclchk
  • -M[no]defaultunit
  • -M[no]dlines
  • -Mdollar=char
  • -Mextend
  • -Mfixed
  • -M[no]free[form]
  • -M[no]i4
  • -M[no]iomutex
  • -Mlibsuffix=suffix
  • -M[no]llalign
  • -Mnomain
  • -Mobjsuffix=suffix
  • -M[no]onetrip
  • -M[no]r8
  • -M[no]r8intrinsics=float
  • -M[no]recursive
  • -M[no]ref_externals
  • -M[no]save
  • -M[no]signextend
  • -M[no]stack_arrays
  • -Mstandard
  • -Msyntax-only
  • -M[no]unixlogical
  • -M[no]upcase
  • -module directory
  • -Munlink_module
  • -r4
  • -r8
  • -Wh,argument[,argument]...

๐Ÿ‘‘ Target-specific Options

  • -acc
  • -noacc
  • -gpu=option
  • -K[no]ieee
  • -Ktrap=option
  • -march=target
  • -m[no-]daz-ftz
  • -M[no]daz
  • -M[no]flushz
  • -M[no]fpmisalign
  • -M[no]fprelaxed=option
  • -M[no]func32
  • -M[no]longbranch
  • -M[no]second_underscore
  • -M[no]varargs
  • -Mwritable-strings
  • -mcmodel=small|medium
  • -stdpar=option
  • -nostdpar
  • -ta=target
  • -target=option
  • -tp=target

๐Ÿ’€ bestie listen to me. when source files are compiled using any of the following options, the same option(s) should be passed when using nvfortran to link the objects: -g -mp -Mconcur -Mipa -Mprof. don't compile with the sauce and then link without it, that's how you get mystery behaviour and a sad afternoon ๐Ÿ˜ญ

more sections incoming, stay with me ๐Ÿ’…

โœจ Overall Options โœจ

  • -- โ€” everything after this switch gets treated as a filename, periodt. Ngl though, most tools won't let a filename start with a dash anyway, so likeโ€ฆ maybe just don't? ๐Ÿซถ
  • -# โ€” shows you the invocations of the compiler, assembler, and linker. These are literally the command lines that nvfortran created. peek behind the curtain bestie ๐Ÿ’…
  • ### โ€” same vibe, but it shows the invocations of the compiler, assembler and linker and does not execute them. window shopping only ๐Ÿ’–
  • -c โ€” skips the link step entirely; compile and assemble only. no linking, no problem โœจ
  • -defaultoptions (default) / -nodefaultoptions โ€” use (or don't use) the default options that are set in site-specific or user-specific PREOPTIONS or POSTOPTIONS driver variables. you're the main character, you decide ๐ŸŽ€
  • -dryrun โ€” displays the invocations of the compiler, assembler, and linker but does not execute them. all the lore, none of the consequences ๐Ÿ”ฅ
  • -drystdinc โ€” displays the standard include directories without even invoking the compiler. just a little peek ๐Ÿ‘€
  • -dumpversion โ€” displays the shortened version of the compiler. for example, 21.11 or 22.3. cute little version drop ๐Ÿ’œ
  • -echo [=go|stop] โ€” echoes the command line flags and (by default) stops. this is lowkey iconic when the compiler is invoked by a script.
    • go โ€” don't stop after echoing the command line.
    • stop (default) โ€” do stop after echoing the command line.
  • --flagcheck โ€” doesn't compile anything, just emits any messages for command-line switch errors. returns a success error code if there are no command-line switch errors. a whole vibe check for your flags โญ
  • -flags โ€” displays all valid nvfortran command-line options in alphabetical order. the full alphabetized menu, slay ๐Ÿ“
  • -fmax-errors=<n> โ€” specifies the max number of errors before compilation terminates. (the manpage says "maximun" and honestly? iconic typo behavior, we love her ๐Ÿ’€)
  • *--gcc-toolchain=path* โ€” specifies the gcc toolchain location using path to the gcc directory or the gcc executable. the argument can be the gcc root directory, <root directory>/bin, or the gcc executable itself. flexible queen ๐ŸŒธ
  • -help[=option] โ€” displays command-line options recognized by nvfortran on the standard output. nvfortran -help -otherswitch gives you help about -otherswitch. the default is to list nvfortran command line options by group. the options are:
    • groups โ€” prints out the groups into which the switches are organized.
    • asm โ€” print help for assembler command-line options.
    • debug โ€” print help for debugging command-line options.
    • language โ€” print help for language-specific command-line options.
    • linker โ€” print help for linker options.
    • opt โ€” print help for optimization command-line options.
    • other โ€” print help for any other command-line options.
    • overall โ€” print help for overall command-line options.
    • phase โ€” print help for the known compiler phases.
    • prepro โ€” print help for preprocessor command-line options.
    • suffix โ€” describe the known file suffixes.
    • switch โ€” print all switches in alphabetical order.
    • target โ€” print help for target-specific command-line options.
    • variable โ€” show the nvfortran configuration; this is the same as -show.
  • -Manno โ€” produces annotated assembly files where the source code is intermixed with assembly language. implies -Mkeepasm. a little collage of code ๐ŸŽจ
  • *-Minform=level* โ€” specifies the minimum level of error severity that the compiler displays during compilation.
    • fatal โ€” tells the compiler to display fatal error messages.
    • file (default) / nofile โ€” print out (don't print out) the names of files as they are compiled; this is only active when there's more than one file on the command line.
    • severe โ€” tells the compiler to display severe and fatal error messages.
    • warn โ€” tells the compiler to display warning, severe and fatal error messages.
    • inform โ€” tells the compiler to display all error messages (inform, warn, severe and fatal).

the default is -Minform=warn. yes, both defaults are stated, that's just how she is ๐Ÿ’…

  • -Mdetail โ€” displays enhanced error messages that include a source line and column pointer. currently available for syntax errors and some semantic errors. she's pointing at exactly where you messed up, lovingly ๐Ÿซถ
  • -Mkeepasm โ€” keeps the assembly file for each source file, but continues to assemble and link the program. mainly for compiler performance analysis and debugging. keeping the receipts, ngl ๐Ÿงพ
  • -Mlist / -Mnolist (default) โ€” create (or don't create) a listing file.
  • -noswitcherror โ€” ignores unknown command line switches after printing a warning message. the default behavior is to print an error message and halt. choose chaos ๐Ÿ˜ญ
  • -o file โ€” use file as the name of the executable program instead of the default a.out. if used with -c or -S and a single input file, file is used as the name of the object or assembler output file. name your baby ๐Ÿ‘‘
  • -rc rcfile โ€” specifies the name of an nvfortran startup configuration file. if rcfile is a full pathname, then use the specified file. if rcfile is a relative pathname, use the file name as found in the $DRIVER directory. โœจ
  • -S โ€” skips the assembly and link steps. leaves the output from the compile step in a file named file.s for each file named, for instance, file.f. see also -o. assembly only, we're being efficient ๐ŸŒˆ
  • -show โ€” produces help information describing the current nvfortran configuration. ๐Ÿฆ‹
  • -silent โ€” do not print warning messages. same as -Minform=severe. shhh ๐Ÿคซ
  • -time โ€” prints execution times for the various steps in the compiler itself. clocking the tea โ˜•
  • -V โ€” displays version messages and other information. ๐Ÿ’–
  • -V<ver> โ€” if the specified version of the compiler is installed, that version of the compiler is invoked. pick your era ๐Ÿ”ฅ
  • -v โ€” verbose mode; prints out the command line for each tool before it's executed. she's narrating everything, and honestly? we're listening ๐Ÿ’…
  • --version โ€” displays version messages and other information.
  • -w โ€” do not print warning messages. ๐Ÿ™ˆ
  • -Werror โ€” turns all warning messages into errors. no notes, everything is a problem now ๐Ÿ’€
  • -x language โ€” explicitly specifies the language for the input files (instead of choosing based on the file name suffix). possible values for language are:
c

cpp c++ cpp-output

f F

f95 f95-cpp-input

f90 F90

f77 f77-cpp-input

cuf CUF

asm ASM assembler assembler-with-cpp
  • -x none โ€” turns off language specification, so the input files are handled according to their suffixes. back to vibes-based detection โœจ
  • -Wpass,option[,option...] โ€” passes option to the specified pass. each comma-delimited option is passed as a separate argument. the passes are:
    • h โ€” for the Fortran 90/95 front end,
    • 0 โ€” for the compiler back end,
    • a โ€” for the assembler,
    • i โ€” for the interprocedural analyzer, and
    • l โ€” for the linker.
  • *-Ypass,directory* โ€” look in directory for pass pass, rather than in the standard area. the passes are:
    • h โ€” search for the Fortran 90/95 front end executable in directory.
    • 0 โ€” search for the compiler back end executable in directory.
    • a โ€” search for the assembler executable in directory.
    • C โ€” search for the compiler library in directory.
    • i โ€” search for the InterProcedural Analyzer (IPA) in directory.
    • l โ€” search for the linker in directory.
    • I โ€” set the compiler's standard include directory to directory. the standard include directory is set to a default value by the driver and can be overridden by this option.
    • L โ€” if the linker supports the -YL option, then pass the option -YL,directory to the linker. otherwise, use directory as the standard library location.
    • S โ€” search for the startup object files in directory.
    • U โ€” if the linker supports the -YU option, then pass the option -YU,directory to the linker. otherwise this option is ignored.

๐Ÿ”ฅ Optimization Options ๐Ÿ”ฅ

  • -fast โ€” chooses generally optimal flags for the target platform. use nvfortran -fast -help to see the equivalent switches. note this sets the optimization level to a minimum of 2; see -O. the glow-up option, fr fr ๐Ÿ‘‘
  • -fcx-limited-range โ€” specifies that complex division does not need range reduction. -fno-cx-limited-range specifies that complex division does need range reduction. -fcx-limited-range is the default setting at optimization level -Ofast. ๐ŸŒ€
  • -fastsse โ€” chooses generally optimal flags for a processor that supports vectorizing for the SSE/AVX instructions. use nvfortran -fastsse -help to see the equivalent switches. โšก
  • -fPIC โ€” equivalent to -fpic; provided for compatibility with other compilers. ๐Ÿ’œ
  • -fpic โ€” tells the compiler to generate position-independent code which can be used to create shared object files (dynamically linked libraries). move anywhere, babe ๐Ÿฆ‹
  • -KPIC โ€” equivalent to -fpic; provided for compatibility with other compilers.
  • -Kpic โ€” equivalent to -fpic; provided for compatibility with other compilers.
  • -Mcache_align โ€” aligns unconstrained data objects of size greater than or equal to 16 bytes on cache-line boundaries. an unconstrained object is a variable or array that is not a member of an aggregate structure or common block, isn't allocatable, and isn't an automatic array. aligned and unbothered ๐Ÿ’…
  • -Mconcur[=option[,option...]] โ€” okay so heads up: this option has been deprecated and will be removed in a future release. ๐Ÿšจ it tells the compiler to enable auto-concurrentization of loops. this also sets the optimization level to a minimum of 2; see -O. if -Mconcur is specified, multiple processors will be used to execute loops which the compiler determines to be parallelizable. when linking, the -Mconcur switch must be specified or unresolved references will occur. the OMP_NUM_THREADS or NCPUS environment variables control how many processors will be used to execute parallelized loops. the options can be one or more of the following:
  • allcores โ€” bestie, this one uses all available cores when the environment variables OMP_NUM_THREADS and NCPUS aren't set. Tiny catch: you must specify it at link time. โœจ
  • altcode:n, noaltcode โ€” generate (or don't generate, with noaltcode) alternate scalar code for parallelized loops. The parallelizer whips up scalar code that runs whenever the loop count is less than or equal to n. But if you say noaltcode? The parallelized version of the loop runs always, no matter how smol the loop count is. ๐Ÿ’…
  • altreduction[:n] โ€” same energy, but for parallelized loops that contain a reduction. If a parallelized loop has a reduction in it, the parallelizer generates scalar code to run whenever the loop count is less than or equal to n. ๐ŸŽ€
  • assoc (default), noassoc โ€” enable (or disable) parallelization of loops with reductions. It's giving "on by default, bestie."
  • cncall, nocncall (default) โ€” assume (or don't assume) that loops containing calls are safe to parallelize. Also, no minimum loop count threshold has to be satisfied before parallelization kicks in, and the last values of scalars are assumed to be safe. ๐Ÿซถ
  • dist:block โ€” parallelize with block distribution. Contiguous blocks of iterations of a parallelizable loop get handed out to the available processors. Chunky slices, no cap. ๐Ÿ“
  • dist:cyclic โ€” parallelize with cyclic distribution. The outermost parallelizable loop in any loop nest is the one that gets parallelized. If the parallelized loop is innermost, its iterations are allocated to processors cyclically. Like, if there are 3 processors executing a loop: processor 0 performs iterations 0, 3, 6, etc; processor 1 performs iterations 1, 4, 7, etc; and processor 2 performs iterations 2, 5, 8, etc. Round-robin slay. ๐ŸŒˆ
  • innermost, noinnermost (default) โ€” enable (or disable) parallelization of innermost loops.
  • levels:n โ€” parallelize loops nested at most n levels deep; the default is 3. ๐ŸŒธ

  • -Mdepchk (default), -Mnodepchk โ€” assume (or don't assume) that potential data dependencies exist.
๐Ÿ’€ Heads up: -Mnodepchk may result in incorrect code. Not me warning you and then you doing it anyway...
  • -Mdse, -Mnodse (default) โ€” enable (or disable) the dead store elimination optimization.
  • -Mextract=[option[,option,...]] โ€” runs the subprogram extraction phase to prep for inlining. The =lib:filename option must be used with this switch to name an extract library. See -Minline for more details on inlining. The options are:
    • subprogram[,subprogram] โ€” a non-numeric option that doesn't contain a period is assumed to be the name of a subprogram to be extracted. ๐Ÿ‘‘
    • name:subprogram[,subprogram] โ€” specifies the name of a subprogram or subprograms to be extracted.
    • lib:directory โ€” specifies the name of a directory to contain the extracted subprograms; this directory gets created if it doesn't already exist. โœจ
    • [size:]number โ€” a numeric option is assumed to be a size. Functions containing number or fewer statements are extracted. And if both number and function are specified? Then functions matching the given name(s) or meeting the size requirements are extracted.
  • -Mfma, -Mnofma (default) โ€” generate (or don't generate) fused multiply-add (FMA) instructions on the CPU and GPU for targets that support it. FMA instructions are generally faster than separate multiply-add instructions, and they can generate higher-precision results since the multiply result isn't rounded before the addition. ๐Ÿ’–

But real talk: delaying rounding until after the addition may cause results to differ from those you'd get with unfused multiply-add instructions. So like, vibe check your numerics. FMA instructions are enabled at optimization levels higher than -O1.

  • -Mframe, -Mnoframe (default) โ€” set up (or don't set up) a true stack frame pointer for functions. -Mnoframe allows slightly more efficient operation when a stack frame isn't needed โ€” but some options override -Mnoframe, so don't come for it when that happens. ๐Ÿฆ‹
  • -Midiom, -Mnoidiom (default) โ€” enable loop idiom recognition. Memory copy, memory set, and memory zero loops are recognized and replaced with calls to their respective optimized versions. It's called efficiency, look it up. ๐Ÿ”ฅ
  • -Minfo[=option[,option,...]], -Mnoinfo (default) โ€” emit useful information to stderr. The options are:
    • all โ€” includes the options accel, inline, ipa, loop, lre, mp, opt, par, stdpar, vect. The whole buffet. ๐Ÿ‘‘
    • accel โ€” emit information about accelerator region targeting.
    • ftn โ€” emit Fortran-specific information.
    • inline โ€” emit information about functions extracted and inlined.
    • intensity โ€” โš ๏ธ this option has been deprecated and will be removed in a future version. Emit compute intensity information about loops.
    • ipa โ€” emit information about the optimizations enabled by interprocedural analysis (IPA).
    • loop | opt โ€” emit information about loop optimizations. This includes info about vectorization and loop unrolling. ๐ŸŒŸ
    • lre โ€” emit information about loop-carried redundancy elimination.
    • mp โ€” emit information about OpenMP parallel regions.
    • par โ€” emit information about loop parallelization.
    • pfo โ€” emit profile feedback information.
    • time | stat โ€” emit compilation statistics.
    • stdpar โ€” emit information about parallelization of C++ parallel algorithms and Fortran DO CONCURRENT loops.
    • vect โ€” emit information about automatic loop vectorization.

With no options, -Minfo is the same as -Minfo=accel,ipa,loop,lre,mp,opt,par,stdpar,vect. โœจ

  • -Minline[=option[,option,...]] โ€” passes options to the function inliner. The options are:
    • lib:filename.ext โ€” specify an inline library created by a previous -Mextract option. Functions from the specified library get inlined. If no library is specified, functions are extracted from a temporary library created during an extract prepass. ๐ŸŽ€
    • except:func โ€” specifies which functions should not be inlined. (The "you're not invited" list.)
    • [name:]function โ€” a non-numeric option is assumed to be a function name. If name: is specified, whatever follows is always the name of a function.
    • pragma โ€” Fortran Only: inline only those procedures that have a !NVF$ INLINE pragma on the source line immediately before the procedure's SUBROUTINE or FUNCTION statement. ๐Ÿ’…
    • [maxsize:]number โ€” a numeric option is assumed to be a size. Functions of size number or less are inlined. If both number and function are specified, then functions matching the given name(s) or meeting the size requirements get inlined.
    • reshape โ€” for Fortran, the default is to not inline subprograms with array arguments if the array shape doesn't match the shape in the caller. This option overrides that default. ๐Ÿฆ‹
    • smallsize:number โ€” always inline functions of size smaller than number, regardless of other size limits. Tiny function rights!! ๐Ÿฅบ
    • totalsize:number โ€” stop inlining in a function when that function's total inlined size reaches the number specified. Boundaries, bestie. ๐Ÿ›‘
  • -Minstrument [=option] โ€” generate additional code to enable function-level instrumentation. This option implies -Mframe. The option is:
    • functions (default)
  • -Mipa [=option[,option,...]], -Mnoipa (default) โ€” enable and specify options for InterProcedural Analysis (IPA).
๐Ÿ˜ญ Note: IPA is not compatible with parallel make environments (e.g., pmake). Also, IPA sets the optimization level to a minimum of 2; see -O. If no option list is specified, then it's equivalent to -Mipa=const.

The options are:

  • align, noalign (default) โ€” enable (or disable) recognition when pointer targets are all cache-line aligned, which allows better SSE code generation. โœจ
  • arg, noarg (default) โ€” remove (or don't remove) arguments replaced by -Mipa=ptr,const. Note: -Mipa=noarg implies -Mipa=nolocalarg. ๐Ÿ”
  • const (default), noconst โ€” enable (or disable) propagation of constants across procedure calls.
  • f90ptr, nof90ptr (default) โ€” enable (or disable) Fortran 90 pointer disambiguation across procedure calls.
  • fast โ€” chooses generally optimal -Mipa flags for the target platform; run nvfortran -Mipa -help to see the equivalent options. ๐ŸŒˆ
  • force โ€” force all objects to recompile regardless of whether IPA information has changed. Blunt but effective.
  • globals, noglobals (default) โ€” analyze (or don't analyze) which globals are modified by procedure calls.
  • inline:n โ€” determine additional functions to inline, allowing up to n levels of inlining. Additional suboptions are:
    • except:proc โ€” disables inlining of procedure proc.
    • nopfo โ€” ignore any profile frequency information from -Mpfo when choosing which functions to inline.
    • reshape, noreshape (default) โ€” enable (or disable) Fortran inlining with mismatched array shapes. ๐Ÿ›
  • ipofile โ€” save IPA information in a .ipo file instead of the default of appending the information to the object file. ๐Ÿ“
  • jobs:n โ€” use up to n jobs in parallel to reoptimize object files. Multitasking queen. ๐Ÿ‘‘
  • keepobj (default) / nokeepobj โ€” keep (or don't keep) the optimized object files, using file name mangling, so your later builds recompile faster. Free speed, bestie ๐Ÿซถ
    • libc / nolibc (default) โ€” optimize calls to certain standard C library routines.
    • libinline / nolibinline (default) โ€” allow (or don't allow) inlining from routines in libraries. Heads up: -Mipa=libinline implies -Mipa=inline โœจ
    • libopt / nolibopt (default) โ€” allow (or don't allow) recompiling and reoptimizing routines from libraries with IPA info.
    • localarg / nolocalarg (default) โ€” enable (or disable) the feature that externalizes local variables so arguments can be replaced by -Mipa=ptr. Also: -Mipa=localarg implies -Mipa=arg.
    • main:func โ€” name a function to serve as a global entry point. You can use this multiple times, but it disables linking. ๐Ÿ‘€
    • ptr / noptr (default) โ€” enable (or disable) pointer disambiguation across procedure calls.
    • pure / nopure (default) โ€” detect (or don't detect) pure functions.
    • quiet โ€” don't print out messages about which files get recompiled at link time. Silence is the vibe ๐Ÿคซ
    • reaggregation / noreaggregation (default) โ€” enable (or disable) global struct reaggregation. Real talk: this can change the order of struct members, or split structs into multiple structs, to improve memory locality and cache utilization. It be rearranging your structs ๐Ÿ˜ญ
    • required โ€” return an error condition if IPA is inhibited for any reason, instead of the default behavior of just linking without IPA optimization.
    • safe:[function|library] โ€” declares that the named function, or all functions in the named library, are safe. A safe procedure doesn't call back into the known procedures and doesn't change any known global variables. Without -Mipa=safe, any unknown procedures will cause IPA to fail. โš ๏ธ
    • safeall / nosafeall (default) โ€” declares that all unknown functions are safe (or not safe); see -Mipa=safe.
    • shape / noshape (default) โ€” perform (or don't perform) Fortran 90 shape propagation.
    • summary โ€” only collect IPA summary information when compiling. This blocks IPA optimization of this file, but lets other files linked with it get optimized. It's giving teamwork ๐Ÿ’…
    • vestigial / novestigial (default) โ€” remove (or don't remove) functions that are never called.
  • -Mlre[=assoc|noassoc], -Mnolre โ€” enable (or disable) loop-carried redundancy elimination. The assoc option allows expression reassociation, and noassoc disallows expression reassociation.
  • -Mmovnt, -Mnomovnt โ€” force (or disable) generation of nontemporal moves. Fun fact: -Mmovnt used with -fastsse can sometimes be faster than -fastsse alone ๐Ÿ”ฅ By default, nontemporal moves are generated for loops with large loop counts.
  • -Mneginfo=option[,option...] โ€” tells the compiler to produce info on why certain optimizations aren't performed. But bestie, use the -Minfo flag instead. ๐Ÿ™ˆ
  • -Mnoopenmp โ€” when -mp is present, ignore the OpenMP pragmas.
  • -Mnosgimp โ€” when -mp is present, ignore the SGI parallelization pragmas.
  • -Mnovintr โ€” do not generate vector intrinsic calls.
  • -Mpfi[=option] โ€” generate profile feedback instrumentation. This includes extra code to collect run-time statistics used in a subsequent compile, and -Mpfi must also appear when the program is linked. When the program runs, a profile feedback file pgfi.out gets generated; see -Mpfo. The allowed options are:
    • indirect / noindirect (default) โ€” enable (or disable) collection of indirect function call targets, which can be used for indirect function call inlining.
  • -Mpfo[=option[,option,...]] โ€” enable profile feedback optimizations. There must be a profile feedback file pgfi.out in the current directory, containing the result of running the program compiled with -Mpfi. The options are:
    • indirect / noindirect (default) โ€” enable (or disable) indirect function call inlining; this requires a pgfi.out file generated from a binary built with -Mpfi=indirect.
    • layout (default) / nolayout โ€” enable (or disable) basic block layout, so it takes advantage of instruction cache locality by keeping hot paths close together. Hot paths stay close, iykyk ๐Ÿ”ฅ
    • dir=directory โ€” specify the directory containing the pgfi.out profile feedback information file; the default is the current directory.
  • -Mpre, -Mnopre (default) โ€” enable (or disable) the partial redundancy elimination optimization.
  • -Mprefetch[=option:n], -Mnoprefetch โ€” add (or don't add) prefetch instructions for the processors that support them (Pentium 4, Opteron). -Mprefetch is default on Opteron; -Mnoprefetch is default on other processors. The options are:
    • distance:d โ€” set the fetch-ahead distance for prefetch instructions to d cache lines.
    • n:n โ€” set the maximum number of prefetch instructions to generate in a loop to n.
    • nta โ€” use the prefetchnta instruction.
    • plain โ€” use the prefetch instruction.
    • t0 โ€” use the prefetcht0 instruction.
    • w โ€” allow the AMD-specific prefetchw instruction.
  • -Mprof[=option[,option,...]] โ€” set performance profiling options. Using these makes the resulting executable create a performance profile you can view and analyze with the PGPROF performance profiler โœจ For the descriptions below: old-style profiling means compiler-generated source instrumentation, and MPICH-style profiling means using instrumented wrappers for MPI library routines. The -Mprof options are:
    • dwarf โ€” generate limited DWARF symbol information, which is enough for most performance profilers.
    • func โ€” perform old-style function level profiling.
    • hwcts โ€” generate a profile using event-based sampling of hardware counters via the PAPI interface (PAPI must be installed).
    • lines โ€” perform old-style line level profiling.
    • time โ€” generate a profile using time-based instruction-level statistical sampling. This is equivalent to -pg, except the profile is saved in a file named pgprof.out instead of gmon.out.
On Linux systems that have OProfile installed, PGPROF supports collection of performance data without recompilation. Using -Mprof=dwarf is useful for this mode of profiling. ๐Ÿ‘‘
  • -Mpropcond (default), -Mnopropcond โ€” enable (or disable) propagation of constant values derived from conditional branches with equality tests.
  • -Mquad โ€” align large objects on quad-word boundaries.
  • -Msafe_lastval โ€” okay so picture this: a scalar is used after a loop, but it's not defined on every iteration of the loop. By default the compiler does not parallelize that loop. This option tells the compiler it's safe to parallelize it. Your call, bestie ๐Ÿซถ
  • -Msigned-zeroes (default), -Mno-signed-zeros โ€” toggles whether to honor (-Msigned-zeros) or ignore (-Mno-signed-zeros) issues associated with a signed 0.0 during optimization.
  • -Mstride0, -Mnostride0 (default) โ€” generate (or don't generate) alternate code for a loop that contains an induction variable whose increment may be zero.
  • -Munroll[=option[,option...]], -Mnounroll (default) โ€” invoke (or don't invoke) the loop unroller. This also sets the optimization level to a minimum of 2; see -O. The option is one of the following:
    • c:m โ€” tells the compiler to completely unroll loops with a constant loop count less than or equal to m, a supplied constant. If this value isn't supplied, the m count is set to 1. If m is set to 1, a compiler heuristic determines the maximum loop count at which such loops will be completely unrolled.
    • n:u โ€” tells the compiler to unroll u times a single-block loop which is not completely unrolled, or has a non-constant loop count. If u isn't supplied, the unroller computes the number of times a candidate loop is unrolled.
    • m:u โ€” tells the compiler to unroll u times a multi-block loop which is not completely unrolled, or has a non-constant loop count. If u isn't supplied, the unroller computes the number of times a candidate loop is unrolled.

And -Mnounroll tells the compiler not to unroll loops. Periodt. ๐Ÿ’…

  • -Munsafe_par_align, -Mnounsafe_par_align โ€” use (or don't use) aligned moves for array loads in parallelized loops, as long as the first element of the array is aligned. This is only effective with -Mvect=simd. And why is it "unsafe"? Because there are situations where the array elements allocated to some processors are not aligned. ๐Ÿ˜ฌ
  • -Mvect [=option[,option,...]], -Mnovect (default) โ€” pass options to the internal vectorizer. This also sets the optimization level to a minimum of 2, the equivalent of -O; for more info see optimization levels under -O. If no option list is specified, then these vector optimizations are used: assoc,cachesize:c,simd:256, where c is the actual cache size of the machine. The -Mvect options are:
    • altcode (default) / noaltcode โ€” enable (or disable) alternate code generation for vector loops, depending on things like array alignments and loop counts.
    • fuse / nofuse (default) โ€” enable (or disable) loop fusion, which combines adjacent loops into a single loop. Two loops into one, it's giving efficiency ๐Ÿฆ‹
    • prefetch โ€” use prefetch instructions in loops where profitable.
  • simd[:{128|256|512}] (default) / nosimd โ€” use vector SIMD instructions (AVX, AVX2, AVX512). The argument can limit you to 128-bit SIMD instructions. Specifying 512-bit SIMD instructions is only possible for target processors that support AVX512. slay, but know your hardware ๐Ÿ’…
  • uniform / nouniform (default) โ€” perform the same optimizations in the vectorized and residual loops. This may affect the performance of the residual loop. lowkey a tradeoff vibe ๐Ÿ‘€

These options are also supported, but not recommended for use in new development, except by experienced users, and may be phased out in future releases:

  • assoc (default) / noassoc โ€” enable (disable) certain associativity conversions that can change the results of a computation due to floating-point roundoff error differences. A typical optimization is to change the order of additions, which is mathematically correct, but can be computationally different, due to roundoff error. math girlies know this one gets spicy ๐ŸŒถ๏ธ
  • cachesize:number (default=automatic) โ€” tells the vectorizer, when performing cache tiling optimizations, to assume a cache size of number. manifesting a bigger cache for u โœจ
  • gather (default) / nogather โ€” enable (disable) vectorization of loops with indirect array references.
  • idiom (default) / noidiom โ€” enable idiom recognition; alternate form of -Midiom.
  • levels:n โ€” set maximum nest level of loops to optimize.
  • partial โ€” enable partial loop vectorization via innermost loop distribution.
  • short / noshort (default) โ€” enable (disable) recognition of short vector operations that arise from scalar code outside of loops or within the body of loops.
  • sizelimit[:number] / nosizelimit (default) โ€” limit the size of loops that are vectorized; the default is to attempt to vectorize all loops. all loops? iconic. maybe chaotic. both ๐Ÿ’–
  • tile / notile (default) โ€” enable (disable) loop tiling to optimize for cache locality.

-Mnovect disables the vectorizer, and is the default at -O0 and -O1.

  • -Mzerotrip (default) / -Mnozerotrip โ€” include (don't include) a zero-trip test for loops. Use -Mnozerotrip only when all loops are known to execute at least once. fr fr only if you're sure ๐Ÿ˜ญ
  • -mp[=option] โ€” enable OpenMP pragmas and directives to explicitly parallelize regions of code for execution by accelerator devices or multi-processor system. The options allowed are:
    • gpu โ€” compile OpenMP directives for parallel execution on the GPU. GPU main character energy ๐Ÿ‘‘
    • multicore (default) โ€” compile OpenMP directives for parallel execution on the CPU.
    • align / noalign (default) โ€” modify (don't modify) default loop iteration scheduling to align iterations with array references. The default is to use simple static scheduling.
    • autopar (default) / noautopar โ€” enable loop autoparallelization of omp loop constructs.
    • ompt โ€” link against OMPT-enabled OpenMP library.
  • -nomp โ€” ignore OpenMP directives and do not link against OpenMP runtime libraries. no OpenMP, no problem bestie ๐Ÿซถ
  • -O[level] โ€” set the optimization level. If -O is not specified, then the default level is 1 if -g is not specified, and 0 if -g is specified. If a number is not supplied with -O then the optimization level is set to 2. The optimization levels and their meanings are as follows:
    • -O0 โ€” sets the optimization level to 0. A basic block is generated for each statement. No scheduling is done between statements. No global optimizations are performed.
    • -O1 โ€” sets the optimization level to 1. Scheduling within extended basic blocks is performed. No global optimizations are performed.
    • -O โ€” sets the optimization level to 2, with no SIMD vectorization enabled. All level 1 optimizations are performed. In addition, traditional scalar optimizations such as induction recognition and loop invariant motion are performed by the global optimizer.
    • -O2 โ€” all -O optimizations are performed. In addition, more advanced optimizations such as SIMD code generation, cache alignment and partial redundancy elimination are enabled.
    • -O3 โ€” all -O1 and -O2 optimizations are performed. In addition, this level enables more aggressive code hoisting and scalar replacement optimizations that may or may not be profitable.
    • -Ofast โ€” enables -O3, -Mfprelaxed, -Mstack_arrays, -Mno-nan, Mno-inf, and -fcx-limited-range. Note -Mstack_array is disabled when both command line options -Ofast and -stdpar are enabled. fast mode says go go go ๐Ÿ”ฅ
    • -O4 โ€” all -O1, -O2, and -O3 optimizations are performed. In addition, hoisting of guarded invariant floating-point expressions is enabled.
  • -pg โ€” enable gprof-style sample-based profiling; implies -Mframe.

๐Ÿž Debugging Options ๐Ÿž

  • -C โ€” add array bounds checking; the same as -Mbounds. safety era ๐Ÿ›ก๏ธ
  • -g โ€” generate symbolic debug information. This also sets the optimization level to zero, unless a -O switch is present on the command line. Symbolic debugging may give confusing results if an optimization level other than zero is selected. Using -O0 the generated code will be slower than code generated at other optimization levels. debug mode: slower but honest ๐Ÿ˜ญ
  • -gopt โ€” generate symbolic debug information, without affecting optimizations. This may give confusing results when debugging with optimizations; it is intended for use with other tools that use the debug information.
  • -Mbounds / -Mnobounds (default) โ€” add (don't add) array bound checking.
  • -Mchkptr โ€” check for unintended de-referencing of NULL pointers. NULL pointer jump scare warning ๐Ÿ™ˆ
  • -Mchkstk โ€” check the stack for available space upon entry to and before the start of a parallel region. Useful when many private variables are declared.
  • -Mcoff โ€” generate a COFF formatted object.
  • -Mdwarf2 โ€” generate DWARF2 debug information with -g.
  • -Mdwarf3 โ€” generate DWARF3 debug information with -g.
  • -Melf โ€” generate an ELF formatted object.
  • -Mnodwarf โ€” don't add the default dwarf information.
  • -traceback (default) / -notraceback โ€” add debug information for runtime traceback.

๐Ÿงช Preprocessor Options ๐Ÿงช

  • -Dname[=def] โ€” define name to be def in the preprocessor. If def is missing, it is assumed to be empty. If the = sign is missing, then name is defined to be the string 1.
  • -E โ€” preprocess each .c file and send the result to standard output. No compilation, assembly, or linking is performed. just preprocess and dip โœจ
  • -F โ€” stop after preprocessing.
  • -Idirectory โ€” add directory to the compiler's search path for include files. For include files surrounded by < >, each -I directory is searched followed by the standard area. For include files surrounded by " ", the directory containing the file containing the #include directive is searched, followed by the -I directories, followed by the standard area.
  • -isystem directory โ€” same as -I, but mark the directory as a system directory.
  • -Mcpp=[[no]comment|m|md|mm|mmd|mq:target|mt:target|suffix:suff] โ€” only runs the preprocessor on the input file(s); by default, the output is written to file.i, unless renamed with the -o switch. The options are:
    • comment / nocomment โ€” keep (don't keep) C-style comments in the preprocessed output.
    • include:file โ€” include this file before processing the source file.
    • m โ€” print makefile dependencies to stdout, a la -M.
    • md โ€” print makefile dependencies to file.d, a la -MD.
    • mm โ€” print makefile dependencies to stdout, ignoring system includes (includes with angle braces), a la -MM.
    • mmd โ€” print makefile dependencies to file.d, ignoring system includes (includes with angle braces), a la -MMD.
    • mq:'target' โ€” print makefile dependencies to stdout, a la -MQ.
    • mt:target โ€” print makefile dependencies to stdout, a la -MT.
    • line โ€” include line numbers into the preprocessed output.
    • suffix:suff โ€” when generating makefile dependencies, name the dependent file file.suff; the default is to name the dependent file file.o.
  • -Mnostddef โ€” do not predefine any macros to the preprocessor. blank slate vibe ๐Ÿซง
  • -Mnostdinc โ€” do not search in the standard location for include files when those files are not found elsewhere.
  • -Mpreprocess โ€” run the preprocessor on Fortran or assembler source files. By default, the preprocessor is run when the source's suffix is .fpp, .F, .F90, .F95, or .HPF.
  • -Uname โ€” remove the definition of the name macro in the preprocessor.
  • -YI,directory โ€” change the standard include directory to directory.
  • -Yp,directory โ€” look in directory for the preprocessor executable.

๐Ÿ› ๏ธ Assembler Options ๐Ÿ› ๏ธ

  • -Wa,option[,option...] โ€” pass each comma-delimited option to the assembler.
  • -Ya,directory โ€” look in directory for the assembler executable.

๐Ÿ”— Linker Options ๐Ÿ”—

okay bestie, welcome to the link era โ€” the part where all your cute little object files hold hands and become an executable or a shared object. These flags get passed through to the linker, or they tell the driver what to hand it. every single one matters ๐Ÿ’…

  • -acclibs โ€” link-time option to add the accelerator libraries to the link line. โœจ
  • --as-needed, --no-as-needed โ€” passed to the linker. --as-needed tells it to only set the DT_NEEDED flag for subsequent shared libraries โ€” which means requiring those libraries at run time โ€” if theyโ€™re used to satisfy references. --no-as-needed restores the default behavior. ๐Ÿซถ
  • -Bdynamic โ€” passed to the linker to specify dynamic binding.
  • -Bstatic โ€” this is the same as -static; peep -static for the details. ๐Ÿ’–
  • -Bstatic-nvidia โ€” this is the same as -static-nvidia; peep -static-nvidia for the details.
  • -c++libs โ€” link-time option to add the C++ runtime libraries, so mixed-language programming can do its thing. ๐ŸŽ€
  • -cudaforlibs โ€” link-time option to add the CUDA Fortran runtime libraries, allowing mixed-language programming. It implies -fortranlibs. ๐Ÿฆ‹
  • -cudalib[=libname[,libname...]] โ€” add CUDA-optimized libraries to the link line. When no option is specified, the compiler will link all necessary CUDA-optimized libraries. -cudalib will use the version of the library appropriate to the CUDA version being used. The libraries it recognizes are:
    • cublas
    • cublasmp
    • cufft
    • cufftmp
    • cufftw
    • curand
    • cusolver
    • cusolvermp
    • cusparse
    • cutensor
    • nccl
    • nvblas
    • nvlamath
    • nvshmem
    • nvtx3
  • -cudalibs โ€” this option has been deprecated, please refer to -cudalib. Link-time option to add the CUDA runtime API library. ๐Ÿ™ˆ
  • -fortranlibs โ€” link-time option to add the Fortran runtime libraries, allowing mixed-language programming.
  • -g77libs โ€” link-time option which allows object files generated by GNU g77 (or gcc) to be linked into nvfortran main programs. ๐ŸŒธ
  • -Ldirectory โ€” passed to the linker; add directory to the list of directories in which the linker searches for libraries.
  • -llibrary โ€” passed to the linker; load the library liblibrary.a from the standard library directory. See also the -L option. โญ
  • -m โ€” cause the linker to display a link map. ๐Ÿ—บ๏ธ
  • -Mcudalib[=libname[,libname...]] โ€” this option has been deprecated, please refer to -cudalib. Add CUDA-optimized libraries to the link line. When no option is specified, the compiler will link all necessary CUDA-optimized libraries.
  • -Meh_frame, -Mnoeh_frame โ€” add (donโ€™t add) arguments to the link line to preserve the stack frame information for zero-cost exception handling frames. The default is -Mnoeh_frame unless changed in a site or user rcfile. ๐Ÿ”ฅ
  • -Mnostartup โ€” do not link in the usual startup routine. This routine contains the entry point for the program.
  • -Mnostdlib โ€” do not link in the standard libraries when linking a program.
  • -Mrpath (default), -Mnorpath โ€” the default is to add -rpath to the link line, giving the directories containing the required runtime shared objects. Use -Mnorpath to instruct the driver not to add any -rpath switches to the link line. ๐Ÿ‘‘
  • -Mmkl โ€” add Intelโ€™s Math Kernel libraries to the link line. Requires that the environment variable MKLROOT be set to the path to the local MKL installation (the part of the path that precedes lib/<arch>). ๐ŸŒˆ
  • -nvmalloc โ€” use a custom host memory allocator.
  • -pthread โ€” adds support for multithreading with the pthreads library. This option sets flags for both the preprocessor and linker. ๐Ÿงต
  • -Rdirectory โ€” passed to the linker; instructs the linker to hard-code the pathname directory into the search path for generated shared object files. Note that there cannot be a space between R and directory. ๐Ÿ’€
  • -r โ€” passed to the linker; generate a re-linkable object file.
  • -rpath directory โ€” passed to the linker to add the directory to the runtime shared library search path.
  • -s โ€” passed to the linker; strip symbol table information. โœ‚๏ธ
  • -shared โ€” passed to the linker. Instructs the linker to generate a shared object file (dynamically linked library). Implies -fpic. ๐Ÿซถ
  • -soname name โ€” passed to the linker. When creating a shared object, instructs the linker to set the internal DT_SONAME field to the specified name.
  • -static โ€” passed to the linker to specify static binding.
  • -static-nvidia โ€” statically link in the NVIDIA runtime libraries, while using dynamic linking for the system libraries; implies -Mnorpath. ๐ŸŒŸ
  • -uname โ€” passed to the linker; generate undefined reference.
  • --whole-archive, --no-whole-archive โ€” passed to the linker. Instructs the linker to include all objects in subsequent archive files. --no-whole-archive restores the default behavior. ๐Ÿ“ฆ
  • -Wl,option[,option]..., -Xlinker option[,option]... โ€” pass each comma-delimited option to the linker.
  • -YC,directory โ€” look in directory for the standard compiler library files.
  • -Yl,directory โ€” look in directory for the linker.
  • -YL,directory โ€” change the standard library directory to directory.
  • -YS,directory โ€” look in directory for the standard system startup object files.
  • -YU,directory โ€” passed to the linker; change library search path. ๐Ÿฆ‹

โœจ Language Options โœจ

okay bestie, this batch is literally the โ€œwhat kind of file is this and how should Fortran actโ€ squad ๐Ÿ’… keep these facts exact, because the compiler is not here for guesswork โœจ

  • -asmsuffix=suffix โ€” says a file with the given suffix is an assembly language file ๐Ÿ› ๏ธ
  • -byteswapio โ€” swaps bytes from big-endian to little-endian or vice versa on input/output of unformatted Fortran data. Using this option enables reading/writing Fortran unformatted data files compatible with those produced on Sun or SGI systems ๐Ÿ”„
  • -csuffix=suffix โ€” says a file with the given suffix is a C source file ๐Ÿ’ป
  • -fsuffix=suffix โ€” says a file with the given suffix is a Fortran source file ๐Ÿงก
  • -FSUFFIX=suffix โ€” says a file with the given suffix is a Fortran source file ๐Ÿงก
  • -cuda[=option[,option...] โ€” enables CUDA Fortran; adds CUDA include paths, and links with the CUDA runtime libraries. -cuda is required on the link line. If -cuda is used in compilation, it must also be used for linking. For target specific options, please refer to -gpu. For linking additional CUDA libraries (e.g. math libraries), please refer to -cudalib. Use these sub-options to tailor compilation of CUDA Fortran accelerator regions:
    • charstring โ€” enable limited support for character strings in GPU kernels ๐Ÿงต
    • madconst โ€” put Module Array Descriptors in CUDA Constant Memory ๐Ÿ’พ
  • -i2 โ€” treats INTEGER variables as two bytes ๐Ÿ“
  • -i4 โ€” treats INTEGER variables as four bytes ๐Ÿ“
  • -i8 โ€” treats default INTEGER and LOGICAL variables as eight bytes. For operations involving integers, use 64-bits for computations ๐Ÿ”ข
  • -i8storage โ€” allocates 8 bytes for INTEGER and LOGICAL ๐Ÿ—ƒ๏ธ
  • -Mallocatable[=95|03] โ€” selects whether to use Fortran 1995 or Fortran 2003 semantics for assignments to allocatable objects and allocatable components of derived types. Fortran 1995 semantics require the user to allocate the object or component and that an array object or component be conformant before the assignment. Fortran 2003 semantics require the compiler to add code to check whether the object or component is allocated and whether an array object is conformant before the assignment, and to allocate or reallocate if not ๐Ÿง 
  • -Mbackslash, -Mnobackslash (default) โ€” treat / donโ€™t treat backslash as a normal (non-escape) character in strings. -Mnobackslash causes the standard C backslash escape sequences to be recognized in quoted strings; -Mbackslash causes the backslash to be treated like any other character ๐Ÿช„
  • -Mbyteswapio โ€” swaps bytes from big-endian to little-endian or vice versa on input/output of unformatted Fortran data. Using this option enables reading/writing Fortran unformatted data files compatible with those produced on Sun or SGI systems ๐Ÿ”„
  • -Mcray=pointer โ€” forces Cray Fortran (CF77) compatibility with respect to the listed options. Possible options include:
    • pointer โ€” for purposes of optimization, assume that pointer-based variables do not overlap the storage of any other variable ๐Ÿงท
  • -Mcuda[=option[,option...] โ€” this option has been deprecated, please refer to -cuda. Enables CUDA (and CUDA Fortran), and links with the CUDA libraries. -Mcuda is required on the link line if there are no CUDA Fortran source files specified on the command line. If -Mcuda is used in compilation, it must also be used for linking ๐Ÿšจ
  • -Mdalign (default), -Mnodalign โ€” align / donโ€™t align doubles in structures on 8-byte boundaries. -Mnodalign may lead to data alignment exceptions โš ๏ธ
  • -Mdclchk, -Mnodclchk (default) โ€” require / donโ€™t require that all variables be declared ๐Ÿ“
  • -Mdefaultunit, -Mnodefaultunit (default) โ€” treat / donโ€™t treat '*' as stdout/stdin regardless of the status of units 6/5. -Mnodefaultunit causes * to be a synonym for 5 on input and 6 on output; -Mdefaultunit causes * to be a synonym for stdin on input and stdout on output ๐ŸŽ›๏ธ
  • -Mdlines, -Mnodlines (default) โ€” treat / donโ€™t treat lines beginning with D in column 1 as executable statements, ignoring the D ๐Ÿ“œ
  • -Mdollar=char โ€” sets the character used to replace dollar signs in names to char. Default is an underscore (_) ๐Ÿ’ฒ
  • -Mextend โ€” allows 132-column source lines ๐Ÿ“
  • -Mfixed โ€” processes Fortran source using fixed form specifications. The -Mfree options specify free form formatting. By default files with a .f or .F extension use fixed form formatting ๐Ÿงฑ
  • -Mfree, -Mfreeform, -Mnofree, -Mnofreeform โ€” process Fortran source using free form specifications. The -Mnofree and -Mfixed options specify fixed form formatting. By default files with a .f90, .F90, .f95 or .F95 extension use freeform formatting ๐Ÿ•Š๏ธ
  • -Mi4 (default), -Mnoi4 โ€” treat / donโ€™t treat INTEGER as INTEGER*4. -Mnoi4 treats INTEGER as INTEGER*2 ๐Ÿงฎ
  • -Miomutex, -Mnoiomutex (default) โ€” generate / donโ€™t generate critical section calls around Fortran I/O statements ๐Ÿ”
  • -Mlibsuffix=suffix โ€” says a file with the given suffix is an object library file ๐Ÿ“š
  • -Mllalign (default), -Mnollalign โ€” align / donโ€™t align long longs or INTEGER*8 in structures or common blocks on 8-byte boundaries. -Mllalign is the default ๐Ÿ“
  • -Mnomain โ€” when the link step is called, donโ€™t include the object file which calls the Fortran main program. Useful for using the nvfortran driver to link programs with the main program written in C or C++ and one or more subroutines written in Fortran ๐Ÿ”—
  • -Mobjsuffix=suffix โ€” says a file with the given suffix is a binary object file ๐Ÿงฑ
  • -Monetrip, -Mnoonetrip (default) โ€” force / donโ€™t force each DO loop to be iterated at least once ๐Ÿ”
  • -Mr8, -Mnor8 (default) โ€” treat / donโ€™t treat REAL as DOUBLE PRECISION and real constants as double precision constants ๐ŸŽฏ
  • -Mr8intrinsics [=float], -Mnor8intrinsics (default) โ€” treat / donโ€™t treat the intrinsics CMPLX as DCMPLX and REAL as DBLE.
    • float โ€” also treat the FLOAT intrinsic as DBLE ๐ŸŒŠ
  • -Mrecursive, -Mnorecursive (default) โ€” allocate / donโ€™t allocate local variables on the stack, thus allowing recursion. SAVEd, data-initialized, or namelist members are always allocated statically, regardless of the setting of this switch ๐Ÿชœ
  • -Mref_externals, -Mnoref_externals (default) โ€” force / donโ€™t force references to names appearing in EXTERNAL statements ๐Ÿ”
  • -Msave, -Mnosave (default) โ€” assume / donโ€™t assume that all local variables are subject to the SAVE statement. -Msave may allow many older Fortran programs to run but can greatly reduce performance ๐Ÿข
  • -Msignextend (default), -Mnosignextend โ€” sign extend / donโ€™t sign extend when a narrowing conversion overflows. For example, when -Msignextend is in effect and an integer containing the value 65535 is converted to a short, the value of the short will be -1. ANSI C specifies that the result of such conversions are undefined ๐ŸŒ€
  • -Mstack_arrays, -Mnostack_arrays (default) โ€” allocate automatic arrays on the stack (on the heap) ๐Ÿฅž
  • -Mstandard โ€” flag non-ANSI-Fortran usage ๐Ÿšฉ
  • -Msyntax-only โ€” perform only syntax checking, semantic checking, and Fortran module (.mod) file generation ๐Ÿงช
  • -Munixlogical, -Mnounixlogical (default) โ€” when -Munixlogical is in effect, a logical is considered to be .TRUE. if its value is non-zero and .FALSE. otherwise. When -Mnounixlogical is in effect (the default), a logical is considered to be .TRUE. if its value is odd and .FALSE. if its value is even ๐Ÿ”˜
  • -Mupcase, -Mnoupcase (default) โ€” preserve / donโ€™t preserve case in names. -Mnoupcase causes all names to be converted to lower case. Note that, if -Mupcase is used, then variable name 'X' is different than variable name 'x', and keywords must be in lower case ๐Ÿ” 
  • -module directory โ€” save/search for module files in directory ๐Ÿ“
  • -Munlink_module โ€” instructs nvfortran to unlink a symlink to desired module file before writing out the module file. Without this option, nvfortran will follow the symlink and write the module file to the symlinkโ€™s target, provided it has permission to write there ๐Ÿ”—
  • -r4 โ€” interpret DOUBLE PRECISION variables as REAL ๐ŸŽˆ
  • -r8 โ€” interpret REAL variables as DOUBLE PRECISION. Equivalent to using the options -Mr8 and -Mr8intrinsics ๐ŸŽฏ
  • -Wh,option[,option...] โ€” pass each comma-delimited option to the Fortran 90/95 front end ๐Ÿšš

๐ŸŽฏ Target-specific Options ๐ŸŽฏ

  • -acc โ€” enable OpenACC pragmas and directives to explicitly parallelize regions of code for execution by accelerator devices. See the -gpu flag to select options specific to NVIDIA GPUs. The options are:
    • autopar (default), noautopar โ€” enable loop autoparallelization within parallel constructs ๐Ÿ”„
    • gpu (default) โ€” compile OpenACC directives for parallel execution on the GPU ๐Ÿš€
    • host โ€” compile OpenACC directives for serial execution on the host CPU ๐Ÿ–ฅ๏ธ
    • legacy โ€” suppress warnings about deprecated PGI accelerator directives ๐Ÿ•ฐ๏ธ
    • multicore โ€” compile OpenACC directives for parallel execution on the host CPU ๐Ÿงต
    • routineseq, noroutineseq (default) โ€” compile every routine for the device, as if it had a routine seq directive ๐Ÿ“ฆ
    • strict โ€” issue warnings when accelerator directives are encountered which do not adhere to the OpenACC standard ๐Ÿšจ
    • sync โ€” ignore async clauses, and run every data transfer and kernel launch on the default sync queue โณ
    • verystrict โ€” abort compilation with a fatal error when an accelerator directive is encountered which does not adhere to the OpenACC standard ๐Ÿ’€
    • wait (default), nowait โ€” wait for each compute kernel to finish ๐Ÿ›‘
  • -noacc โ€” disable OpenACC directives and do not link with OpenACC libraries ๐Ÿšซ
  • -gpu=option โ€” use the following sub-options to tailor the compilation of target accelerator regions:
  • autocompare โ€” auto-compares CPU vs GPU results ๐Ÿซถ. The accelerated code sections run in redundant mode, and data gets compared any time it would ordinarily get moved off the accelerator.
  • ccXY โ€” generates code for a device with compute capability XY. You can list multiple compute capabilities and it makes one version for each. Default move: the compiler sniffs out the compute capability of every installed GPU all by itself โœจ. Peep the valid compute capabilities for your install with -help -gpu.
  • ccall โ€” generates code for all compute capabilities supported for this target and by the CUDA Toolkit version you picked. Go big or go home ๐Ÿ’….
  • ccnative โ€” detects the visible GPUs on the system and generates code for them. If no device is available, the default compute capability gets used (cc50).
  • ccall-major โ€” compiles for all major supported compute capabilities. Heads up though: it does not include PTX for the highest major virtual architecture โ€” for that support, see the -gpu=[no]rdc option ๐Ÿ‘€.
  • cudaX.Y โ€” uses CUDA X.Y Toolkit compatibility, where installed.
  • deepcopy โ€” enables Full Deepcopy support in OpenACC Fortran.
  • fastmath โ€” turns on the fast math library, which includes faster-but-lower-precision implementations of certain math and intrinsic functions. Speed demon era ๐Ÿ”ฅ.
  • flushz, noflushz (default) โ€” enables (disables) flush-to-zero mode on the GPU.
  • fma, nofma โ€” generates (does not generate) fused multiply-add operations on the GPU. It's on by default at optimization level -O1.
  • implicitsections, noimplicitsections (default) โ€” changes (does not change) array element references in OpenACC and OpenMP data clauses into array section references.
  • interceptdeallocations, nointerceptdeallocations โ€” intercepts (does not intercept) LIBC function calls (e.g. free) and calls the matching CUDA memory deallocation version if the address is in pinned or managed memory, and the regular version otherwise.
  • keepbin โ€” keeps the generated CUDA binary, with a .cubin suffix.
  • keepgpu โ€” keeps the generated CUDA GPU source files, with a .gpu suffix.
  • keepltoir โ€” keeps the generated GPU LTOIR files, with a .ltoir suffix. Only works when -gpu=lto is enabled, iykyk.
  • keepptx โ€” keeps the generated portable assembly files, with a .ptx suffix.
  • lineinfo, nolineinfo (default) โ€” generates debugging line information.
  • loadcache:[L1|L2] โ€” generates code to cache global memory loads in the L1 or L2 hardware cache โญ.
  • lto โ€” enables Device Link Time Optimization (Device LTO).
  • maxregcount:n โ€” sets the maximum number of registers to use in the generated GPU code.
  • managed โ€” allocates any dynamically allocated data in CUDA Managed memory. This option must appear in both the compile and link lines. And nope, it may not be used with -gpu=pinned ๐Ÿ™ˆ.
    • intercept โ€” intercepts LIBC function calls (e.g. free) and calls their managed memory version if the address is in managed memory, and the regular version otherwise.
  • nomanaged โ€” does not allocate any dynamically allocated data in CUDA Managed memory. Use it with -stdpar to stop that flag's implicit use of -gpu=managed when CUDA Managed memory capability is detected.
  • nounified โ€” does not compile for CUDA Unified memory capability. Use it with -stdpar to stop that flag's implicit use of -gpu=unified when CUDA Unified memory capability is detected.
  • pinned โ€” allocates any dynamically allocated data in CUDA Pinned host memory. This option must appear in both the compile and link lines, and it may not be used with -gpu=managed|unified ๐Ÿ’€.
    • intercept โ€” intercepts LIBC function calls (e.g. free) and calls their pinned memory version if the address is in pinned memory, and the regular version otherwise.
  • mem:[mode] โ€” picks the GPU memory mode from one of the options below: separate, managed, unified. This one cannot be combined with -gpu=pinned, gpu=managed or -gpu=unified ๐Ÿšซ.
    • mem:separate โ€” all data lives in separate CPU and GPU memories. Explicit memory copies happen when data are accessed from both CPU and GPU.
    • mem:managed โ€” allocates any dynamically allocated data in CUDA Managed Memory. Data that aren't dynamically allocated live in separate GPU memory and get copied explicitly between CPU and GPU memories. This option must appear in both the compile and link lines.
    • mem:unified โ€” compiles for full CUDA Unified Memory capability, where system memory is accessible from the GPU. Every variable in the CPU code is accessible from the GPU without explicit directives or attributes. This mode uses system and managed memory for dynamically allocated data unless explicit behavior is set through the -gpu=mem:unified:[no]managedalloc subflags. This option must appear in both the compile and link lines.
  • mem:unified:managedalloc, mem:unified:nomanagedalloc โ€” allocates (does not allocate) any dynamically allocated data in CUDA Managed Memory.
  • mem:separate:pinnedalloc, mem:separate:nopinnedalloc โ€” allocates (does not allocate) any dynamically allocated data in CUDA Pinned host memory.
  • ptxinfo โ€” prints ptxas information.
  • rdc (default), nordc โ€” generates (does not generate) relocatable device code for separate compilation, and invokes the device linker before the host linker at the link step.
  • redundant โ€” runs accelerated code redundantly on the CPU. Implied by autocompare.
  • safecache โ€” allows variable-sized array sections in cache directives; the compiler just assumes they fit into CUDA shared memory ๐Ÿงš.
  • sm_XY โ€” generates code for a device with compute capability XY. Multiple compute capabilities can be specified and one version gets generated for each. By default the compiler detects the compute capability for every installed GPU. Use -help -gpu to see the valid compute capabilities for your installation.
  • stacklimit:limit (default), nostacklimit โ€” okay so this option has been deprecated and is getting removed in a future release, no cap ๐Ÿ˜ญ. It gives an error if the total stack size of a kernel or procedure exceeds limit KBytes. The default is stacklimit:512.
  • tripcount:host โ€” calculates loop trip counts on the host for some compute constructs. This is the default behavior when -gpu=tripcount isn't specified. Lowkey important: this behavior is not compliant with the OpenACC specification. Want compliance? Use -gpu=tripcount:device.
  • tripcount:device โ€” calculates loop trip counts on the device for some compute constructs. This one is compliant with the OpenACC specification, even though it's not the default. To explicitly turn the default back on, use -gpu=tripcount:host.
  • tripcount:warn, tripcount:nowarn โ€” enables (disables) compile-time warnings when loop trip counts are calculated on the host instead of on the device.
  • tripcount:check, tripcount:nocheck โ€” inserts (does not insert) runtime checks to make sure the trip count value calculated on the device matches the one calculated on the host. Want the differences reported? Set the environment variable NVCOMPILER_ACC_CHECK_TRIPCOUNT.
  • unified โ€” compiles for CUDA Unified memory capability, where system memory is accessible from the GPU. All variables in the CPU code are accessible from the GPU without explicit directives or attributes. This mode uses system and managed memory for dynamically allocated data unless explicit behavior is set through -gpu=[no]managed. This option must appear in both the compile and link lines, and it may not be used with -gpu=pinned ๐Ÿ™…โ€โ™€๏ธ.
    • intercept โ€” intercepts LIBC function calls (e.g. free) and calls their unified version if the address is in unified memory, and the regular version otherwise.
  • unroll, nounroll โ€” automatically (does not) unroll inner loops. On by default at optimization level -O3 โœจ.

  • -Kieee, -Knoieee (default) โ€” performs floating-point operations in strict conformance with the IEEE 754 standard ๐ŸŽ€. Some optimizations get disabled with -Kieee, and a more accurate math library is used. The default, -Knoieee, uses faster but very slightly less accurate methods.
  • -Ktrap=option[,option]... โ€” controls what the processor does when floating-point exceptions happen while your program is running. Possible options include:
    • denorm โ€” traps on denormalized operands.
    • divz โ€” traps on divide by zero.
    • fp โ€” traps on floating-point exceptions.
    • inexact โ€” traps on inexact result.
    • inv โ€” traps on invalid operation.
    • none (default) โ€” disables all traps. Note that -Ktrap=inv,none,ovf implies -Ktrap=ovf ๐Ÿ‘€.
    • ovf โ€” traps on floating-point overflow.
    • unf โ€” traps on floating-point underflow. Ngl, -Ktrap is only meaningful when you're compiling a C/C++ main function or a Fortran main program.
-Ktrap=fp is shorthand for -Ktrap=divz,inv,ovf ๐Ÿ’…

okay so these options are literally all about the processor's floating-point exception mask bits, and they're giving "handle with care" energy. Normally the processor's exception mask bits are enabled, meaning floating-point exceptions are masked โ€” the processor recovers from the exception and just keeps going. But if a mask bit is off (unmasked) and the corresponding exception happens? ๐Ÿ’€ Execution terminates with a floating-point exception (Linux FPE signal). No cap.

  • -march=target โ€” this is the same as -tp, bestie. Peep -tp for the details.
  • -m[no-]daz-ftz โ€” specifies how denormals are handled by the processor at runtime. -mno-daz-ftz means denormal operands and results are honored โ€” shorthand for -Mnodaz -Mnoflushz. -mdaz-ftz is the default setting and means denormal operands and results are treated as zero โ€” shorthand for -Mdaz -Mflushz.
  • -Mdaz, -Mnodaz โ€” enable [disable] mode to treat denormal (subnormal) floating-point operands as zero. -Mdaz is the default setting for x86_64 and aarch64 processors.
  • -Mflushz, -Mnoflushz โ€” enable [disable] setting floating-point denormal (subnormal) results to zero. -Mflushz is the default setting for x86_64 and aarch64 processors.
  • -Mfpmisalign, -Mnofpmisalign โ€” allow (don't allow) vector arithmetic instructions with memory operands that are not aligned on 16-byte boundaries.
  • -Mfprelaxed [=option[,option,...]], -Mnofprelaxed (default) โ€” perform (don't perform) certain floating-point operations using relaxed precision when it improves speed. The options are:
    • div โ€” perform divide using relaxed precision.
    • intrinsic โ€” perform certain intrinsic functions using relaxed precision.
    • order, noorder โ€” allow (don't allow) expression reordering, including factoring such as computing a*b+a*c as a*(b+c).
    • recip โ€” perform reciprocal operations using relaxed precision.
    • rsqrt โ€” perform reciprocal square root (1/sqrt) using relaxed precision.
    • sqrt โ€” perform square root using relaxed precision.

With no options, -Mfprelaxed will choose to generate relaxed precision code for those operations that generate a significant performance improvement, depending on the target processor.

  • -Mfunc32 (default), -Mnofunc32 โ€” align (don't align) functions on 32 byte boundaries.
  • -Mlongbranch, -Mnolongbranch (default) โ€” enable (disable) long branches.
  • -Msecond_underscore, -Mnosecond_underscore (default) โ€” add (don't add) a second underscore to the name of a Fortran global if its name already contains an underscore. This option is useful for maintaining compatibility with g77, which adds a second underscore to such symbols by default.
  • -Mvarargs, -Mnovarargs (default) โ€” generate code for calls made from Fortran to C routines to use varargs calling sequence.
  • -Mwritable-strings โ€” store string constants in the writable data segment.
  • -mcmodel=small|medium โ€” pick your memory model vibe:
    • small โ€” limits the combined area for a user's object or executable to 4GB. The maximum code size is 2GB.
    • medium โ€” allows unrestricted data size. The maximum code size is 2GB.
  • -stdpar=option โ€” enable (ISO Fortran 2018) DO-CONCURRENT. Options are:
    • gpu โ€” (ISO Fortran 2018) DO-CONCURRENT is compiled for parallel execution on the GPU. This option implies -gpu=unified on targets with Unified memory capability and -gpu=managed otherwise.
    • multicore โ€” (ISO Fortran 2018) DO-CONCURRENT is compiled for parallel execution on the CPU.
  • -nostdpar โ€” execute (ISO Fortran 2018) DO-CONCURRENT sequentially.
  • -ta=target โ€” this option has been deprecated, please refer to -acc.
    • -ta=tesla โ€” this option has been deprecated, please refer to -acc=gpu and -gpu.
    • -ta=multicore โ€” this option has been deprecated, please refer to -acc=multicore.
    • -ta=host โ€” this option has been deprecated, please refer to -acc=host.
  • -target=option โ€” select the target for all parallel programming paradigms used (OpenACC, OpenMP, Standard Languages). Possibilities are:
    • gpu โ€” globally set the target device to an NVIDIA GPU.
    • multicore โ€” globally set the target device to the host CPU.
  • -tp=target โ€” specify the type of the target processor. Issue:
nvfortran -help -tp

to display the list of recognized target processors.


๐ŸŒธ FILES ๐ŸŒธ

  • a.out โ€” executable output file
  • file.a โ€” library of object files
  • file.f โ€” fixed-format Fortran source file
  • file.F โ€” fixed-format Fortran source file that requires preprocessing
  • file.f90 โ€” free-format Fortran source file
  • file.F90 โ€” free-format Fortran source file that requires preprocessing
  • file.f95 โ€” free-format Fortran source file
  • file.F95 โ€” free-format Fortran source file that requires preprocessing
  • file.f03 โ€” free-format Fortran source file
  • file.F03 โ€” free-format Fortran source file that requires preprocessing
  • file.for โ€” fixed-format Fortran source file
  • file.fpp โ€” fixed-format Fortran source file that requires preprocessing
  • file.cuf โ€” free-format CUDA Fortran source file
  • file.CUF โ€” free-format CUDA Fortran source file that requires preprocessing
  • file.ipa โ€” InterProcedural Analyzer (IPA) file
  • file.ipo โ€” InterProcedural Analyzer (IPA) file
  • file.o โ€” object file
  • file.s โ€” assembler source file
  • .mynvfortranrc โ€” you may add custom switches or make other additions to nvfortran by creating a file named .mynvfortranrc in your home directory.

The installation of this version of the compiler resides in Basedir/Linux_x86_64/dev/; other versions may coexist in Basedir/Linux_x86_64/release/. Basedir is the root of the compiler installation directory, specified by the installer. The default is /opt/nvidia/hpc_sdk.

The compiler installation subdirectories are:

  • compilers/bin/ โ€” compiler and tool executables and configuration files (rcfiles).
  • compilers/include/ โ€” compiler include files.
  • compilers/lib/ โ€” runtime libraries and object files.
  • comm_libs/ โ€” communication libraries, including NCCL and NVSHMEM.
  • math_libs/ โ€” math libraries, including cuBLAS, cuTENSOR, cuSPARSE, cuFFT, cuSOLVER, and cuRAND.
  • profilers/ โ€” profilers, including Nsight Compute and Nsight Systems.

๐Ÿ‘€ SEE ALSO ๐Ÿ‘€

nvc (1), nvc++ (1), and the NVIDIA User's Guide.


๐Ÿšจ DIAGNOSTICS ๐Ÿšจ

The compiler produces information and error messages as it translates the input program. The linker and assembler may issue their own error messages. So if something looks cursed, check who's actually yelling at you ๐Ÿ‘‘.


okay that's literally the whole page, bestie! source/version is nvfortran(1), dated September 2026 โ€” now go compile something iconic ๐Ÿ’…โœจ๐Ÿฆ‹

๐Ÿ“ฆ where this page comes from