8 minutes
Written: 2021-07-02 23:26 +0000
Updated: 2024-08-06 00:52 +0000
GSoC21 W4: LFortran, Backends and Bugs
This post is part of the GSoC21: LFortran series.
Towards the mid-summer evaluation and redirecting efforts
Background
Serialized update for the 2021 Google Summer of Code under the fortran-lang organization, mentored by Ondrej Certik.
Overview
This week was a bit of a sticky wicket. My unfamiliarity with the LLVM backend
and its internals caught up with me just around the same time I ran into several
fixture and rent related idiosyncrasies which led to yet another shift in my
weekly meeting. Thanks to a timely reminder from my mentor Ondrej, I managed,
nevertheless, to make some concrete progress working on the compilation of
dftatom
modules.
New Merge Requests
- ASR Bug with Arrays (997)
- Fixes a bug in the existing handling of arrays and
allocate
calls
Freshly Assigned Issues
- Semantics: Implement TINY (388)
- A classic intrinsic for error handling
- Semantics: Array Initializer Expressions (389)
- A bugfix related to the merge request
- ODE1 Error (390)
- Placeholder issue to be narrowed and chiseled into something actionable
- ASR mismatch between `gfortran` modules and source (395)
- Issue relating to the completeness and equivalence of
mod
formats
Additional Tasks
I’d like to make some time to continue exploring the LLVM, and continue familiarizing myself with formal language and automata theory.
Logistics
- I met with Ondrej on Friday this week
- He was kind enough to make a standing meeting twice a week, Tuesdays and Fridays
- This was done to ensure concrete progress is made beyond intangibles
- Discussed the possibility of extending the
lfortran mod
interface- Currently this has a copy of the ASR
- In principle then, later modules are larger since they have relevant code
- While
gfortran
does not bother with having a concrete representation in themod
file
- Discussed forming a functional subset of the
dftatom
code for now- This is related to the slight change in direction which is being considered
- Rather than stick to one feature / function from front end to back end, it was decided that a more breadth first approach would be better
- Though I am still encouraged to delve into the backend, it is good to set up a fully working rational ASR pass first
- Eventually, backends aside, work will need to be undertaken for the runtime library as well
Misc Log
Some other things which came my way this week.
Linking Troubles
Sometime down the line of modules and the roadmap to dftatom
described in the master issue here, I ran into an odd linker error. These seem to show up with both miniconda
and nix
, however, it is unclear to me at the moment if it warrants an issue until I check on a native ArchLinux machine. Another natural fix might be to actually bring in and compile llvm
; then use the lld
linker instead of the bfd
.
1lfortran mod types.mod --show-asr
2Traceback (most recent call last):
3 File "/build/glibc-2.32/csu/../sysdeps/x86_64/start.S", line 120, in _start()
4 Binary file "/nix/store/hp8wcylqr14hrrpqap4wdrwzq092wfln-glibc-2.32-37/lib/libc.so.6", in __libc_start_main()
5 File "/users/home/rog32/Git/Github/Fortran/mylf/src/bin/lfortran.cpp", line 1086, in ??
6 asr = LFortran::mod_to_asr(al, arg_mod_file);
7LFortranException: Unknown module file format
In any case, for now, switching to micromamba
and using direnv
just works.
Missing Symbols
This actually seems related to the more pertinent issue namely, that my lapack
module didn’t seem to contain relevant symbols at all:
1lfortran -c types.f90 -o types.o
2lfortran -c lapack.f90 -o lapack.o
3lfortran -c constants.f90 -o constants.o
4lfortran -c interpolation.f90 -o interpolation.o
5Semantic error: The symbol 'dgesv' not found in the module 'lapack'
This is true actually:
1cat lapack.mod | grep dgesv
Truncated Stacktraces
Also related, probably, was an issue I noticed while co-working with Ondrej, namely, that my stacktraces in nix
were and are a good deal less informative than his, probably due to the default nix lack of debug symbols. This can be quickly reproduced with:
1lfortran character_array.f90
2BFD: DWARF error: could not find variable specification at offset 2722f
3BFD: DWARF error: could not find variable specification at offset 2723e
4BFD: DWARF error: could not find variable specification at offset 2736f
5BFD: DWARF error: could not find variable specification at offset 2722f
6BFD: DWARF error: could not find variable specification at offset 2723e
7BFD: DWARF error: could not find variable specification at offset 2736f
8BFD: DWARF error: could not find variable specification at offset 2722f
9BFD: DWARF error: could not find variable specification at offset 2723e
10BFD: DWARF error: could not find variable specification at offset 2736f
11BFD: DWARF error: could not find variable specification at offset 2722f
12BFD: DWARF error: could not find variable specification at offset 2723e
13BFD: DWARF error: could not find variable specification at offset 2736f
14BFD: DWARF error: could not find variable specification at offset 2722f
15BFD: DWARF error: could not find variable specification at offset 2723e
16BFD: DWARF error: could not find variable specification at offset 2736f
17BFD: DWARF error: could not find variable specification at offset 2722f
18BFD: DWARF error: could not find variable specification at offset 2723e
19BFD: DWARF error: could not find variable specification at offset 2736f
20BFD: DWARF error: could not find variable specification at offset 615b9
21Traceback (most recent call last):
22 File "/build/glibc-2.32/csu/../sysdeps/x86_64/start.S", line 120, in _start()
23 Binary file "/nix/store/hp8wcylqr14hrrpqap4wdrwzq092wfln-glibc-2.32-37/lib/libc.so.6", in __libc_start_main()
24 File "/users/home/rog32/Git/Github/Fortran/mylf/src/bin/lfortran.cpp", line 1250, in ??
25 err = compile_to_object_file(arg_file, tmp_o, false,
26 File "/users/home/rog32/Git/Github/Fortran/mylf/src/bin/lfortran.cpp", line 601, in (anonymous namespace)::compile_to_object_file(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, bool) [clone .isra.0]
27 result = fe.get_asr2(input);
28 File "/users/home/rog32/Git/Github/Fortran/mylf/src/lfortran/codegen/evaluator.cpp", line 469, in LFortran::FortranEvaluator::get_asr2(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)
29 asr = ast_to_asr(al, *ast, symbol_table);
30 File "/users/home/rog32/Git/Github/Fortran/mylf/src/lfortran/semantics/ast_to_asr.cpp", line 3091, in LFortran::ast_to_asr(Allocator&, LFortran::AST::TranslationUnit_t&, LFortran::SymbolTable*)
31 v.visit_TranslationUnit(ast);
32 File "/users/home/rog32/Git/Github/Fortran/mylf/src/lfortran/ast.h", line 3235, in LFortran::SymbolTableVisitor::visit_TranslationUnit(LFortran::AST::TranslationUnit_t const&)
33 case modType::Program: { v.visit_Program((const Program_t &)x); return; }
34 File "/users/home/rog32/Git/Github/Fortran/mylf/src/lfortran/ast.h", line 3555, in LFortran::AST::BaseVisitor<LFortran::SymbolTableVisitor>::visit_program_unit(LFortran::AST::program_unit_t const&)
35 void visit_program_unit(const program_unit_t &b) { visit_program_unit_t(b, self()); }
36 File "/users/home/rog32/Git/Github/Fortran/mylf/src/lfortran/ast.h", line 3561, in LFortran::AST::BaseVisitor<LFortran::SymbolTableVisitor>::visit_unit_decl2(LFortran::AST::unit_decl2_t const&)
37 void visit_unit_decl2(const unit_decl2_t &b) { visit_unit_decl2_t(b, self()); }
38 File "/users/home/rog32/Git/Github/Fortran/mylf/src/lfortran/ast.h", line 3624, in LFortran::AST::BaseVisitor<LFortran::SymbolTableVisitor>::visit_expr(LFortran::AST::expr_t const&)
39 void visit_expr(const expr_t &b) { visit_expr_t(b, self()); }
40 File "/users/home/rog32/Git/Github/Fortran/mylf/src/lfortran/ast.h", line 3369, in void LFortran::AST::visit_expr_t<LFortran::SymbolTableVisitor>(LFortran::AST::expr_t const&, LFortran::SymbolTableVisitor&)
41 static void visit_expr_t(const expr_t &x, Visitor &v) {
42 Binary file "/nix/store/hp8wcylqr14hrrpqap4wdrwzq092wfln-glibc-2.32-37/lib/libc.so.6", in killpg()
43Segfault: Signal SIGSEGV (segmentation fault) received
With a rather simple test problem I was using for my allocatable length
character feature.
1! character_array.f90
2program character_array
3 implicit none
4
5 character(15) :: something
6 something = "sUpErWeiRdCaSe"
7
8 call upcase(something)
9
10 something = upcase_func(something)
11
12 contains
13
14subroutine upcase(s)
15! Returns string 's' in uppercase
16character(*), intent(in) :: s
17character(len(s)) :: t
18integer :: i, diff
19t = s; diff = ichar('A')-ichar('a')
20do i = 1, len(t)
21 if (ichar(t(i:i)) >= ichar('a') .and. ichar(t(i:i)) <= ichar('z')) then
22 ! if lowercase, make uppercase
23 t(i:i) = char(ichar(t(i:i)) + diff)
24 end if
25end do
26print*, "Subroutine"
27print*, "Length of arg is ", len(s)
28print*, "Converted " // s // " to " // t
29
30end subroutine
31
32function upcase_func(s) result(t)
33! Returns string 's' in uppercase
34character(*), intent(in) :: s
35character(len(s)) :: t
36integer :: i, diff
37t = s; diff = ichar('A')-ichar('a')
38do i = 1, len(t)
39 if (ichar(t(i:i)) >= ichar('a') .and. ichar(t(i:i)) <= ichar('z')) then
40 ! if lowercase, make uppercase
41 t(i:i) = char(ichar(t(i:i)) + diff)
42 end if
43end do
44! print*, new_line('c')
45print*, "Function"
46print*, "Length of arg is ", len(s)
47print*, "Converted " // s // " to " // t
48end function
49
50end program character_array
Gfortran Modules
One of the early goals was inter-operability with the gfortran
module format. This is a lisp
like syntax which changes occasionally.
1! simple module
2module b
3implicit none
4private
5public g
6contains
7integer function g()
8g = 5
9end function
10end module
The corresponding asr
is given by:
1(TranslationUnit (SymbolTable 1 {b: (Module (SymbolTable 2 {g: (Function (SymbolTable 3 {g: (Variable 3 g ReturnVar () Default (Integer 4 []) Source Public Required)}) g [] [(= (Var 3 g) (ConstantInteger 5 (Integer 4 [])))] (Var 3 g) Source Public Implementation)}) b [] .false.)}) [])
For the currently supported gfortran
module (v14) we get:
1lfortran mod b14.mod --show-asr
2(TranslationUnit (SymbolTable 1 {g: (Subroutine (SymbolTable 2 {}) g [] [] GFortranModule Public Interface)}) [])
Which is contains a lower amount of information. The differences between the module versions are not major:
More importantly however, the module versions correspond to being compressed and this needs to be eventually handled as well.
Conclusions
For the next week, I shall be finalizing work on the allocatable character lengths and moving on to some more semantics and intrinsics. Naturally as these are completed there will be more progress down the dftatom
module listing. The main takeaway from this week for me was the retargeting of efforts. I do wish to continue struggling with the backend simply because I feel it is exciting and fun, but I shall endeavor to be more productive by applying a breadth first approach by contributing more concrete code every week. I have high hopes for being able to power through the intended project goals by the end of the program, and can always clean up / document afterwards.
Series info
GSoC21: LFortran series
- GSoC21 W1: LFortran Kickoff
- GSoC21 W2: LFortran Unraveling
- GSoC21 W3: Kind, Characters, and Standards
- GSoC21 W4: LFortran, Backends and Bugs <-- You are here!
- GSoC21 W5: LFortran Design Details and minidftatom
- GSoC21 W6: LFortran ASR and Values
- GSoC21 W7: LFortran Workflow Basics
- GSoC21 W8: LFortran Refactors, and Compile Time Evaluations
- GSoC21 W9: LFortran Bug Hunting Bonanza
- GSoC21 W10: LFortran Runtime Library Design
- GSoC21 LFortran and Computational Chemistry