How to allocate a derived type-parameterized (Fortran 2003)? - gfortran

Am testing the derived type parameterized. the array in the derived type contains a scalar expression .
For example :
integer :: a(n+2)
I used the intel compiler version 18.0 . It works perfectly . But with gfortran 8.3 am having an internal compiler error
For example:
public
type mytab(n)
integer, len :: n
integer :: tab1(n)
integer :: tab2(n*2)
end type mytab
contains
subroutine create(pt1, n)
type(mytab(:)),allocatable, intent(out) :: pt1
integer, intent(in) :: n
allocate (mytab(n)::pt1)
end subroutine
The allocation works only for tab1 and not tab2
this is what a get as an error.
allocate (mytab(n)::pt1)
internal compiler error: in gfc_conv_expr_op, at fortran/trans-expr.c:3498
0x5c5fa9 gfc_conv_expr_op
../../gcc/fortran/trans-expr.c:3498
0x5c5fa9 gfc_conv_expr(gfc_se*, gfc_expr*)
../../gcc/fortran/trans-expr.c:7999
0x704b17 gfc_conv_expr_val(gfc_se*, gfc_expr*)
../../gcc/fortran/trans-expr.c:8056
0x704c30 gfc_conv_expr_type(gfc_se*, gfc_expr*, tree_node*)
../../gcc/fortran/trans-expr.c:8070
0x6e3401 structure_alloc_comps
../../gcc/fortran/trans-array.c:9129
0x6e6260 gfc_allocate_pdt_comp(gfc_symbol*, tree_node*, int, gfc_actual_arglist*)
../../gcc/fortran/trans-array.c:9405
0x73e4cd gfc_trans_allocate(gfc_code*)
../../gcc/fortran/trans-stmt.c:6599
0x6cf5e7 trans_code
../../gcc/fortran/trans.c:2001
0x6f5dbb gfc_generate_function_code(gfc_namespace*)
../../gcc/fortran/trans-decl.c:6515
0x6d2fe9 gfc_generate_module_code(gfc_namespace*)
../../gcc/fortran/trans.c:2227
0x68612b translate_all_program_units
../../gcc/fortran/parse.c:6112
0x68612b gfc_parse_file()
../../gcc/fortran/parse.c:6328
0x6cca5f gfc_be_parse_file
../../gcc/fortran/f95-lang.c:204
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <https://gcc.gnu.org/bugs/> for instructions.

Related

Haskell *** Exception: Prelude.read: no parse

Hi I am trying to complete CIS194 Spring 13 when I get the error message *** Exception: Prelude.read: no parse on one of my functions. The file that the function is in is called LogAnalysis.hs and the function is parseMessage, but the file also imports from Log.hs. Why am I geting this error message and how can I fix it?
Here is my code:
https://github.com/Adam-Morris/CIS194/tree/master/Homework-2
read is a function with type read :: Read a => String -> a. This means that read takes String as input and returns a value for some type a provided that a implements the Read type class. read has to know what specific type to return, and it can know that in one of two ways: either the type is given to it explicitly (e.g. read "123" :: Int or read "True" :: Bool) or it infers it from the context. In your case, read infers that it must return an Int because LogMessage expects an Int as its second parameter. So in this case the expression read [y] means: take the Char y, convert it into an one-element string, and then try to convert that to an Int, by parsing it. Now if y happens to contain a character that is not a decimal digit, it will fail (by throwing an exception) because it will not know how to covert it into an integer.
Now how can you deal with that issue? You must check that the input to read is ok before calling it. For example, you can check that y is a digit (using the appropriate function):
parseMessage (x:y:z)
| x == 'I' && isDigit y = LogMessage Info (read [y]) (unwords [z])
...
Alternatively, you can use readMaybe from Text.Read that is like read but it does not throw an exception if it fails, instead it returns a nothing value:
parseMessage (x:y:z)
| x == 'I', Just n <- readMaybe [y] = LogMessage Info n (unwords [z])
The problem is your input message format. You're reading a line as a string, then matching on the characters in the string (since a string is type alias for [Char]).
In your sample.log the first line (I 6 Completed armadillo processing) would be passed in as a string to parseMessage, and the parameters will take the following values:
x = 'I'
y = ' ' --single white space character
z = "6 Completed armadillo processing"
read gets the white space character and throws *** Exception: Prelude.read: no parse
In order to get the values, you could do the following:
parseMessage :: String -> LogMessage
parseMessage msg =
case words msg of
"I":y:z -> LogMessage Info (read y :: TimeStamp) (unwords z)
"W":y:z -> undefined
"E":y:z -> undefined
_ -> undefined
This way the first two valid words (MessageType and TimeStamp in this case) can be extracted easily.

Fortran save procedure as property in derived type

