Bonjour,
J'écris ma question en anglais vu que je me trouve plus à l'aise avec cette langue. (C'est la première discussion que j'ouvre sur ce site).
I wrote this small code in order to adapt it to my main code and to use the `fork/wait` method to execute tasks stored in an `array` of 16 tasks (`defined type` : `function pointer` pointing to the subroutine to execute + `integer` for the state of the task).
As you can see here (if I understood well..), we have one child process executing the computations and the parent process waiting and printing some stuff.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38 ! fork.f90 program main use :: unix implicit none integer :: i, pid, STATUS,any_child integer :: sum=0,product=5 pid = c_fork() if (pid < 0) then ! Fork failed. call perror('fork()' // c_null_char) else if (pid == 0) then print '(a)', '>>> child process running ...' do i = 1, 3 ! Sleep for 1 second. print '(">>> step ", i0, " ...")', i sum=sum+1 product=product*2 open(1, file = 'variables.dat') write(1,*) sum,product close(1) end do print '(a)', '>>> child process done.' call exit(STATUS) else ! Parent process. print*,'habibi' any_child=c_wait(STATUS) print*,'ya nour 3in' open(2,file='variables.dat') read(2,*) sum,product close(2) print*,'The sum is equal to : ',sum print*,'The product is equal to : ',product end if end program main
The problem I encountred is that the values of "sum" and "product" printed by the parent process aren't correct. For the sum, I get 0 as a value as if the computations done by the child process didn't even happen.
I thought about writing the values computed by the child process in a file which will be read by the parent process. And it works ! But in order to adapt this to my code, I need to take many things into consideration :
First, I spawned 16 child processes not only 1.
Second, I have more than 15 variables not only 2 (sum and product).
Finally, each child process will read and write in the file which makes the program very very very slow especially with 16 child processes.
I'll show you a part of my code:
As you can see, I wrote and read multiple variables.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 number_children=16 do ff =5,number_children+4 if (tasks_ready_master(ff)%state==STATE_READY) then tasks_ready_master(ff)%state=STATE_RUNNING pid=c_fork() !< spawn a child process if (pid < 0) then call perror('fork()' // c_null_char) !< Error else if (pid == 0) then !< Child process call tasks_ready_master(ff)%f_ptr(self,var) !< execute the task open(1, file = 'variables.dat') write(1,*) var%pas_t write(1,*) var%cpt_t write(1,*) var%cpt1_t write(1,*) var%nb_element_t write(1,*) var%ww_t write(1,*) var%dt_t write(1,*) var%dx_t write(1,*) var%p_element_t write(1,*) var%u_prime_t write(1,*) var%u_prime_moins_t write(1,*) var%u_prime_plus_t write(1,*) var%taux_t write(1,*) var%grad_x_u_t write(1,*) var%grad_t_u_t write(1,*) var%grad_t_f_t write(1,*) var%grad_x_f_t write(1,*) var%flux_t write(1,*) var%sm_t write(1,*) var%ax_plus_t write(1,*) var%ax_moins_t write(1,*) var%ux_moins_t write(1,*) var%ux_plus_t write(1,*) var%tab0_t write(1,*) var%tab_t close(1) tasks_ready_master(ff)%state=STATE_INACTIVE call exit(STATUS) else any_child=c_wait(STATUS) !< wait for the child process if (any_child<0) then stop 'error' !< Error end if end if open(2,file='variables.dat') read(2,*) var%pas_t read(2,*) var%cpt_t read(2,*) var%cpt1_t read(2,*) var%nb_element_t read(2,*) var%ww_t read(2,*) var%dt_t read(2,*) var%dx_t read(2,*) var%p_element_t read(2,*) var%u_prime_t read(2,*) var%u_prime_moins_t read(2,*) var%u_prime_plus_t read(2,*) var%taux_t read(2,*) var%grad_x_u_t read(2,*) var%grad_t_u_t read(2,*) var%grad_t_f_t read(2,*) var%grad_x_f_t read(2,*) var%flux_t read(2,*) var%sm_t read(2,*) var%ax_plus_t read(2,*) var%ax_moins_t read(2,*) var%ux_moins_t read(2,*) var%ux_plus_t read(2,*) var%tab0_t read(2,*) var%tab_t close(2) end if end do end if
In order to understand what var is, here is its declaration:
with:
Code : Sélectionner tout - Visualiser dans une fenêtre à part type(variables)::var !< the variables
Simply, it stores all the variables I need in my computations and in the execution of the tasks.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 type::variables INTEGER,pointer::pas_t,cpt_t,cpt1_t,nb_element_t,ww_t real(kind=REAL64),pointer :: dt_t,dx_t integer ,dimension(:),pointer::p_element_t real(kind=REAL64), dimension(:),pointer ::u_prime_t,u_prime_moins_t, u_prime_plus_t,taux_t,grad_x_u_t,& &grad_t_u_t,grad_t_f_t,grad_x_f_t,flux_t,sm_t real(kind=REAL64),dimension(:),pointer:: ax_plus_t,ax_moins_t,ux_moins_t,ux_plus_t real(kind=REAL64),dimension(:,:),pointer::tab0_t,tab_t end type variables
Is the small code efficient ? I want to avoid using pipe.
What should I do in this case? How can I avoid my program getting very slow? Should I parellize using OpenMP ? I want to mention that only one thread execute the part of code I showed before.
Partager