MPI master/slave code ending before completing all tasks - fortran

I am trying to run serial tasks in parallel using MPI. I had some very nice help from Sigismondo with this. However, I have run into an issue. When I run the following code, only 8 of the 16 tasks end up getting complete, one task completed per core. I am not sure why the master processor doesn't send another job after one of the slave processors completes a task. I was hoping to get some help. Everything else works perfectly fine though.
if(myid.eq.0) then
pending_tasks = 0
sent_tasks = 0
open(100,file="s2p_commands.txt")
do i=1,(numprocs-1)
read(100,'(A)') command
call MPI_SEND(command,200,MPI_CHAR,i,0,MPI_COMM_WORLD,ierr)
pending_tasks = pending_tasks + 1
sent_tasks = sent_tasks + 1
enddo
! all procs have one task to work on.
do
! wait for results - from any source
call MPI_RECV(result,200,MPI_CHAR,MPI_ANY_SOURCE,0,MPI_COMM_WORLD,istatus,ierr)
free_proc = istatus(MPI_SOURCE)
if (sent_tasks < nlines) then
read(100,'(A)') command
call MPI_SEND(command,200,MPI_CHAR,free_proc,0,MPI_COMM_WORLD,ierr)
sent_tasks = sent_tasks + 1
else
! all tasks sent, but wait all the results
pending_tasks = pending_tasks - 1
endif
#ifdef debug
write(6,*) "Processor ",myid," executes: ",trim(command)
#endif
if (pending_tasks == 0) EXIT
enddo
! in this point the master can send out the 'QUIT' command to all the slaves
else
do
call MPI_RECV(command,200,MPI_CHAR,0,0,MPI_COMM_WORLD,istatus,ierr)
! that's a suggestion for a clean exit policy - pseudocode, don't forget
if (command=='QUIT') EXIT
call MPI_SEND(result, 200,MPI_CHAR,0,0,MPI_COMM_WORLD,ierr)
enddo
endif
time2 = MPI_Wtime()
call system (trim(command))
time3 = MPI_Wtime()
write(6,*) "System call on myid=",myid," took ",time3-time2," seconds"
if(myid.eq.0) write(6,*) "Total time was ",time3-time1," seconds"
call MPI_FINALIZE(ierr)

Related

Fortran: reading file with unknown number of lines

I am trying to open an ASCII file with unknown number of lines (but fixed number of entries in each line - please see example file below). It goes to the end of the file, but fails after that.
Option 1: Using iostat statement: I get the same error when using either "Use, intrinsic :: iso_fortran_env, Only : iostat_end" or simply treating io as an integer.
Option 2: Using "end= .." option. This is what I have used earlier (F77).
Both approaches should work in principle, but neither does. Any help in fixing this will be greatly appreciated.
Thanks,
Pinaki.
Program:
!=======================================!
program read
!=======================================!
! Use, intrinsic :: iso_fortran_env, Only : iostat_end
implicit none
integer :: i,io,n
n=0
open(10,file='a.dat',status='old',action='read')
!=================================!
! option 1
!=================================!
do
read(10,*,iostat=io)
write(*,*)io
! if (io.eq.iostat_end) exit
if (io.ne.0) exit
n=n+1
write(*,*)'n=',n
enddo
!=================================!
!=================================!
! option 2
!=================================!
do 10 i=1,1000000
read(10,*,end=10)
n=n+1
write(*,*)n
10 continue
!================================!
close(10)
write(*,*)'n=',n
end program read
!======================!
Compiled using "gfortran --std=f2003 -o read.out read.f90"
Error message:
==============================================
dyld: lazy symbol binding failed: Symbol not found: ___emutls_get_address
Referenced from: /usr/local/opt/gcc/lib/gcc/11/libgfortran.5.dylib
Expected in: /usr/lib/libSystem.B.dylib
dyld: Symbol not found: ___emutls_get_address
Referenced from: /usr/local/opt/gcc/lib/gcc/11/libgfortran.5.dylib
Expected in: /usr/lib/libSystem.B.dylib
Program received signal SIGABRT: Process abort signal.
Backtrace for this error:
#0 0x105364f8e
#1 0x10536419d
#2 0x7fff6eed05fc zsh: abort ./read.out
=====================================================
File I am trying to read:
=====================================================
1 -1.1559859375 2.0399371094 0.1686166667 0.8242152778
2 -1.1618015625 2.1375250000 0.1765231481 0.8105046296
3 -1.1696710937 2.2325417969 0.1860513889 0.7936782407
1 -1.1730312500 2.3271382813 0.1975254630 0.7718773148
2 -1.1767945313 2.3942726563 0.2113162500 0.7446933333
3 -1.1694437500 2.4738000000 0.2281966667 0.7099266667
1 -1.1566140625 2.5312164063 0.2494466667 0.6636841667
2 -1.1293765625 2.5746707031 0.2747766667 0.6066154167
3 -1.0836390625 2.5938144531 0.3026616667 0.5403733333
1 -1.0380632812 2.5721433594 0.3302462121 0.4727159091
=======================================================================
I tested your code, the first option worked. Your second option would also work if you remove the label 10 from do 10 i=1,1000000 and add a end do right before 10 continue. You would also have to add a rewind(10) or close(10); open(10,file='a.dat',status='old',action='read') right before the second option's do loop. But more interestingly, this problem is very easy to solve in Fortran 2008 using the is_iostat_end() intrinsic function that checks for the end-of-file error code occurrence. Here is a modern implementation,
program read
implicit none
integer :: i, n, iostat, fileUnit
n = 0
open(newunit = fileUnit, file = 'a.dat', status = 'old', action = 'read')
do
read(fileUnit,*,iostat = iostat)
if (is_iostat_end(iostat)) exit
write(*,*) iostat
n = n + 1
write(*,*)'n = ', n
end do
close(fileUnit)
end program read
Compile and rune it with the following commands,
gfortran --std=f2008 -o read.out read.f90
./read.out
Even though the problem was trivial, you asked a very nice question by providing a full code, data files, a recipe to compile the code, and the errors encountered. It deserves an upvote.