Is it possible to store a procedure as a property of a derived type? I was thinking of something along the lines of:
module funcs_mod
public :: add
contains
function add(y,z) result (x)
integer,intent(in) :: y,z
integer :: x
x = y + z
end function
end module
module type_A_mod
use funcs_mod
public :: type_A,set_operator
type type_A
procedure(),pointer,nopass :: operator
end type
contains
subroutine set_operator(A,operator)
external :: operator
type(type_A),intent(inout) :: A
A%operator => operator
end subroutine
function operate(A,y,z) result(x)
type(type_A),intent(in) :: A
integer,intent(in) :: y,z
integer :: x
x = A%operator(y,z)
end function
end module
program test
use type_A_mod
use funcs_mod
type(type_A) :: A
call set_operator(A,add)
write(*,*) operate(A,1,2)
end program
But this doesn't successfully compile. Several errors are displayed including:
1) Syntax error in procedure pointer component
and
2) 'operator' at (1) is not a member of the 'type_a' structure
As well as some unsuccessful use statements. Is there a way to do this correctly? Any help is greatly appreciated.
UPDATE:
I've modified procedure,pointer to procedure(),pointer and now the errors are
1) FUNCTION attribute conflicts with SUBROUTINE attribute in 'operator'
and
2) Can't convert UNKNOWN to INTEGER(4)
Both refer to the line x = A%operator(y,z)
As you have discovered, the syntax for declaring a procedure pointer declaration requires procedure([interface]), pointer [, ...] :: .... You chose procedure(), pointer, nopass :: operator.
The consequence of procedure() is that you are not declaring whether operator is a function or a subroutine. There is nothing untoward in this, but more work then remains in convincing the compiler that you are using the references consistently. Your compiler appears to not believe you.
Rather than go into detail of what the compiler thinks you mean, I'll take a different approach.
You reference A%operator for a structure A of type with that component as the result of the function operate. You say clearly in declaring this latter function that its result is an integer.
Now, assuming that you don't want to do exciting things with type/kind conversion to get to that integer result, we'll take that you always intend for A%operator to be a function with integer result. That means you can declare that procedure pointer component to be a function with integer result.
This still leaves you with choices:
type type_A
procedure(integer),pointer,nopass :: operator
end type
being a function with integer result and implicit interface, and
type type_A
procedure(add),pointer,nopass :: operator
end type
being a function with explicit interface matching the function add.
Your ongoing design choices inform your final decision.
As a final note, you aren't using implicit none. This is important when we consider your line
external :: operator
If operator is a function then (by implicit typing rules) it has a (default) real result. So, you want to change to one of the following
integer, external :: operator
or
procedure(integer) :: operator
or
procedure(add) :: operator
To conclude, and echo the comment by Vladimir F, think very carefully about your design. You currently have constraints from the reference of operate (in the function result and its arguments) that look like you really do know that the component will have a specific interface. If you are sure of that, then please do use procedure(add) as the declaration/

gfortran 4.8.0 bug? Return type mismatch of function

I just use gfortran 4.1.2 and gfortran 4.8.0 to compile the following simple code:
function foo(a, b) result(res)
integer, intent(in) :: a, b
integer res
res = a+b
end function foo
program test
integer a, b, c
c = foo(a, b)
end program test
gfortran 4.1.2 succeeds, but gfortran 4.8.0 gives the weird error:
test.F90:14.11:
c = foo(a, b)
1
Error: Return type mismatch of function 'foo' at (1) (REAL(4)/INTEGER(4))
Any idea?
There is a bug in your code, namely that you don't specify the return type of the function foo in the main program. Per the Fortran implicit typing rules it thus gets a type of default real.
You should (1) always use 'implicit none', furthermore if at all possible, (2) use modules or contained procedures thus giving you explicit interfaces.
The reason why GFortran 4.1 doesn't report this error is that older versions of GFortran always functioned in a 'procedure at a time' mode; thus the compiler is happily oblivious to any other functions in the same file. Newer versions work in 'whole file' mode (default since 4.6) where the compiler 'sees' all the procedures in a file at a time. This allows the compiler to catch errors such as the one in your code, and also provides some optimization opportunities.

Gfortran do loop if-statement error

