Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arpack random generator cannot be seeded #218

Open
pv opened this issue Jul 7, 2019 · 9 comments
Open

Arpack random generator cannot be seeded #218

pv opened this issue Jul 7, 2019 · 9 comments

Comments

@pv
Copy link
Contributor

pv commented Jul 7, 2019

Expected behavior

It would nice to be able to set the random seed of Arpack's internal random number generator, for cases where more strict fp reproducibility is aimed at (needs of course also compiler and library support to be complete). There could be a new subroutine call in the API that sets it.

Actual behavior

Currently, the rng seeding is done on the first call to each of *getv0.f routines,

arpack-ng/SRC/dgetv0.f

Lines 202 to 208 in c43cb86

if (inits) then
iseed(1) = 1
iseed(2) = 3
iseed(3) = 5
iseed(4) = 7
inits = .false.
end if

Specifying an initial vector is not sufficient, since new random vectors are sometimes needed along the run,

call dgetv0 (ido, bmat, itry, .false., n, j, v, ldv,

Where/how to reproduce the problem

  • arpack-ng: as of 2019-07
@fghoussen
Copy link
Collaborator

You may propose a PR. If so, think about also providing / updating iso_c_ binding API.

@fghoussen
Copy link
Collaborator

BTW, not sure to get the pb right. Seeds are fixed: so generated random numbers should be the same if you provide the same initial vector, no ?

@pv
Copy link
Contributor Author

pv commented Jul 22, 2019

The seed is initialized only the first time *getv0 is called in a process (save variables), so you'll get different results every time you invoke arpack in the same process. This means e.g. that libraries that use arpack cannot control the randomness, since they don't control the whole-program execution.

@fghoussen
Copy link
Collaborator

OK, I can try to PR something about that.
So you need something to reset seed at every iteration of the RCI-while loop, right ?

@pv
Copy link
Contributor Author

pv commented Jul 22, 2019

I have a branch here: master...pv:rng-seed
It should retain the old behavior exactly by default, but I did not yet get around to testing it in real world.

@pv
Copy link
Contributor Author

pv commented Jul 22, 2019

By the way, are the iso_c_bindings as they currently are done in arpack-ng correct for the logical type? Adding the interface declaration the compiler complains that logical(kind=c_bool) and logical are not compatible types, and indeed false seems to behave incorrectly if no conversion is done and interface is omitted?

@fghoussen
Copy link
Collaborator

I have a branch here: master...pv:rng-seed

Looks a bit fuzzy (many impacts) and incomplete (missing all p*getv0.f). Tried to PR some fix : not tested, @pv could you test if this behaves like you need ? (debug/stat common have already been initialized. I realized that, here, it is about save... Which may not behave exactly like common). If this works, this should cover all cases.

By the way, are the iso_c_bindings as they currently are done in arpack-ng correct for the logical type?

I believe yes. ICB is mainly "typing variables". Not sure how/when mixing ICB and interface is safe. Fortran is an every day pain (personal opinion)... So I avoid to play near border lines (but you may be right, this may be possible to mix them)

@pv
Copy link
Contributor Author

pv commented Jul 23, 2019

The current #223 won't do it --- save variables are local to each routine, so there are four different RNG states. Wanting to preserve backward compatibility with that is what necessitates the complexity, so I guess you'd necessarily converge to a similar solution; common blocks could simplify it, though.

PARPACK is more complicated and a similar seeding approach may not be appropriate there -- needs more thinking (and not sure I have the time), so it's not done.

For the other issue, to state it more clearly: the current icb definitions look wrong --- on my platform (gfortran), logical(kind=c_bool) appears to be logical(1) whereas logical becomes logical(4), so the calling convention goes wrong without interface declarations / variable conversions. You can e.g. follow execution of icb_test_c in debugger inside dseupd_c, and notice the value of rvec is not correctly passed. (Or check it adding print statements; most clearly seen changing rvec=false in icb_test_c.c and trying to print rvec at beginning of dseupd.f.)

@fghoussen
Copy link
Collaborator

Can't afford more time on this. Hope somebody can.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants