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

Issue: "System.IndexOutOfRangeException: Index was outside the bounds of the array." #1

Open
JamesLear92 opened this issue Oct 28, 2021 · 3 comments

Comments

@JamesLear92
Copy link

JamesLear92 commented Oct 28, 2021

Hi, really interested in this project, but I've hit some weird problems.
The public static method "GetEntry" in TtUtil.cs almost immediately crashes.
It's throwing an "Index was outside the bounds of the array" error.

As you can see below, "Index" is larger than than the static array from the get go
https://i.imgur.com/ssQJBnD.png
https://i.imgur.com/wi53Rdr.png

This is occurring while debugging with "Any CPU", on a 64x processor, compiling with .NET 5, with the following UCI commands:

setoption hash value 8192
setoption threads 8
isready
ucinewgame
position startpos moves d2d4
go wtime 122000 btime 120000 winc 2000 binc 2000

@JamesLear92
Copy link
Author

Seems the issue is with
"public static void Init(bool force)"

I'll raise a pull request

JamesLear92 added a commit to JamesLear92/Chess22kDotNet that referenced this issue Oct 28, 2021
Program suffered "Index outside of bounds of array" exception. The original Java version had a "* 2" at the end while setting the variable "maxEntries".
I have added this in, and it resolves issue: respel#1
@JamesLear92
Copy link
Author

Mmm, this double memory usage though which is not good. Perhaps the keyshift needs to be 1 more to bring the index into a reasonable range.
Like:

    public static void Init(bool force)
    {
        if (!force && _isInitialized) return;
        _keyShifts = 64 - EngineConstants.Power2TtEntries + 1;
        var maxEntries = (int)(Util.PowerLookup[EngineConstants.Power2TtEntries] + BucketSize - 1);
        _entries = new TtEntry[maxEntries];
        _isInitialized = true;
    }

@JamesLear92
Copy link
Author

JamesLear92 commented Oct 29, 2021

Interestingly the original chess22k seems to also have this problem which is why it's max entries is twice as large as it should be.
When the Zobrist key is negative, GetIndex will return a number greater than the size of _entries. I'm really not sure that I understand the idea behind

 (int) (key >>> keyShifts) << 1;

Because the first bit can be positive if the long is negative, keyShifts needs to be +1 more than it already is, but that's ok, easy to fix. The <<1 is really "odd" though, because it's making the first bit of the index 0, which means that every index is even. Surely that's increasing the chances that you'll have to go through your buckets to find a free spot in the hashtable. There should be a small performance increase from allowing both even & odd node indexes.

Two fixes would be to change the GetIndex method to:

 private static int GetIndex(long key) => (int) Util.RightTripleShift(key, _keyShifts + 1);

OR
In zobrist.cs changing the LongRandom method to:

private static long LongRandom(Random rand) => rand.NextInt64();

and deleting the GetIndex method, and just doing this in it's place:

var index = key >> _keyShifts;

This requires .NET 6 for the NextInt64 method, the advantage of this is that it's extremely fast, and it only returns positive longs, so there is no need for a triple shift because the first bit is always 0 anyway.

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

1 participant