I have a simple Fortran code, and I am getting an error that I cannot find a solution to. Does anyone know how to fix this?
subroutine sort(A,A_done,N,P)
! Sort a real array by algebraically increasing value and return the permutation that
! rearranges the array
implicit none
Integer N, TEMP1, K, L, P(N), TEMP2
real(8), dimension(:) :: A_done
real(8), dimension(:) :: A
DO K=1, N-1
DO L=K+1, N
if A(K)>A(L)
TEMP1=A(K)
TEMP2=P(K)
A(K)=A(L)
P(K)=P(L)
A(L)=TEMP1
P(L)=TEMP2
end if
END DO
END DO
A_done=A
RETURN
END
gfortran -Wall -Werror -fbounds-check -w -L -lm -o Simulation readinput.for noutfile.for mean.for covariance.for correlation.for rperm.for simmain.for sort.for
In file sort.for:13
if A(K)>A(L)
1
Error: Unclassifiable statement at (1)
In file sort.for:20
end if
1
Error: Expecting END DO statement at (1)
make: * [Simulation] Error 1
Thanks for the help
You have forgotten a pair of parentheses and a "then":
At if A(K)>A(L) you must type if (A(K)>A(L)) then
Other than that, your code has multiple issues:
At TEMP1=A(K) and similar expressions, you pass a real(8) value to an integer variable
I don't understand what the P variable does (could you describe please?), but you also mix real(8) and integer there.
You MUST specify the dimension of the arrays in the subroutine. (I think there is a way not doing so by using modules)
Keep in mind that you change A and then you copy it to A_done. Why to do so? You lose your original values and consume more memory.
I have made some corrections that you may want to keep, you may make more. This code compiles and runs well.
Program test
implicit none
integer N
real(8), allocatable :: A(:), A_done(:), P(:)
N=5
Allocate (A(N), A_done(N), P(N))
A=(/5,3,6,1,9/)
call sort(A, A_done, N, P)
Write (*,*) A_done
End
subroutine sort(A,A_done,N,P)
! Sort a real array by algebraically increasing value and return the permutation that
! rearranges the array
implicit none
Integer N, K, L
real(8), dimension(N) :: A, A_done, P
real(8) :: TEMP1, TEMP2
DO K=1, N-1
DO L=K+1, N
if (A(K)>A(L)) then
TEMP1=A(K)
TEMP2=P(K)
A(K)=A(L)
P(K)=P(L)
A(L)=TEMP1
P(L)=TEMP2
end if
END DO
END DO
A_done=A
RETURN
END

How to get a pointer value in Haskell?

I wish to manipulate data on a very low level.
Therefore I have a function that receives a virtual memory address as an integer and "does stuff" with this memory address. I interfaced this function from C, so it has the type (CUInt -> a).
The memory I want to link is a Word8 in a file. Sadly, I have no idea how to access the pointer value to that Word8.
To be clear, I do not need the value of the Word8, i need the value to the virtual memory address, which is the value of the pointer to it.
For the sake of a simple example, say you want to add an offset to the pointer.
Front matter:
module Main where
import Control.Monad (forM_)
import Data.Char (chr)
import Data.Word (Word8)
import Foreign.ForeignPtr (ForeignPtr, withForeignPtr)
import Foreign.Ptr (Ptr, plusPtr)
import Foreign.Storable (peek)
import System.IO.MMap (Mode(ReadOnly), mmapFileForeignPtr)
Yes, you wrote that you don't want the value of the Word8, but I've retrieved it with peek to demonstrate that the pointer is valid. You might be tempted to return the Ptr from inside withForeignPtr, but the documentation warns against that:
Note that it is not safe to return the pointer from the action and use it after the action completes. All uses of the pointer should be inside the withForeignPtr bracket. The reason for this unsafeness is the same as for unsafeForeignPtrToPtr below: the finalizer may run earlier than expected, because the compiler can only track usage of the ForeignPtr object, not a Ptr object made from it.
The code is straightforward:
doStuff :: ForeignPtr Word8 -> Int -> IO ()
doStuff fp i =
withForeignPtr fp $ \p -> do
let addr = p `plusPtr` i
val <- peek addr :: IO Word8
print (addr, val, chr $ fromIntegral val)
To approximate “a Word8 in a File” from your question, the main program memory-maps a file and uses that buffer to do stuff with memory addresses.
main :: IO ()
main = do
(p,offset,size) <- mmapFileForeignPtr path mode range
forM_ [0 .. size-1] $ \i -> do
doStuff p (offset + i)
where
path = "/tmp/input.dat"
mode = ReadOnly
range = Nothing
-- range = Just (4,3)
Output:
(0x00007f1b40edd000,71,'G')
(0x00007f1b40edd001,117,'u')
(0x00007f1b40edd002,116,'t')
(0x00007f1b40edd003,101,'e')
(0x00007f1b40edd004,110,'n')
(0x00007f1b40edd005,32,' ')
(0x00007f1b40edd006,77,'M')
(0x00007f1b40edd007,111,'o')
(0x00007f1b40edd008,114,'r')
(0x00007f1b40edd009,103,'g')
(0x00007f1b40edd00a,101,'e')
(0x00007f1b40edd00b,110,'n')
(0x00007f1b40edd00c,33,'!')
(0x00007f1b40edd00d,10,'\n')
You are probably looking for ptrToIntPtr and probably fromIntegral to make it a CUInt.
Note that a CUInt cannot represent a pointer on all platforms, though.

Resources