Lua: How do you update a variable that's in an event?

The issue I'm running into is that my variable isn't updating after an event. Here is my code:
local Players = game:GetService("Players")
local intermission = 15 -- time in seconds
local AmountOfPlayers = #Players:GetPlayers() -- starts at zero
local minPlayers = 1
Players.PlayerAdded:Connect(function(Player) -- updates amount of players in server
AmountOfPlayers = AmountOfPlayers + 1
end)
Players.PlayerRemoving:Connect(function(Player) -- updates amount of players in server
AmountOfPlayers = AmountOfPlayers - 1
end)
Below, this if-statement is not running since AmountOfPlayers is not equal to minPlayers.
while intermission > 0 do
if AmountOfPlayers >= minPlayers then
print("SUCCESS")
end
end
I have a scope issue of the variable AmountOfPlayers. I'm not sure how to fix this, so any suggestions will be appreciated. Thank you for your help!
You forgot to add a wait() in your while loop. This is most likely what leads to the script crashing and not working. So it should look like:
while intermission > 0 do
wait()
if AmountOfPlayers >= minPlayers then
print("SUCCESS")
end
end
OR
If that isn't the problem, instead of making:
local AmountOfPlayers = #Players:GetPlayers()
Instead:
local AmountOfPlayers = Players:GetChildren()
And Remove the two functions.

How to fix "Segmentation fault" in fortran program

