3235 implicit none
3236 integer, intent(in)::inode_entry,ctr_entry
3237 integer, intent(inout)::istat
3238 integer::j,k,in,in1,ierr,son,nmb_procs_inode,nmb_sons_inode,
3239 & share,current,offset,
3240 & in_tmp,nfront,npiv,ncb,
3241 & keep48_loc,min_cand_needed
3242 integer, dimension(:), allocatable :: procs4son
3243 character (len=48):: subname
3244 DOUBLE PRECISION :: relative_weight,costs_sons, shtemp
3245 DOUBLE PRECISION :: costs_sons_real
3246 DOUBLE PRECISION :: PartofaProc
3247 LOGICAL :: SkipSmallNodes
3248 parameter(partofaproc=0.01d0)
3249 DOUBLE PRECISION :: loc_relax
3250 INTEGER :: depth
3251 logical force_cand
3252 integer MUMPS_REG_GETKMAX, MUMPS_BLOC2_GET_NSLAVESMIN
3253 external MUMPS_REG_GETKMAX, MUMPS_BLOC2_GET_NSLAVESMIN
3254 DOUBLE PRECISION Y
3255 integer nmb_propmap_strict,share2,procsrest,current2
3256 integer k69onid,nb_free_procs,local_son_indice,nb_procs_for_sons,
3257 & ptr_upper_ro_procs
3258 integer :: inode, ctr
3259 INTEGER :: allocok
3260 logical upper_round_off,are_sons_treated
3261 DOUBLE PRECISION tmp_cost
3262 inode = inode_entry
3263 ctr = ctr_entry
3264 1234 CONTINUE
3265 if (ctr.le.0) then
3266 istat = 0
3267 return
3268 endif
3269 istat= -1
3270 if(cv_frere(inode).eq.cv_n+1) return
3271 subname='PROPMAP'
3272 nmb_procs_inode = 0
3273 do j=1,cv_slavef
3275 & nmb_procs_inode = nmb_procs_inode + 1
3276 end do
3277 if(nmb_procs_inode.eq.0) then
3278 if(cv_lp.gt.0)
3279 & write(cv_lp,*)'Error in ',subname
3280 & ,subname
3281 return
3282 end if
3283 if ((cv_nodelayer(inode).eq.0).AND.
3284 & (cv_frere(inode).ne.cv_n+1)) then
3285 istat = 0
3286 return
3287 endif
3288 ptr_upper_ro_procs=1
3289 work_per_proc(1:cv_slavef)=0.0d0
3290 id_son(1:cv_slavef)=0
3291 nmb_sons_inode = 0
3292 costs_sons = dble(0)
3293 force_cand=(mod(cv_keep(24),2).eq.0)
3294 min_cand_needed=0
3295 in = inode
3296 do while (cv_fils(in).gt.0)
3297 in=cv_fils(in)
3298 end do
3299 if (cv_fils(in).eq.0) then
3300 istat = 0
3301 return
3302 endif
3303 in = -cv_fils(in)
3304 son=in
3305 do while(in.gt.0)
3306 nmb_sons_inode = nmb_sons_inode + 1
3307 if(cv_tcostw(in).le.0.0d0) then
3308 if(cv_lp.gt.0)
3309 & write(cv_lp,*)'Subtree costs for ',in,
3310 & ' should be positive in ',subname
3311 return
3312 endif
3313 if (cv_keep(67) .ne. 1) then
3314 costs_sons = costs_sons + cv_tcostw(in)
3315 else
3316 costs_sons = costs_sons + cv_tcostm(in)
3317 endif
3318 in=cv_frere(in)
3319 enddo
3320 IF (nmb_sons_inode.eq.1) THEN
3321 if(.NOT.associated(cv_prop_map(son)%ind_proc)) then
3323 if(ierr.ne.0) then
3324 if(cv_lp.gt.0)
3325 & write(cv_lp,*)'PROPMAP_INIT signalled error to'
3326 & ,subname
3327 istat = ierr
3328 goto 999
3329 end if
3330 endif
3331 ctr = ctr -1
3332 cv_prop_map(son)%ind_proc = cv_prop_map(inode)%ind_proc
3333 inode = son
3334 GOTO 1234
3335 ENDIF
3336 costs_sons_real = costs_sons
3337 skipsmallnodes = .true.
3338 IF (costs_sons_real.gt.0.0d0) then
3339 in = son
3340 do while (in.gt.0)
3341 if (cv_keep(67) .ne. 1) then
3342 relative_weight=cv_tcostw(in)/costs_sons_real
3343 else
3344 relative_weight=cv_tcostm(in)/costs_sons_real
3345 endif
3346 shtemp = relative_weight*dble(nmb_procs_inode)
3347 IF (shtemp.lt.partofaproc) THEN
3348 if (cv_keep(67) .ne. 1) then
3349 costs_sons = costs_sons - cv_tcostw(in)
3350 else
3351 costs_sons = costs_sons - cv_tcostm(in)
3352 endif
3353 ENDIF
3354 in=cv_frere(in)
3355 enddo
3356 IF (costs_sons.LT. partofaproc*costs_sons_real) THEN
3357 costs_sons = costs_sons_real
3358 skipsmallnodes = .false.
3359 ENDIF
3360 ENDIF
3361 if(costs_sons.le.0.0d0) then
3362 if(cv_lp.gt.0)
3363 & write(cv_lp,*)'Error in ',subname
3364 & ,subname
3365 return
3366 endif
3367 if(cv_relax.le.0.0d0) then
3368 if(cv_lp.gt.0)
3369 & write(cv_lp,*)'Error in ',subname,'. Wrong cv_relax'
3370 return
3371 endif
3372 ALLOCATE(procs4son(cv_size_ind_proc),stat=allocok)
3373 IF (allocok .GT. 0) THEN
3374 cv_info(1) = cv_error_memalloc
3375 cv_info(2) = cv_size_ind_proc
3376 istat = cv_error_memalloc
3377 if(cv_lp.gt.0)
3378 & write(cv_lp,*)
3379 & 'Memory allocation error in ',subname
3380 return
3381 ENDIF
3382 depth=
max(cv_n - ctr,0)
3383 if(cv_keep(24).eq.8) then
3384 loc_relax = cv_relax
3385 elseif ((cv_keep(24).eq.16).OR.(cv_keep(24).eq.18)) then
3386 loc_relax = cv_relax
3387 elseif (cv_keep(24).eq.10) then
3388 loc_relax = cv_relax
3389 elseif ((cv_keep(24).eq.12).OR.(cv_keep(24).eq.14)) then
3390 if(depth.ge.cv_mixed_strat_bound) then
3391 loc_relax = cv_relax
3392 else
3393 loc_relax = cv_relax +
3394 &
max(dble(cv_keep(77))/dble(100), dble(0))
3395 endif
3396 endif
3397 in=son
3398 current = 1
3399 local_son_indice=1
3400 nb_procs_for_sons=0
3401 upper_round_off=.false.
3402 are_sons_treated=.true.
3403 do while(in.gt.0)
3404 if( (nmb_sons_inode.ge.nmb_procs_inode).AND.
3405 & (nmb_procs_inode.LT.4) ) then
3406 procs4son = cv_prop_map(inode)%ind_proc
3407 are_sons_treated=.false.
3408 nb_procs_for_sons=nmb_procs_inode
3409 nmb_propmap_strict=nmb_procs_inode
3410 elseif(nmb_procs_inode .LE. cv_keep(83)) then
3411 procs4son = cv_prop_map(inode)%ind_proc
3412 are_sons_treated=.false.
3413 nb_procs_for_sons=nmb_procs_inode
3414 nmb_propmap_strict=nmb_procs_inode
3415 else
3416 do k=1,cv_size_ind_proc
3417 do j=0,cv_bitsize_of_int-1
3418 procs4son(k)=ibclr(procs4son(k),j)
3419 end do
3420 end do
3421 if(costs_sons.gt.0.0d0) then
3422 if (cv_keep(67) .ne. 1) then
3423 relative_weight=cv_tcostw(in)/costs_sons
3424 else
3425 relative_weight=cv_tcostm(in)/costs_sons
3426 endif
3427 else
3428 relative_weight=dble(0)
3429 endif
3430 shtemp = relative_weight*dble(nmb_procs_inode)
3431 IF ( (shtemp.LT.partofaproc)
3432 & .AND. ( skipsmallnodes ) ) THEN
3433 share = 1
3434 do j=current,cv_slavef
3435 if(ke69 .gt.1) then
3436 call mumps_get_idp1_proc(j-1,k69onid,ierr)
3437 else
3438 k69onid = j
3439 endif
3442 if(ierr.ne.0) then
3443 if(cv_lp.gt.0)write(cv_lp,*)
3444 & 'BIT_SET signalled error to',subname
3445 istat = ierr
3446 goto 999
3447 end if
3448 share = share -1
3449 exit
3450 endif
3451 enddo
3452 if (share.gt.0) then
3453 do j=1,current-1
3454 if(ke69 .gt.1) then
3455 call mumps_get_idp1_proc(j-1,k69onid,ierr)
3456 else
3457 k69onid = j
3458 endif
3461 if(ierr.ne.0) then
3462 if(cv_lp.gt.0)write(cv_lp,*)
3463 & 'BIT_SET signalled error to',subname
3464 istat = ierr
3465 goto 999
3466 end if
3467 share = share -1
3468 exit
3469 endif
3470 enddo
3471 endif
3472 if(share.ne.0) then
3473 if(cv_lp.gt.0) write(cv_lp,*)
3474 & 'Error reported in ',subname
3475 goto 999
3476 end if
3477 if(.NOT.associated(cv_prop_map(in)%ind_proc)) then
3479 if(ierr.ne.0) then
3480 if(cv_lp.gt.0)
3481 & write(cv_lp,*)'PROPMAP_INIT signalled error to'
3482 & ,subname
3483 istat = ierr
3484 goto 999
3485 end if
3486 endif
3487 current = j
3488 cv_prop_map(in)%ind_proc = procs4son
3489 in = cv_frere(in)
3490 cycle
3491 ENDIF
3492 share =
max(1,nint(shtemp))
3493 if (dble(share).ge.shtemp) then
3494 upper_round_off=.true.
3495 else
3496 upper_round_off = .false.
3497 endif
3498 share=
min(share,nmb_procs_inode)
3499 nmb_propmap_strict=share
3500 nb_procs_for_sons=nb_procs_for_sons+nmb_propmap_strict
3501 offset=1
3502 do j=current,cv_slavef
3503 if(ke69 .gt.1) then
3504 call mumps_get_idp1_proc(j-1,k69onid,ierr)
3505 else
3506 k69onid = j
3507 endif
3510 if(ierr.ne.0) then
3511 if(cv_lp.gt.0)write(cv_lp,*)
3512 & 'BIT_SET signalled error to',subname
3513 istat = ierr
3514 goto 999
3515 end if
3516 share = share-1
3517 if(share.le.0) then
3518 current = j + offset
3519 if(current.gt.cv_slavef) current = 1
3520 exit
3521 end if
3522 end if
3523 end do
3524 if(share.gt.0) then
3525 do j=1,current-1
3526 if(ke69 .gt.1) then
3527 call mumps_get_idp1_proc(j-1,k69onid,ierr)
3528 else
3529 k69onid = j
3530 endif
3533 if(ierr.ne.0) then
3534 if(cv_lp.gt.0)write(cv_lp,*)
3535 & 'BIT_SET signalled error to',subname
3536 istat = ierr
3537 goto 999
3538 end if
3539 share = share-1
3540 if(share.le.0) then
3541 current = j + offset
3542 if(current.gt.cv_slavef) current = 1
3543 exit
3544 end if
3545 end if
3546 end do
3547 endif
3548 if(share.ne.0) then
3549 if(cv_lp.gt.0) write(cv_lp,*)
3550 & 'Error reported in ',subname
3551 goto 999
3552 end if
3553 if(.not.upper_round_off)then
3554 if(local_son_indice.lt.cv_slavef)then
3555 id_son(local_son_indice)=in
3556 if ( cv_keep(67) .ne. 1 ) then
3557 work_per_proc(local_son_indice)=cv_tcostw(in)/
3558 & dble(nmb_propmap_strict)
3559 else
3560 work_per_proc(local_son_indice)=cv_tcostm(in)/
3561 & dble(nmb_propmap_strict)
3562 endif
3563 local_son_indice=local_son_indice+1
3564 if(local_son_indice.eq.cv_slavef)then
3565 CALL mumps_sort_msort(ierr,cv_slavef,id_son,
3566 & work_per_proc)
3567 if(ierr.ne.0) then
3568 if(cv_lp.gt.0)
3569 & write(cv_lp,*)
3570 & 'Error reported by MUMPS_SORT_MSORT in ',subname
3571 istat = ierr
3572 goto 999
3573 endif
3574 endif
3575 else
3576 current2=cv_slavef
3577 if (cv_keep(67) .ne.1) then
3578 tmp_cost=cv_tcostw(in)/dble(nmb_propmap_strict)
3579 else
3580 tmp_cost=cv_tcostm(in)/dble(nmb_propmap_strict)
3581 endif
3582 do while(current2.ge.1)
3583 if(tmp_cost.lt.work_per_proc(current2))exit
3584 current2=current2-1
3585 enddo
3586 if(current2.ne.cv_slavef)then
3587 if(current2.eq.0)then
3588 current2=1
3589 endif
3590 do j=cv_slavef-1,current2,-1
3591 id_son(j+1)=id_son(j)
3592 work_per_proc(j+1)=work_per_proc(j)
3593 enddo
3594 id_son(current2)=in
3595 work_per_proc(current2)=tmp_cost
3596 endif
3597 endif
3598 endif
3599 upper_round_off=.false.
3600 endif
3601 if(.NOT.associated(cv_prop_mapthen
3603 if(ierr.ne.0) then
3604 if(cv_lp.gt.0)
3605 & write(cv_lp,*)'PROPMAP_INIT signalled error to'
3606 & ,subname
3607 istat = ierr
3608 goto 999
3609 end if
3610 endif
3611 cv_prop_map(in)%ind_proc = procs4son
3612 in=cv_frere(in)
3613 end do
3614 if(are_sons_treated)then
3615 if(nb_procs_for_sons.ne.nmb_procs_inode)then
3616 do j=1,nmb_procs_inode-nb_procs_for_sons
3617 procs4son=cv_prop_map(id_son(j))%ind_proc
3618 do while(current.le.cv_slavef)
3619 if(ke69 .gt.1) then
3620 call mumps_get_idp1_proc(current-1,k69onid,ierr)
3621 else
3622 k69onid = current
3623 endif
3625 current=current+1
3626 else
3627 exit
3628 endif
3629 enddo
3631 cv_prop_map(id_son(j))%ind_proc=procs4son
3632 enddo
3633 ptr_upper_ro_procs=
min(j,nmb_procs_inode-nb_procs_for_sons)
3634 endif
3635 endif
3636 in=son
3637 current = 1
3638 do while(in.gt.0)
3639 if( (nmb_sons_inode.ge.nmb_procs_inode).AND.
3640 & (nmb_procs_inode.LT.4) ) then
3641 procs4son = cv_prop_map(inode)%ind_proc
3642 elseif(nmb_procs_inode .LE. cv_keep(83)) then
3643 procs4son = cv_prop_map(inode)%ind_proc
3644 else
3645 procs4son = cv_prop_map(in)%ind_proc
3646 in_tmp=in
3647 nfront=cv_nfsiz(in_tmp)
3648 npiv=0
3649 in_tmp=in_tmp
3650 do while(in_tmp.gt.0)
3651 if (cv_blkon) then
3652 npiv = npiv + cv_sizeofblocks(in_tmp)
3653 else
3654 npiv=npiv+1
3655 endif
3656 in_tmp=cv_fils(in_tmp)
3657 end do
3658 ncb=nfront-npiv
3659 if (force_cand) then
3660 if (cv_keep(50) == 0) then
3661 keep48_loc=0
3662 else
3663 keep48_loc=3
3664 endif
3665 if (cv_keep(48).EQ.5) keep48_loc = 5
3666 min_cand_needed=
3668 & (cv_slavef, keep48_loc,cv_keep8(21),
3669 & cv_keep(50),
3670 & nfront,ncb,
3671 & cv_keep(375), cv_keep(119))
3672 min_cand_needed=
min(cv_slavef,min_cand_needed+1)
3673 else
3674 min_cand_needed = 0
3675 endif
3676 min_cand_needed =
max(min_cand_needed, cv_keep(91))
3677 if(costs_sons.gt.0.0d0) then
3678 if (cv_keep(67) .ne.1) then
3679 relative_weight=cv_tcostw(in)/costs_sons
3680 else
3681 relative_weight=cv_tcostm(in)/costs_sons
3682 endif
3683 else
3684 relative_weight=dble(0)
3685 endif
3686 nmb_propmap_strict=0
3687 do k=1,cv_slavef
3689 nmb_propmap_strict=nmb_propmap_strict+1
3690 end if
3691 end do
3692 offset=1
3693 share2=
3694 &
max(0,nint(relative_weight*(loc_relax-dble(1))*
3695 & dble(nmb_procs_inode)))
3696 share2 =
max(share2, min_cand_needed -nmb_propmap_strict,
3697 & (cv_keep(83)/2) - nmb_propmap_strict)
3698 procsrest=nmb_procs_inode - nmb_propmap_strict
3699 share2=
min(share2,procsrest)
3700 share2 = 0
3701 CALL random_number(y)
3702 current2 =int(dble(y)*dble(procsrest))
3703 nb_free_procs=1
3704 do j=1,cv_slavef
3705 if(share2.le.0) exit
3706 if(ke69 .gt.1) then
3707 call mumps_get_idp1_proc(j-1,k69onid,ierr)
3708 else
3709 k69onid = j
3710 endif
3713 if(nb_free_procs.ge.current2)then
3715 if(ierr.ne.0) then
3716 if(cv_lp.gt.0)write(cv_lp,*)
3717 & 'BIT_SET signalled error to',subname
3718 istat = ierr
3719 goto 999
3720 end if
3721 share2 = share2 - 1
3722 endif
3723 nb_free_procs=nb_free_procs+1
3724 end if
3725 end do
3726 if(share2.gt.0) then
3727 do j=1,cv_slavef
3728 if(share2.le.0) exit
3729 if(ke69 .gt.1) then
3730 call mumps_get_idp1_proc(j-1,k69onid,ierr)
3731 else
3732 k69onid = j
3733 endif
3737 if(ierr.ne.0) then
3738 if(cv_lp.gt.0)write(cv_lp,*)
3739 & 'BIT_SET signalled error to',subname
3740 istat = ierr
3741 goto 999
3742 end if
3743 share2 = share2 - 1
3744 end if
3745 end do
3746 endif
3747 if(share2.ne.0) then
3748 if(cv_lp.gt.0) write(cv_lp,*)
3749 & 'Error reported in ',subname
3750 goto 999
3751 end if
3752 endif
3753 ierr=0
3754 in1=in
3755 cv_prop_map(in1)%ind_proc = procs4son
3756 IF (nmb_sons_inode.EQ.1) DEALLOCATE(procs4son)
3758 if(ierr.ne.0) then
3759 if(cv_lp.gt.0) write(cv_lp,*)
3760 & 'Error reported in ',subname
3761 istat=ierr
3762 goto 999
3763 endif
3764 in=cv_frere(in)
3765 end do
3766 istat = 0
3767 999 CONTINUE
3768 if (allocated(procs4son)) DEALLOCATE(procs4son)
3769 return