Error: Rank mismatch in argument (rank-1 and scalar) - fortran
I am getting these kind of errors.
colsys.f:1367.51:
1 NOLD, ALDIF, K, NCOMP, M, MSTAR, 3,DUMM,0)
1
Warning: Rank mismatch in argument 'dmval' at (1) (rank-1 and scalar)
colsys.f:814.33:
1 EALPHA, A, IPIV, INTEGS, RNORM, 0, FSUB,
1
Warning: Actual argument contains too few elements for dummy argument 'integs' (1/3) at (1)
Here I an giving the program link. More errors are there in the link provided below. Some of the errors I fixed. But I don't know how to attach the updated program since it is too long to copy and paste.
http://www4.ncsu.edu/~mtchu/Teaching/Lectures/MA581/colsys.f
Either
a) in the declaration of a procedure (either a function or a subroutine) argument dumm is defined to be a rank-1 array (an array with 1 dimension if you prefer but 'rank-1' is the Fortran terminology that your compiler uses) and when your code calls the procedure it is given a scalar value. Note in particular that a scalar value is not the same (for argument matching) as a rank-1 array with only one element.
or
b) vice-versa.
Either way, there is a mismatch between the argument in the procedure definition and the argument passed when the procedure is called.
The second error you report is similar, it seems that when the procedure is called it expects a 3-element array but gets only a 1-element array. Or something like that.
Personally I'm not inclined to follow links off-site in search of more errors to fix.
The linked code is an old code written in 1981 (more than 35 years ago!), and it seems that all the warning messages come from the now obsolete way of using one-element arrays as assumed-size arrays, e.g.,
DIMENSION M(1), ZETA(1), IPAR(1), LTOL(1), TOL(1),
So, I guess it will probably be OK to just ignore all the warning messages as long as it compiles successfully. If desired, the warnings may be suppressed by some compiler options, or by modifying such arrays to assumed-size ones, e.g.
DIMENSION M(*), ZETA(*), IPAR(*), LTOL(*), TOL(*),
Another problem is that the author passes a scalar variable named DUMM etc to a dummy array argument that is not used in the subroutine. So, to avoid warnings, we also need to declare those variables explicitly as DUMM(1) in the caller side.
To actually modify the code, replace dummy arguments with (1) and ,1) in the DIMENSION statement by (*) and ,*) (which could be done by hand or by sed/awk). Then the difference between the original and modified codes becomes as follows. Although it is still not clear whether the code works correctly, this at least eliminates all the warnings by gfortran and ifort.
457,458c457,461
< DIMENSION M(1), ZETA(1), IPAR(1), LTOL(1), TOL(1),
< 1 FIXPNT(1), ISPACE(1), FSPACE(1)
---
> DIMENSION M(*), ZETA(*), IPAR(*), LTOL(*), TOL(*),
> 1 FIXPNT(*), ISPACE(*), FSPACE(*)
>
> dimension dum1(1), dum2(1), dum3(1), dum4(1)
>
769,771c772,774
< DIMENSION XI(1), XIOLD(1), XIJ(1), ALPHA(1), ALDIF(1), RHS(1)
< DIMENSION A(1), VALSTR(1), SLOPE(1), ACCUM(1), IPIV(1), INTEGS(1)
< DIMENSION DALPHA(1), EALPHA(1) , FIXPNT(1)
---
> DIMENSION XI(*), XIOLD(*), XIJ(*), ALPHA(*), ALDIF(*), RHS(*)
> DIMENSION A(*), VALSTR(*), SLOPE(*), ACCUM(*), IPIV(*), INTEGS(*)
> DIMENSION DALPHA(*), EALPHA(*) , FIXPNT(*)
1260,1261c1263,1266
< DIMENSION D1(40), D2(40), ZV(40), SLOPE(1), ACCUM(1), VALSTR(1)
< DIMENSION XI(1), XIOLD(1), XIJ(1), ALDIF(1), FIXPNT(1)
---
> DIMENSION D1(40), D2(40), ZV(40), SLOPE(*), ACCUM(*), VALSTR(*)
> DIMENSION XI(*), XIOLD(*), XIJ(*), ALDIF(*), FIXPNT(*)
>
> dimension dumm(1)
1755c1760,1762
< DIMENSION XIOLD(1), ALDIF(1), VALSTR(1), WORK(MSTAR,1)
---
> DIMENSION XIOLD(*), ALDIF(*), VALSTR(*), WORK(MSTAR,*)
>
> dimension dumm(1)
1899,1900c1906,1907
< DIMENSION ALPHO(1), XI(1), XIOLD(1), XIJ(1), ALPHA(1)
< DIMENSION ALDIF(1), RHS(1), A(1), IPIV(1), INTEGS(3,1)
---
> DIMENSION ALPHO(*), XI(*), XIOLD(*), XIJ(*), ALPHA(*)
> DIMENSION ALDIF(*), RHS(*), A(*), IPIV(*), INTEGS(3,*)
1901a1909,1910
>
> dimension dummy(1)
2163,2164c2172,2173
< DIMENSION Q(NROW,1), Z(1), DF(NCOMP,1)
< DIMENSION XI(1), BASEF(620), ALPHO(1), DG(40)
---
> DIMENSION Q(NROW,*), Z(*), DF(NCOMP,*)
> DIMENSION XI(*), BASEF(620), ALPHO(*), DG(40)
2329c2338,2341
< DIMENSION Z(1), FSPACE(1), ISPACE(1)
---
> DIMENSION Z(*), FSPACE(*), ISPACE(*)
>
> dimension dumm(1)
>
2332c2344,2345
< CALL APPROX (ISPACE(5), X, Z, FSPACE(IS6), FSPACE, ISPACE,
---
> CALL APPROX (ISPACE(5), X, Z, FSPACE(IS6), FSPACE, ISPACE(1),
> c CALL APPROX (ISPACE(5), X, Z, FSPACE(IS6), FSPACE, ISPACE,
2374c2387
< DIMENSION Z(1), VN(1), XI(1), ALDIF(1), M(1), DMVAL(1)
---
> DIMENSION Z(*), VN(*), XI(*), ALDIF(*), M(*), DMVAL(*)
2482c2495
< DIMENSION VN(1), M(1)
---
> DIMENSION VN(*), M(*)
2532c2545
< DIMENSION VN(1), XI(1), M(1)
---
> DIMENSION VN(*), XI(*), M(*)
2612c2625
< DIMENSION BASEF(1), VN(1), XMESH(1)
---
> DIMENSION BASEF(*), VN(*), XMESH(*)
2889c2902
< DIMENSION ALDIF(1), ALPHA(1), XI(1), M(1)
---
> DIMENSION ALDIF(*), ALPHA(*), XI(*), M(*)
3004,3005c3017,3018
< DIMENSION UHIGH(1) , AR(20), ARM1(20)
< DIMENSION ALDIF(1), XIOLD(1)
---
> DIMENSION UHIGH(*) , AR(20), ARM1(20)
> DIMENSION ALDIF(*), XIOLD(*)
Related
MergeSort vs. antialising rule
I have the following implementation of the MergeSort algorithm in Fortran. My question is about call merge(work(1 : half), A(half + 1:), A). Obviously I have overlapping memory, but from looking at the code in merge, this should be no problem, as long as the input arrays are sorted. (Which they are assumed to be anyway.) On the other hand Fortran compilers may assume non aliased memory, so I always think "don't do this". I have two questions now: When and how can I run into problems with my merge subroutine. If I cannot implement MergeSort like this, how do I do it without creating a temporary array. !> Merge sorted arrays A and B into C while preversing order. subroutine merge(A, B, C) implicit none integer, intent(in) :: A(:), B(:) integer, intent(inout) :: C(:) integer :: i, j, k if (size(A) + size(B) > size(C)) abort i = 1; j = 1 do k = 1, size(C) if (i <= size(A) .and. j <= size(B)) then if (A(i) <= B(j)) then C(k) = A(i) i = i + 1 else C(k) = B(j) j = j + 1 end if else if (i <= size(A)) then C(k) = A(i) i = i + 1 else if (j <= size(B)) then C(k) = B(j) j = j + 1 end if end do end subroutine merge recursive subroutine MergeSort(A, work) implicit none integer, intent(inout) :: A(:) integer, intent(inout) :: work(:) integer :: half half = (size(A) + 1) / 2 if (size(A) < 2) then continue else if (size(A) == 2) then call naive_sort(A) else call MergeSort(A( : half), work) call MergeSort(A(half + 1 :), work) if (A(half) > A(half + 1)) then work(1 : half) = A(1 : half) ! TODO: Non aliasing rule. call merge(work(1 : half), A(half + 1:), A) endif end if end subroutine MergeSort PS: As you perhaps notice, the array C in the merge subroutine is declared as an inout parameter, because it is later used with overlapping memory.
This use of aliasing in calling merge is erroneous. With call merge(work(1 : half), A(half + 1:), A) the dummy argument B is associated with A(half+1:) and the dummy argument C with A which is the understood overlap. This aliasing means that the elements of B may not be defined (which is additionally required by the intent) and that the last few elements of C may not be defined. However, if we look at the main loop in merge we see that in general every element of C appears in a statement looking like C(k)=...: we expect at least one of those conditions inside to be true. This is therefore invalid. To be clear: a statement like C(k)=B(j) would be an illegal definition even if the value of C(k) doesn't change as a result. Fortunately, perhaps, there is an easy way to create a temporary array to avoid aliasing: give the dummy argument B the value attribute. You could even do the same to A and remove the workspace array.
OpenMP reduction into array of C++ template-specified size causes undefined behaviour
I'm new to OpenMP, but am trying to use it to accelerate some operations on entries of a 2D array with a large number of rows and a small number of columns. At the same time, I am using a reduction to calculate the sum of all the array values in each column. The code looks something like this (I will explain the weird bits in a moment): template <unsigned int NColumns> void Function(int n_rows, double** X, double* Y) { #pragma omp parallel for reduction(+:Y[:NColumns]) for (int r = 0; r < n_rows; ++r) { for (int c = 0; c < NColumns; ++c) { X[r][c] = some_complicated_stuff(X[r], X[r][c]); Y[c] += X[r][c]; } } } To clarify, X is a n_rows x NColumns-sized 2D array allocated on the heap, and Y is a NColumns-sized 1D array. some_complicated_stuff isn't actually implemented as a separate function, but what I do to X[r][c] in that line only depends on X[r][c] and other values in the 1D array X[r]. The reason that NColumns is passed in as a template parameter rather than as a regular argument (like n_rows) is that when NColumns is known at compile-time, the compiler can more aggressively optimise the inner loop in the above function. I know that NColumns is going to be one of a small number of values when the program runs, so later on I have something like this code: cin >> n_cols; double** X; double Y[n_cols]; // initialise X and Y, etc. . . for (int i = 0; i < n_iterations; ++i) { switch (n_cols) { case 2: Function< 2>(X, Y); break; case 10: Function<10>(X, Y); break; case 60: Function<60>(X, Y); break; default: throw "Unsupported n_cols."; break; } // . . . Report(i, Y); // see GDB output below } Through testing, I have found that having this NColumns "argument" to Update as a template parameter rather than a normal function parameter actually makes for an appreciable performance increase. However, I have also found that, once in a blue moon (say, about every 10^7 calls to Function), the program hangsāand even worse, that its behaviour sometimes changes from one run of the program to the next. This happens rarely enough that I have been having a lot of trouble isolating the bug, but I'm now wondering whether it's because I am using this NColumns template parameter in my OpenMP reduction. I note that a similar StackOverflow question asks about using template types in reductions, which apparently causes unspecified behaviour - the OpenMP 3.0 spec says If a variable referenced in a data-sharing attribute clause has a type derived from a template, and there are no other references to that variable in the program, then any behavior related to that variable is unspecified. In this case, it's not a template type per se that is being used, but I'm sort of in the same ballpark. Have I messed up here, or is the bug more likely to be in some other part of the code? I am using GCC 6.3.0. If it is more helpful, here's the real code from inside Function. X is actually a flattened 2D array; ww and min_x are defined elsewhere: #pragma omp parallel for reduction(+:Y[:NColumns]) for (int i = 0; i < NColumns * n_rows; i += NColumns) { double total = 0; for (int c = 0; c < NColumns; ++c) if (X[i + c] > 0) total += X[i + c] *= ww[c]; if (total > 0) for (int c = 0; c < NColumns; ++c) if (X[i + c] > 0) Y[c] += X[i + c] = (X[i + c] < min_x * total ? 0 : X[i + c] / total); } Just to thicken the plot a bit, I attached gdb to a running process of the program which hanged, and here's what the backtrace shows me: #0 0x00007fff8f62a136 in __psynch_cvwait () from /usr/lib/system/libsystem_kernel.dylib #1 0x00007fff8e65b560 in _pthread_cond_wait () from /usr/lib/system/libsystem_pthread.dylib #2 0x000000010a4caafb in omp_get_num_procs () from /opt/local/lib/libgcc/libgomp.1.dylib #3 0x000000010a4cad05 in omp_get_num_procs () from /opt/local/lib/libgcc/libgomp.1.dylib #4 0x000000010a4ca2a7 in omp_in_final () from /opt/local/lib/libgcc/libgomp.1.dylib #5 0x000000010a31b4e9 in Report(int, double*) () #6 0x3030303030323100 in ?? () [snipped traces 7-129, which are all ?? ()] #130 0x0000000000000000 in ?? () Report() is a function that gets called inside the program's main loop but not within Function() (I've added it to the middle code snippet above), and Report() does not contain any OpenMP pragmas. Does this illuminate what's happening at all? Note that the executable changed between when the process started running and when I attached GDB to it, which required referring to the new (changed) executable. So that could mean that the symbol table is messed up.
I have managed to partly work this out. One of the problems was with the program behaving nondeterministically. This is just because (1) OpenMP performs reductions in thread-completion order, which is non-deterministic, and (2) floating-point addition is non-associative. I assumed that the reductions would be performed in thread-number order, but this is not the case. So any OpenMP for construct that reduces using floating-point operations will be potentially non-deterministic even if the number of threads is the same from one run to the next, so long as the number of threads is greater than 2. Some relevant StackOverflow questions on this matter are here and here. The other problem was that the program occasionally hangs. I have not been able to resolve this issue. Running gdb on the hung process always yields __psynch_cvwait () at the top of the stack trace. It hangs around every 10^8 executions of the parallelised for loop. Hope this helps a little.
Why does it output error crash?
I am writing a code to analyze a game, and I have a problem. This code goes through every combination of 7 six-sided dices (from 1111111 to 6666666) and for every combination it sees if the combination makes some points or not. So I tried to check if it could put in the console every dice-combinations and the points associated just to check and it ran fine until 1223353 but at 1223354 it "crashed", as the image shows.Here we can see the console running my code. So I don't understand why it just stops after ~10'000 iterations. P.S.: I tried to run it in code blocks and it didn't work either... Thank you for your answers!
Ok, when the debugger gets to this line it crashes: if (sptopt[k]==sptopt[j]){ // here k == 3 and sptopt.size() == 3 sptopt.erase(sptopt.begin()+k); // this line crashes sdesopt.erase(sdesopt.begin()+k); soptch.erase(soptch.begin()+k); } I have looked at the state of the variables at the time of the crash and indeed: k == 3 and sptopt.size() == 3 Basically you are looping and erasing from a vector (which is very very inefficient from a memory perspective), and not checking that value of k is not equal/higher than the size of your vectors. This is the stack I got: Thread 1Queue : com.apple.main-thread (serial) #0 0x00007fff95687f49 in _platform_memmove$VARIANT$Haswell () #1 0x000000010001b8ab in std::__1::enable_if<(is_same<std::__1::remove_const<int>::type, int>::value) && (is_trivially_copy_assignable<int>::value), int*>::type std::__1::__move<int, int>(int*, int*, int*) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:1904 #2 0x000000010001b856 in int* std::__1::move<int*, int*>(int*, int*, int*) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:1913 #3 0x000000010001b802 in std::__1::vector<int, std::__1::allocator<int> >::erase(std::__1::__wrap_iter<int const*>) [inlined] at /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/vector:1676 #4 0x000000010001b675 in main at /Users/**/Documents/iosapps/Chat App/newdaf/newdaf/main.cpp:604 Every time you are about to access a vector that changed in size in a loop, you must add checks such as: if ( ( k < sptopt.size() ) && ( j < sptopt.size()) && ( k < sdesopt.size() ) && ( j < sdesopt.size()) && ( k < soptch.size() ) && ( j < soptch.size()) ... Otherwise you access/erase an element that does not exist. In the case of deletion you get a runtime error. When accessing only, C++ may not be so kind as telling you that you are not where you thought you were (it did enter the function with k being an invalid index), and your program from then on behaves very strangely. So you need to look at your functions and make sure your variables never go over the dimensions of the vectors you are using.
Issues with Halide select statement
I'm trying to do some stencil computation using Halide. So assuming a basic 5 point 2D stencil, to evaluate some value at cell i,j I need the values of i-1,j i-2,j, i+1,j i+2,j. Now the way this works in C++ is that I have a for statement: for(int i = 2; i < max_i - 2; i++) for(int j = 2; j < max_j - 2; j++) Calculate out = some_function_of(in(i,j), in(i-1,j), in(i-2,j), in(i+1,j), in(i+2,j)) Now I'm trying to do the same thing with Halide. so I have a Buffer called in which has the same value as my input array in the C++ code. And I have a Func called out: out(i,j) = select(i >= 2 && j >= 2, some_function_of(in(i,j), in(i-1,j), in(i-2,j), in(i+1,j), in(i+2,j)) ,0.0f) When I run this code I get the following error: Error: Input buffer b0 is accessed at -1, which is before the min (0) in dimension 0 Aborted (core dumped) From my understanding, the reason for this error is that the select statement evaluates both statements so eventhough I don't want to calculate anything for i and j values less than two, the function is evaluated at i = 0 and j = 0 and thus the invalid address access. So is there anyway to do this in Halide? Are there any other equivalents for if/else statements?
Using a boundary condition will do what you want: Func unbounded; unbounded(i, j,) = some_function_of(in(i,j), in(i-1,j), in(i-2,j), in(i+1,j), in(i+2,j)); out(i, j) = BoundaryConditions::constant_exterior(unbounded, 0.0f, 2, width - 4, 2, height - 4)(i, j); I believe you can use "Expr()" instead of "width - 4" or "height - 4" if you want the maximum unbounded. The use if BoundaryConditions functions allows hinting the compiler which direction of the if/else construct is more likely.
Segmentation fault - invalid memory reference
Hey I am trying to get my LAPACK libraries to work and I have searched and searched but I can't seem to figure out what I am doing wrong. I try running my code, and I get the following error Program received signal SIGSEGV: Segmentation fault - invalid memory reference. Backtrace for this error: #0 0x7FFB23D405F7 #1 0x7FFB23D40C3E #2 0x7FFB23692EAF #3 0x401ED1 in sgesv_ #4 0x401D0B in MAIN__ at CFDtest.f03:? Segmentation fault (core dumped) I will paste my main code here, hopefully someone can help me with this problem. **************************************************** PROGRAM CFD_TEST USE MY_LIB IMPLICIT DOUBLE PRECISION (A-H,O-Z) DIMENSION ET(0:10), VN(0:10), WT(0:10) DIMENSION SO(0:10), FU(0:10), DMA(0:10,0:10) DIMENSION DMA2(0:10,0:10), QN(0:10), WKSPCE(0:10) INTEGER*8 :: pivot(10), inf INTEGER*8 :: N EXTERNAL SGESV !SET THE PARAMETERS SIGMA1 = 0.D0 SIGMA2 = 0.D0 TAU = 1.D0 EF = 1.D0 EXP = 2.71828182845904509D0 COST = EXP/(1.D0+EXP*EXP) DO 1 N=2, 10 !COMPUATION OF THE NODES, WEIGHTS AND DERIVATIVE MATRIX CALL ZELEGL(N,ET,VN) CALL WELEGL(N,ET,VN,WT) CALL DMLEGL(N,10,ET,VN,DMA) !CONSTRUCTION OF THE MATRIX CORRESPONDING TO THE !DIFFERENTIAL OPERATOR DO 2 I=0, N DO 2 J=0, N SUM = 0.D0 DO 3 K=0, N SUM = SUM + DMA(I,K)*DMA(K,J) 3 CONTINUE OPER = -SUM IF(I .EQ. J) OPER = -SUM + TAU DMA2(I,J) = OPER 2 CONTINUE !CHANGE OF THE ENTRIES OF THE MATRIX ACCORDING TO THE !BOUNDARY CONDITIONS DO 4 J=0, N DMA2(0,J) = 0.D0 DMA2(N,J) = 0.D0 4 CONTINUE DMA2(0,0) = 1.D0 DMA2(N,N) = 1.D0 !CONSTRUCTION OF THE RIGHT-HAND SIDE VECTOR DO 5 I=1, N-1 FU(I) = EF 5 CONTINUE FU(0) = SIGMA1 FU(N) = SIGMA2 !SOLUTION OF THE LINEAR SYSTEM N1 = N + 1 CALL SGESV(N,N,DMA2,pivot,FU,N,inf) DO 6 I = 0, N FU(I) = SO(I) 6 CONTINUE PRINT *, pivot 1 CONTINUE RETURN END PROGRAM CFD_TEST ***************************************************** The commands I run to compile are gfortran -c MY_LIB.f03 gfortran -c CFDtest.f03 gfortran MY_LIB.o CFDtest.o -o CFDtest -L/usr/local/lib -llapack -lblas I ran the command -fbacktrace -g -Wall -Wextra CFDtest CFDtest: In function _fini': (.fini+0x0): multiple definition of_fini' /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o:/build/buildd/glibc-2.19/csu/../sysdeps/x86_64/crti.S:80: first defined here CFDtest: In function data_start': (.data+0x0): multiple definition ofdata_start' /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o:(.data+0x0): first defined here CFDtest: In function data_start': (.data+0x8): multiple definition of__dso_handle' /usr/lib/gcc/x86_64-linux-gnu/4.9/crtbegin.o:(.data+0x0): first defined here CFDtest:(.rodata+0x0): multiple definition of _IO_stdin_used' /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o:(.rodata.cst4+0x0): first defined here CFDtest: In function_start': (.text+0x0): multiple definition of _start' /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o:(.text+0x0): first defined here CFDtest: In function_init': (.init+0x0): multiple definition of _init' /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o:/build/buildd/glibc-2.19/csu/../sysdeps/x86_64/crti.S:64: first defined here /usr/lib/gcc/x86_64-linux-gnu/4.9/crtend.o:(.tm_clone_table+0x0): multiple definition of__TMC_END' CFDtest:(.data+0x10): first defined here /usr/bin/ld: error in CFDtest(.eh_frame); no .eh_frame_hdr table will be created. collect2: error: ld returned 1 exit status
You haven't posted your code for MY_LIB.f03 so we cannot compile CFDtest.f03 exactly as you have supplied it. (As an aside, the usual naming convention is that f90 in a .f90 file is not supposed to imply the language version being targeted. Rather, .f90 denotes free format while .f is used for fixed format. By extension, your .f03 files would be better (i.e., more portable if) named as .f90.) I commented out the USE MY_LIB line and ran your code through nagfor -u -c cfd_test.f90. The output, broken down, is Extension: cfd_test.f90, line 13: Byte count on numeric data type detected at *#8 Extension: cfd_test.f90, line 15: Byte count on numeric data type detected at *#8 Byte counts are not portable. The kind value for an 8-byte integer is selected_int_kind(18). (Similarly you might like to use a kind(0.0d0) kind value for your double precision data.) Error: cfd_test.f90, line 48: Implicit type for I detected at 2#I Error: cfd_test.f90, line 50: Implicit type for J detected at 2#J Error: cfd_test.f90, line 54: Implicit type for K detected at 3#K Error: cfd_test.f90, line 100: Implicit type for N1 detected at N1#= You have these implicitly typed, which implies they are 4-byte (default) integers. You should probably declare these explicitly as 8-byte integers (using the 8-byte integer kind value above) if that's what you intend. Questionable: cfd_test.f90, line 116: Variable COST set but never referenced Questionable: cfd_test.f90, line 116: Variable N1 set but never referenced Warning: cfd_test.f90, line 116: Unused local variable QN Warning: cfd_test.f90, line 116: Unused local variable WKSPCE You need to decide what you intend to do with these, or whether they are just deletable cruft. With the implicit integers declared explicitly, there is further output Warning: cfd_test.f90, line 116: Variable SO referenced but never set This looks bad. Obsolescent: cfd_test.f90, line 66: 2 is a shared DO termination label Your DO loops would probably be better using the modern END DO terminators (not shared!) Error: cfd_test.f90, line 114: RETURN is only allowed in SUBROUTINEs and FUNCTIONs This is obviously easy to fix. For the LAPACK call, one source of explicit interfaces for these routines is the NAG Fortran Library (through the nag_library module). Since your real data is not single precision, you should be using dgesv instead of sgesv. Adding USE nag_library, ONLY: dgesv and switching to call dgesv instead of sgesv, then recompiling as above, reveals Incorrect data type INTEGER(KIND=4) (expected INTEGER) for argument N (no. 1) of DGESV so you should indeed be using default (4-byte integers) - at least for the LAPACK build on your system, which will almost certainly be using 4-byte integers. Thus you might want to forget all about kinding your integers and just use the default integer type for all. Correcting this gives Array supplied for scalar argument LDA (no. 4) of DGESV so you do need to add this argument. Maybe pass size(DMA2,1)? With this argument added to the call the code compiles successfully, but without the definitions for your *LEGL functions I couldn't go through any run-time testing. Here is my modified (and pretty-printed) version of your program Program cfd_test ! Use my_lib ! Use nag_library, Only: dgesv Implicit None Integer, Parameter :: wp = kind(0.0D0) Real (Kind=wp) :: ef, oper, sigma1, sigma2, tau Integer :: i, inf, j, k, n, sum Real (Kind=wp) :: dma(0:10, 0:10), dma2(0:10, 0:10), et(0:10), fu(0:10), & so(0:10), vn(0:10), wt(0:10) Integer :: pivot(10) External :: dgesv, dmlegl, welegl, zelegl Intrinsic :: kind, size ! SET THE PARAMETERS sigma1 = 0._wp sigma2 = 0._wp tau = 1._wp ef = 1._wp Do n = 2, 10 ! COMPUATION OF THE NODES, WEIGHTS AND DERIVATIVE MATRIX Call zelegl(n, et, vn) Call welegl(n, et, vn, wt) Call dmlegl(n, 10, et, vn, dma) ! CONSTRUCTION OF THE MATRIX CORRESPONDING TO THE ! DIFFERENTIAL OPERATOR Do i = 0, n Do j = 0, n sum = 0._wp Do k = 0, n sum = sum + dma(i, k)*dma(k, j) End Do oper = -sum If (i==j) oper = -sum + tau dma2(i, j) = oper End Do End Do ! CHANGE OF THE ENTRIES OF THE MATRIX ACCORDING TO THE ! BOUNDARY CONDITIONS Do j = 0, n dma2(0, j) = 0._wp dma2(n, j) = 0._wp End Do dma2(0, 0) = 1._wp dma2(n, n) = 1._wp ! CONSTRUCTION OF THE RIGHT-HAND SIDE VECTOR Do i = 1, n - 1 fu(i) = ef End Do fu(0) = sigma1 fu(n) = sigma2 ! SOLUTION OF THE LINEAR SYSTEM Call dgesv(n, n, dma2, size(dma2,1), pivot, fu, n, inf) Do i = 0, n fu(i) = so(i) End Do Print *, pivot End Do End Program In general your development experience will be the most pleasant if you use as good a checking compiler as you can get your hands on and if you make sure you ask it to diagnose as much as it can for you.
As far as I can tell, there could be a number of problems: Your integers with INTEGER*8 might be too long, maybe INTEGER*4 or simply INTEGER would be better You call SGESV on double arguments instead of DGESV Your LDA argument is missing, so your code should perhaps look like CALL DGESV(N,N,DMA2,N,pivot,FU,N,inf) but you need to check whether this is what you want.