Debugging Fortran using Visual Studio Code - pjuangph/fortran GitHub Wiki

Debugging files created using gfortran

In visual studio code there is an option to compile, this is done by creating a task [Terminal-Configure Tasks] and there is an option to launch with debug.

Step 1. Create a makefile which is called by the task json

# Makefile with autodependancy generation
# Note: Before running, you need to install fortdepend `pip install fortdepend` 
# 		fortdepend path can vary so make sure you edit the MAKEDEPEND variable

## Compiler Flags
FC=gfortran		# Fortran Compiler
FFLAGS= -g -Wall -Wextra # -O2  # Note: Compiler optimization flags like -O2 will interfere with debugging
LINKER = $(FC) -o
FCLINKS = -g 
#FFLAGS=-Wall -Wextra -fopenmp		# OpenMP

# $(DEP_FILE) is a .dep file generated by fort_depend.py
DEP_FILE = my_project.dep
PROG = main.exe

# Source files to compile
SOURCES := $(shell find $(SOURCE_DIR) -name '*.f95')
OBJECTS := $(SOURCES:.f95=.o)
$(info $(SOURCES))

build: | check create_objects $(PROG)	

## Auto Generation of Dependancies 
MAKEDEPEND=~/anaconda3/envs/dev/bin/fortdepend
.PHONY: check
check:
ifeq (,$(wildcard $(DEP_FILE)))
	@echo "Creating dependancy file"
	$(shell $(MAKEDEPEND) -f $(SOURCES) -o $(DEP_FILE))	
else
	@echo "$(DEP_FILE) exists, skipping"
endif
-include $(DEP_FILE)

.PHONY: clean
clean :
	@rm -rf *.mod *.o *.exe *.dep

create_objects : *.f95
	@echo "-----------------------------"
	@echo "Creating modules"
	@echo "-----------------------------"
	$(FC) $(FFLAGS) -c $<

%.o : %.f95
	@echo "-----------------------------"
	@echo "Compiling the files into objects"
	@echo "-----------------------------"
	$(FC) $(FFLAGS) -c $<

$(PROG) : $(OBJECTS)
	@echo "-----------------------------"
	@echo "Creating the executable"
	@echo "-----------------------------"
	$(LINKER) $(PROG) $(OBJECTS) $(FCLINKS)

Step 2. and the second step is to create a task json by clicking terminal/configure-tasks Tasks calls make clean then calls make build. It's important to separate them and use the dependsOn to call the clean task

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "label": "clean",
            "type": "shell",
            "command": ["make clean"],
            "args": []            
        },
        {
            "label": "build",
            "type": "shell",
            "command": ["make build"],
            "args": [],
            "group": "build",
            "presentation": {
                // Reveal the output only if unrecognized errors occur.
                "reveal": "silent"
            },
            "dependsOn":["clean"],
            // Use the standard MS compiler pattern to detect errors, warnings and infos
            "problemMatcher": "$msCompile"
        }
    ]
}

Step 3. Set up the debugger through the launch.json. Click the debugger icon and click create launch json file. The file should be set up to use gdb for debugging.

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "(gdb) Debug Fortran",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/main.exe",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ],
            "preLaunchTask": "build"
        }
    ]
}

Example

Compiling and Debugging non-cuda Programs built using nvfortran

It is possible to debug code that is non-cuda or non-openacc that are compiled with nvfortran. Debugging can be done with a simple gdb.

Biggest changes to the makefile is the path to the compiler (hpc_install_path) and (FC). The launch.json remains the same as above.

# Makefile with autodependancy generation
# Note: Before running, you need to install fortdepend `pip install fortdepend` 
# 		fortdepend path can vary so make sure you edit the MAKEDEPEND variable

### Compiler Flags
hpc_install_path=/opt/nvidia/hpc_sdk/Linux_x86_64/2020/compilers/bin
FC=$(hpc_install_path)/nvfortran		#nvidia fortran compiler
FFLAGS= -g  # Note: Compiler optimization flags like -O2 will interfere with debugging (-g)
LINKER = $(FC) -o
FCLINKS = -g 
#FFLAGS=-Wall -Wextra -fopenmp		# OpenMP

# $(DEP_FILE) is a .dep file generated by fort_depend.py
DEP_FILE = my_project.dep
PROG = main.exe

# Source files to compile
SOURCES := $(shell find $(SOURCE_DIR) -name '*.f95')
OBJECTS := $(SOURCES:.f95=.o)
$(info $(SOURCES))

build: | check create_objects $(PROG)	

## Auto Generation of Dependancies 
MAKEDEPEND=~/anaconda3/envs/dev/bin/fortdepend
.PHONY: check
check:
ifeq (,$(wildcard $(DEP_FILE)))
	@echo "Creating dependancy file"
	$(shell $(MAKEDEPEND) -f $(SOURCES) -o $(DEP_FILE))	
else
	@echo "$(DEP_FILE) exists, skipping"
endif
-include $(DEP_FILE)



.PHONY: clean
clean :
	@rm -rf *.mod *.o *.exe *.dep

create_objects : *.f95
	@echo "-----------------------------"
	@echo "Creating modules"
	@echo "-----------------------------"
	$(FC) $(FFLAGS) -c $<

%.o : %.f95
	@echo "-----------------------------"
	@echo "Compiling the files into objects"
	@echo "-----------------------------"
	$(FC) $(FFLAGS) -c $<

$(PROG) : $(OBJECTS)
	@echo "-----------------------------"
	@echo "Creating the executable"
	@echo "-----------------------------"
	$(LINKER) $(PROG) $(OBJECTS) $(FCLINKS)

Compiling and Debugging openacc programs built using nvfortran

Debugging is the same for these files. However since the compiler directive -acc is used, the variables cannot be inspected for their values. The benefit will be to use it to trace the call stack.