0

I have the following code:

PROGRAM PEU72
USE PRIMES
IMPLICIT NONE
INTEGER, PARAMETER :: MYKIND = SELECTED_INT_KIND(16)
INTEGER (KIND=MYKIND) :: SOFAR
INTEGER :: NRP, M

SOFAR = 0_MYKIND

CALL GEN(ALLNUMS,ALLPRIMES) ! This is a call to a module that creates a list of primes. It works fine.

DO M = 2,8  ! When I try to compile in G95, this loop doesn't increment. M = 2 for each cycle.
  SOFAR = SOFAR + NRP(M)
END DO

PRINT *,'ANS: ',SOFAR
READ *,SOFAR

END PROGRAM PEU72

FUNCTION NRP(NUM) RESULT(PHI)
USE PRIMES
IMPLICIT NONE
INTEGER :: NUM, PHI, I!, DIF
INTEGER :: VAR
I = 1
PHI = NUM-1
VAR = NUM
DO
  IF (MOD(NUM,ALLPRIMES(I))==0) THEN
    PHI = PHI-((NUM-1)/ALLPRIMES(I))
    NUM = NUM/ALLPRIMES(I) ! This is the line that silverfrost doesn't like. The code works absolutely fine without it, it just takes too long.
  END IF
  I = I + 1
  VAR = NUM-ALLPRIMES(I)
  IF (VAR<0) THEN
    EXIT
  END IF
END DO
RETURN
END FUNCTION

For optimisation purposes, I want to divide num, a criteria for the while loop, every iteration. My (silverfrost) compiler throws an error (Active DO loop altered) when I do this, and the G95 compiler breaks completely, not iterating the first loop at all. I've tried using DO - IF - EXIT terminology, none of it works. How can I achieve a situation where Num is divided every time, and Allprimes(i) is incremented?

9
  • I'm not sure if it is convenient in a sense of efficiency (considering vectorization and compiler optimization), but this smells like recursion to me Commented Sep 9, 2018 at 0:07
  • 2
    I'm not really understanding this - could you also post the function that falls over on Silverfrost and g95? Commented Sep 9, 2018 at 4:04
  • 1
    Please post a minimal reproducible example Commented Sep 9, 2018 at 9:56
  • 2
    Many illegal programs run and give correct answers. Most of the time ... and then once they suddenly don't. en.wikipedia.org/wiki/Undefined_behavior Commented Sep 9, 2018 at 12:50
  • 4
    It is invalid Fortran for exactly the reason the Silverfrost compiler complains about: with the statement NUM = NUM/ALLPRIMES(I) there is an attempt to modify the loop variable m (as the actual argument associated with num) inside the loop. This is not allowed. Commented Sep 9, 2018 at 13:01

2 Answers 2

3

In the line

NUM = NUM/ALLPRIMES(I) you are altering NUM which enters NRP as argument. The call of NRP gives it as M so actually you are changing M.

Fortran passes the arguments by default by reference. (and by mid air collision of @francescalus comment: "there is an attempt to modify the loop variable m (as the actual argument associated with num) inside the loop. This is not allowed.").

So you have to alter your for loop or redefine NUM in your routine all depending on the problem.

Sign up to request clarification or add additional context in comments.

Comments

2

I suggest you an alternative approach (same logic but standard compliant), for the cases in which it is convenient to manipulate the loop counter:

M = 2
DO WHILE(M <= 8)
  SOFAR = SOFAR + NRP(M)
  M = M + 1 ! if you need to increment the index
END DO

Edit:

How to alter a fortran program index variable in a while loop?

Reading the title of the question again, I think this is not alternative, but a literal answer.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.