I wrote this program that reads daily gridded climate model data (6 variables) from a file and uses it in further calculations. When running the pgm for a relatively short period (e.g. 5 years) it works fine, but when I want to run it for the required 30 year period I get a "Segmentation fault".
System description: Lenovo Thinkpad with Core i7 vPro with Windows 10 Pro
Program run in Fedora (64-bit) inside Oracle VM VirtualBox
After commenting out everything and checking section-by-section I found that:
everything works fine for 30 years as long as it reads 4 variables only
as soon as the 5th or 6th variable is added, the problem creeps in
alternatively, I can run it with all 6 variables but then it only works for a shorter analysis period (e.g. 22 years)
So the problem might lie with:
the statement: recl=AX*AY*4 which I borrowed from another pgm, yet changing the 4 doesn't fix it
the system I'm running the pgm on
I have tried the "ulimit -s unlimited" command suggested elsewhere, but only get the response "cannot modify limit: Operation not permitted".
File = par_query.h
integer AX,AY,startyr,endyr,AT
character pperiod*9,GCM*4
parameter(AX=162,AY=162) ! dim of GCM array
parameter(startyr=1961,endyr=1990,AT=endyr-startyr+1,
& pperiod="1961_1990")
parameter(GCM='ukmo')
File = query.f
program query
!# A FORTRAN program that reads global climate model (GCM) data to
!# be used in further calculations
!# uses parameter file: par_query.h
!# compile as: gfortran -c -mcmodel=large query.f
!# gfortran query.o
!# then run: ./a.out
! Declarations ***************************************************
implicit none
include 'par_query.h' ! parameter file
integer :: i,j,k,m,n,nn,leapa,leapb,leapc,leapn,rec1,rec2,rec3,
& rec4,rec5,rec6
integer, dimension(12) :: mdays
real :: ydays,nyears
real, dimension(AX,AY,31,12,AT) :: tmax_d,tmin_d,rain_d,rhmax_d,
& rhmin_d,u10_d
character :: ipath*43,fname1*5,fname2*3,nname*14,yyear*4,mmonth*2,
& ext1*4
! Data statements and defining characters ************************
data mdays/31,28,31,30,31,30,31,31,30,31,30,31/ ! Days in month
ydays=365. ! Days in year
nyears=real(AT) ! Analysis period (in years)
ipath="/run/media/stephan/SS_Elements/CCAM_africa/" ! Path to
! input data directory
fname1="ccam_" ! Folder where data is located #1
fname2="_b/" ! Folder where data is located #2
nname="ccam_africa_b." ! Input filename (generic part)
ext1=".dat"
leapa=0
leapb=0
leapc=0
leapn=0
! Read daily data from GCM ***************************************
do n=startyr,endyr ! Start looping through years --------------
write(yyear,'(i4.4)')n
nn=n-startyr+1
! Test for leap years
leapa=mod(n,4)
leapb=mod(n,100)
leapc=mod(n,400)
if (leapa==0) then
if (leapb==0) then
if (leapc==0) then
leapn=1
else
leapn=0
endif
else
leapn=1
endif
else
leapn=0
endif
if (leapn==1) then
mdays(2)=29
ydays=366.
else
mdays(2)=28
ydays=365.
endif
do m=1,12 ! Start looping through months --------------------
write(mmonth,'(i2.2)')m
! Reading daily data from file
print*,"Reading data for ",n,mmonth
open(101,file=ipath//fname1//GCM//fname2//nname//GCM//"."//
& yyear//mmonth//ext1,access='direct',recl=AX*AY*4)
do k=1,mdays(m) ! Start looping through days --------------
rec1=(k-1)*6+1
rec2=(k-1)*6+2
rec3=(k-1)*6+3
rec4=(k-1)*6+4
rec5=(k-1)*6+5
rec6=(k-1)*6+6
read(101,rec=rec1)((tmax_d(i,j,k,m,nn),i=1,AX),j=1,AY)
read(101,rec=rec2)((tmin_d(i,j,k,m,nn),i=1,AX),j=1,AY)
read(101,rec=rec3)((rain_d(i,j,k,m,nn),i=1,AX),j=1,AY)
read(101,rec=rec4)((rhmax_d(i,j,k,m,nn),i=1,AX),j=1,AY)
read(101,rec=rec5)((rhmin_d(i,j,k,m,nn),i=1,AX),j=1,AY)
read(101,rec=rec6)((u10_d(i,j,k,m,nn),i=1,AX),j=1,AY)
enddo ! k-loop (days) ends --------------------------------
close(101)
enddo ! m-loop (months) ends --------------------------------
enddo ! n-loop (years) ends -----------------------------------
end program query

Omnet Tkenv run config for multiple parameters: executing only the first value of parameter

My ini code for the config is as:
[Config BR54MBPS1MS]
description = "at 54MBPS with SI 1ms for 1250 Bytes with all time interval"
repeat = 2
sim-time-limit = 1 min
**.scalar-recording = true
**.vector-recording = false
**.host1.udpApp[0].messageLength = 1250B
**.wlan*.bitrate = 54Mbps
**.host1.udpApp[*].sendInterval = ${interval = 100..1200 step 100} us
**.vector-recording = false
output-scalar-file = 54Mbps/${configname}54Mbps${interval}us.sca
and I want to run it for all given intervals from 100 us to 1200 us with a gap of 100 us (at 100, 200, 300 ... us) in omnet tkenv or gui. The only option I read for it is by run it through run configuration as:
The problem is that, it runs only for 100us successfully, generates the output sca file and terminates the process. I am not able to figure out the reason for not running the for the next send interval.
In order to run all combinations of sendInterval values you should write * (asterisk) in Run number field and select Command line interface. Multiple runs are not possible when Tcl/Tk user interface is selected.

Solve error: Fortran runtime error: Bad integer for item 0 in list input

I have recently changed my f90 editor to CodeBlocks for Mac OS X, and when I try to open a file located in the project folder to read the data, the next error message appears on screen when the code is run:
Fortran runtime error: Bad integer for item 0 in list input
I have introduced the same code I used to write in Windows 7 using the intel compiler for fortran and Visual Studio.
The code itself is:
subroutine read_input_data
use input_data
implicit none
integer i,j
open(UNIT=5, FILE='lifting_line_input_data.txt', STATUS='old', FORM='formatted', ACCESS='sequential')
read(5,*) C
read(5,*) U
read(5,*) alpha
read(5,*) rho
read(5,*) wake_length
read(5,*) wake_eps
read(5,*) n_chord
read(5,*) n_twist
if (n_chord .GE. n_twist ) then
i = n_chord
else
i = n_twist
end if
allocate(chord_twist(5,i))
do j = 1, i
read(5,*) chord_twist(:,j)
end do
close(5)
end subroutine read_input_data
Could you help me to solve this problem? Thank you very much.
PD. the data file is obtain from an Excel sheet saved as a .txt delimited by tabulations
! LIFTING-LINE WING
! Number of panels
6
! Free stream speed [m/s]
50
! Angle of attack [rad]
0.15
! Air density [kg/m^3]
1.225
! Wake length [m]
100
! Convergence parameter
0.01
! Number of data points given for the chord distribution
2
! Number of data points given for the twist distribution
2
! Y coord [m] ! X_LE [m] ! X_TE [m] ! Y coord [m] ! Twist [rad]
0 0 2 0 0
10 0 0.5 10 0.052359878
PD2. I have change the format of the .txt file to make it equal to the input files I had used in Visual Studio. Now the file is:
6 ! Number of panels
50 ! Free stream speed [m/s]
0.15 ! Angle of attack [rad]
1.225 ! Air density [kg/m^3]
100 ! Wake length [m]
0.01 ! Convergence parameter
2 ! Number of data points given for the chord distribution
2 ! Number of data points given for the twist distribution
0 0 2 0 0 ! Y coord [m] ! X_LE [m] ! X_TE [m] ! Y coord [m] !Twist [rad]
10 0 0.5 10 0.052359878
And now the error given at the terminal is that the file is not found. As I am a beginner in CodeBlocks, I will explain what I have done step by step because I do not find where I am wrong and I am starting to get desperate:
New Project -> Fortran application -> I indicate where I want to create the project file.
I remove the main.f95 file and I add the .f90 file with the code.
I write the code.
I save the .txt file in the same folder than all the files of the Project.
When I run the code it appears the error message of file not found.
The code is:
!************************************************
subroutine read_input_data
use input_data
implicit none
integer i,j
open(UNIT=10, FILE='lifting_line_wing_input.txt', STATUS='old', ACCESS='sequential')
read(10,*) C
read(10,*) U
read(10,*) alpha
read(10,*) rho
read(10,*) wake_length
read(10,*) wake_eps
read(10,*) n_chord
read(10,*) n_twist
if (n_chord .GE. n_twist ) then
i = n_chord
else
i = n_twist
end if
allocate(chord_twist(5,i))
do j = 1, i
read(10,*) chord_twist(:,j)
end do
close(10)
end subroutine read_input_data
!************************************************
Thank you very much for your time and help
This looks like your old system did something non-standard with exclamation marks on list-directed input.
Try reformatting your input data like
6 / number of panels
(the slash will terminate the READ).
i don't believe any fortran compiler ever automagically handled those comments.
If you want to read this file the way it is, one approach is to make each read handle the error, eg,
integer ios
ios = 1
do while(ios.ne.0)
read(unit,*,iostat=ios)c
end do
ios=1
do while(ios.ne.0)
read(unit,*,iostat=ios)u
end do
etc..
if its a one-off you could just edit the file and delete all the comments as well.