Code Monkey home page Code Monkey logo

ompeval's People

Contributors

etale-cohomology avatar zekyll avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ompeval's Issues

how RANKS magic number are choosen?

In HandEvaluator.cpp defined the following:
const unsigned HandEvaluator::RANKS[]{0x2000, 0x8001, 0x11000, 0x3a000, 0x91000, 0x176005, 0x366000, 0x41a013, 0x47802e, 0x479068, 0x48c0e4, 0x48f211, 0x494493};
I can not find how to generate these numbers.
In SKPokerEval, the is a python script to generate these numbers. brutal force way. If these number were generated the similar way, why RANKS not begin with 0x1, 0x5, ......, but begins with 0x1 << 13.
Who can explain this to me?

Max 9 players support

Is it possible to have a 9 players support? I'm currently not sure why but I get a segmentation fault when I just change the constant from 6 to 9 here. Any further pointers would be appreciated! Thanks!

accessing combos during eval

Sorry if this is a simple question but I'm new to using C++, but I was wondering if there was a way to access which combo is being evaluated from each player during eval so I can pass ranges that are weighted probability distributions. Thanks for the code, you've done some amazing work.

Cheers

short deck support

Hello, I want to support short deck mode in OMP, i.e., remove 2-5, flush > full house, and A6789 is the smallest straight. Do I need to change the hash table, and how is HandEvaluator::RANKS[] defined? Is there a simple modification method?

How to benchmark against 3rd party evals?

I see in benchmark.cpp:

void benchmark()
{
    // Benchmark only one at a time because there's some weird performance interference.
    Benchmark<Omp>().run();
    //Benchmark<Skpe>().run();
    //Benchmark<Tpt>().run();
    //Benchmark<Ace>().run();
    //Benchmark<Sbhs>().run();
    //Benchmark<Pse>().run();
}

I would like to benchmark the others too so I can compare them. But I am not sure how to do that.

Could someone explain the steps that would allow me to uncomment one and successfully compile it?

Best way to create precalculated equity table for heads-up TH

Thanks for great evaluator and calculator!

I want to create precalculated equity table for heads-up game for every board and every hand. I am just iterating all boards and all hands and save the results. That looks ineffective. Some strange things I have notices:

  1. Monte_carlo is slower then fool enumeration
  2. Fool enumeration uses only 20% of CPU. It is more effective to set thread count to one and do OMP parallel loop
  3. Most time is spent in - CombinedRange::joinRanges 28.67% and CardRange::CardRange - 30.55%. I don't know code base but looks like unnecessary combos preprocessing. Unnecessary because I am only passing hands. not ranges.
    Would be appreciated for any ideas how to simply optimize this and accomplish my task?

Symbol lookup error

Hi, would you happen to have an example for how to compile the .so file? I'm including all the libraries and when I run the example in Java I get "symbol lookup error: /usr/lib/libompdelta.so: undefined symbol: _ZN3omp13CombinedRangeC1Ev"

I've tried including all of the .o files but get the same. This is what I run:
g++ -std=c++11 -I$JAVA_HOME/include -I$JAVA_HOME/include/linux -I./omp -I./ ompdelta.cpp -o libompdelta.so -Llib/ompeval.a -Lomp/*.o -shared -fPIC

Hand representation

I claim the following.

There's no such thing as a Card class; there's only a Hand class, which can be initialized in one of three ways:

  1. The trivial way Hand();
  2. With an unsigned integer between 0 and 51, eg. Hand(20);
  3. With an array of two such integers.

Then single cards can be added to and removed from a Hand object at will with the + and - operators.

First question. Is my claim correct?


Assuming SSE support, a Hand is a 128-bit vector of type __m128i, made up of two 64-bit integers, whose structure is roughly as the comments in Hand.h read:

// Bits 0-31: key to non-flush lookup table (linear combination of the rank constants)
// Bits 32-47: suit counts
// Bits 48-51: card count
// Bits 64-128: bit mask for all cards (suits are in 16-bit groups).

(I think there's an off-by-one error in the last line, which should read Bits 64-127)

I've added a public method to the Hand class to print out its vector of data, called mData, to the console, as follows:

void show(){
    int64_t *v64val = (int64_t*) &mData;
    printf("%.16llx %.16llx\n", (uint64)v64val[1], (uint64)v64val[0]);
}

When initializing each hand Hand(0), Hand(0), ..., Hand(51), I get the following output:

0001000100000001 0000000000000001
0001001000000001 0000000000010000
0001010000000001 0000000100000000
0001100000000001 0001000000000000
0001000100000005 0000000000000002
0001001000000005 0000000000020000
0001010000000005 0000000200000000
0001100000000005 0002000000000000
0001000100000018 0000000000000004
0001001000000018 0000000000040000
0001010000000018 0000000400000000
0001100000000018 0004000000000000
0001000100000070 0000000000000008
0001001000000070 0000000000080000
0001010000000070 0000000800000000
0001100000000070 0008000000000000
0001000100000209 0000000000000010
0001001000000209 0000000000100000
0001010000000209 0000001000000000
0001100000000209 0010000000000000
00010001000008c7 0000000000000020
00010010000008c7 0000000000200000
00010100000008c7 0000002000000000
00011000000008c7 0020000000000000
000100010000241c 0000000000000040
000100100000241c 0000000000400000
000101000000241c 0000004000000000
000110000000241c 0040000000000000
0001000100007867 0000000000000080
0001001000007867 0000000000800000
0001010000007867 0000008000000000
0001100000007867 0080000000000000
000100010001929a 0000000000000100
000100100001929a 0000000001000000
000101000001929a 0000010000000000
000110000001929a 0100000000000000
000100010003d12a 0000000000000200
000100100003d12a 0000000002000000
000101000003d12a 0000020000000000
000110000003d12a 0200000000000000
00010001000a2f3d 0000000000000400
00010010000a2f3d 0000000004000000
00010100000a2f3d 0000040000000000
00011000000a2f3d 0400000000000000
0001000100174a57 0000000000000800
0001001000174a57 0000000008000000
0001010000174a57 0000080000000000
0001100000174a57 0800000000000000
000100010034b250 0000000000001000
000100100034b250 0000000010000000
000101000034b250 0000100000000000
000110000034b250 1000000000000000

Second question. Is this correct?

error "Resource temporarily unavailable" when calculating hand by hand

Starting with two ranges, I want to calculate a matrix of hand equities, with individual hand-vs-hand values.

I do this simply in a double loop and constructing a length-2 vector of CardRange's, using 1 thread for each evaluation, like this :

for(h1 in range1){
   for(h2 in range2){
       ...
       std::vector<omp::CardRange> hands{h1, h2};

        eq.start(hands, board, 0, true, 5e-5, nullptr, 0.2, 1);
        eq.wait();
        auto r = eq.getResults();
   }
}

When running this on Linux, I sometimes get a runtime error

terminate called after throwing an instance of 'std::system_error'
what(): Resource temporarily unavailable

Which I assume has something to do with resource acquisition for the threads, although I don't understand how this happens considering I'm starting only 1 thread per caluclation and waiting for each to finish. Is it perhaps a more direct way to do hand-vs-hand evaluations without using the threading functionality?

Combo Counting

Hi,

Awesome library. Thanks very much. Is there a way to output combos for a range and a board, say count two pair+, flush combos, flush draw combos, etc.?

Why Hands doesn't use enumerations

// Create a Hand from a card. CardIdx is an integer between 0 and 51, so that CARD = 4 * RANK + SUIT, where
// rank ranges from 0 (deuce) to 12 (ace) and suit is from 0 (spade) to 3 (diamond).

Ok, I could create enums by my own, but which order?
spade = 0,
hearts,
clubs,
diamonds

or

spade = 0,
clubs,
hearts,
diamonds

Wrong eval result in specific order of evaluations(?)

I get a wrong result returned in the following sequence of evaluations.

(i) Start up a fresh instance of EquityCalculator.
(ii) Calc a 3-handed game, ranges { "AA", "QQ", "AKo" } empty board and no dead cards.
Correct results are returned:
Eq win ties
0.761347, 0.756022, 0.005324
0.187420, 0.186052, 0.001367
0.051233, 0.045909, 0.005324

(iii) now still with the same EquityCalculator instance Calc a 3-handed game, ranges { "AA", "QQ", "AKo" } empty board but now with dead cards (AsTs).
Incorrect results are returned:
0.748711, 0.743139, 0.005572
0.198669, 0.197299, 0.001370
0.052620, 0.047048, 0.005572

I expected this result (verified using Pokerstove):
Eq win ties
0.734955, 0.728980, 0.005975
0.210303, 0.208843, 0.001460
0.054743, 0.048768, 0.005975

===========================

Oddly if I perform some calculations in a different order it always seems to works eg,.
range { "AA", "QQ", "AKo" } dead (AsTs)
then
range { "AA", "QQ", "AKo" } dead ()
then
range { "AA", "QQ", "AKo" } dead (AsTs)
All 3 calculations return the expected results.

I haven't previously ever noticed an incorrect result from this and it seems to happen only with this sequence of evaluations, weird. Perhaps it is just my set up or some slip by me.
I have tried using both a 32 bit and 64 bit version.

Support of hands weights in range

Hi

Is it possible to set weights for hands in a range just like in PioSolver ?
ex: JTo:0.2 , you have JTo in your range only 20% of the time

If not, is it possible to implement it quite easily based on how the project was developed ?

Regards

popcnt

What should I do if the processor does not support the POPCNT instruction and an error (0xC000001D: Illegal Instruction) appears in Util.h >> bitCount (unsigned x) >> return __popcnt (x)?

from Hands to CardRange

hello i am trying to evaluate equity for for a hands ie AcAd in holdem heads-up.

this code seem to works fine:

omp::EquityCalculator eq;
eq.start({"AcAd","random"},0,0,true,5e-5,nullptr,0.2,4);

But now i would like to use the AcAd hands as their numerical representation (4*Ranks+Suit) for "AcAd" it is [12,13]

how can i instantiate a CardRange from a Hand or an array of int ?

Coding help

Hi I am trying to write a code similar to an evaluator which will look up hands in a csv and group them. Would you be interested in helping me? I would pay of course. If interested, please email me [email protected]

How to compile on OSX?

Trying to compile this on OSX by just typing make, but getting the following:

$ make
c++ -O3 -std=c++11 -Wall -Wpedantic -pthread   -c -o omp/CombinedRange.o omp/CombinedRange.cpp
omp/CombinedRange.cpp:21:47: warning: suggest braces around initialization of subobject [-Wmissing-braces]
        Combo c{1ull << h[0] | 1ull << h[1], {h}, {Hand(h)}};
                                              ^
                                              {}
In file included from omp/CombinedRange.cpp:1:
In file included from omp/CombinedRange.h:4:
In file included from omp/HandEvaluator.h:6:
In file included from omp/Hand.h:6:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/array:109:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/algorithm:2950:57: error: constexpr variable '_Rp'
      must be initialized by a constant expression
    static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min()
                                                        ^     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/algorithm:3123:41: note: in instantiation of
      template class 'std::__1::__independent_bits_engine<omp::XoroShiro128Plus, unsigned long long>' requested here
        return static_cast<result_type>(_Eng(__g, _Dt)());
                                        ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/algorithm:3298:35: note: in instantiation of
      function template specialization 'std::__1::uniform_int_distribution<long>::operator()<omp::XoroShiro128Plus>' requested here
            difference_type __i = __uid(__g, _Pp(0, __d));
                                  ^
omp/CombinedRange.cpp:101:10: note: in instantiation of function template specialization
      'std::__1::shuffle<std::__1::__wrap_iter<omp::CombinedRange::Combo *>, omp::XoroShiro128Plus &>' requested here
    std::shuffle(mCombos.begin(), mCombos.end(), rng);
         ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/algorithm:2950:63: note: non-constexpr function
      'max' cannot be used in a constant expression
    static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min()
                                                              ^
omp/Random.h:37:21: note: declared here
    static uint64_t max()
                    ^
In file included from omp/CombinedRange.cpp:1:
In file included from omp/CombinedRange.h:4:
In file included from omp/HandEvaluator.h:6:
In file included from omp/Hand.h:6:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/array:109:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/algorithm:2953:78: error: non-type template
      argument is not a constant expression
    static _LIBCPP_CONSTEXPR const size_t __m = __log2<_Working_result_type, _Rp>::value;
                                                                             ^~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/algorithm:2953:78: note: initializer of '_Rp' is
      not a constant expression
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/algorithm:2950:57: note: declared here
    static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min()
                                                        ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/algorithm:2962:69: error: non-type template
      argument is not a constant expression
    result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());}
                                                                    ^~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/algorithm:3131:15: note: in instantiation of
      member function 'std::__1::__independent_bits_engine<omp::XoroShiro128Plus, unsigned long long>::operator()' requested here
        __u = __e();
              ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/algorithm:3298:35: note: in instantiation of
      function template specialization 'std::__1::uniform_int_distribution<long>::operator()<omp::XoroShiro128Plus>' requested here
            difference_type __i = __uid(__g, _Pp(0, __d));
                                  ^
omp/CombinedRange.cpp:101:10: note: in instantiation of function template specialization
      'std::__1::shuffle<std::__1::__wrap_iter<omp::CombinedRange::Combo *>, omp::XoroShiro128Plus &>' requested here
    std::shuffle(mCombos.begin(), mCombos.end(), rng);
         ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/algorithm:2962:69: note: initializer of '_Rp' is
      not a constant expression
    result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());}
                                                                    ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/algorithm:2950:57: note: declared here
    static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min()


1 warning and 3 errors generated.
make: *** [omp/CombinedRange.o] Error 1

Using the following version of c++:

$ c++ -v
Apple LLVM version 9.1.0 (clang-902.0.39.2)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

Sorry if this is obvious!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.