29
29
//! each move.
30
30
31
31
#![ allow( internal_features) ]
32
- #![ allow( unsafe_op_in_unsafe_fn) ]
33
32
#![ feature( avx512_target_feature) ]
34
33
#![ cfg_attr( target_arch = "x86" , feature( stdarch_x86_avx512, stdarch_internal) ) ]
35
34
#![ cfg_attr( target_arch = "x86_64" , feature( stdarch_x86_avx512, stdarch_internal) ) ]
@@ -419,12 +418,12 @@ fn pos_is_draw(pos: &Pos) -> bool {
419
418
found && !pos_is_winner ( pos)
420
419
}
421
420
422
- #[ target_feature( enable = "avx512f,avx512bw" ) ]
421
+ #[ target_feature( enable = "avx512f,avx512bw,popcnt " ) ]
423
422
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
424
- unsafe fn pos_is_draw_avx512 ( pos : & Pos ) -> bool {
423
+ fn pos_is_draw_avx512 ( pos : & Pos ) -> bool {
425
424
let empty = Color :: Empty as usize ;
426
425
427
- let board0org = _mm512_loadu_epi32 ( & pos. bitboard [ empty] [ 0 ] [ 0 ] ) ;
426
+ let board0org = unsafe { _mm512_loadu_epi32 ( & pos. bitboard [ empty] [ 0 ] [ 0 ] ) } ;
428
427
429
428
let answer = _mm512_set1_epi32 ( 0 ) ;
430
429
@@ -481,7 +480,7 @@ fn search(pos: &Pos, alpha: i32, beta: i32, depth: i32, _ply: i32) -> i32 {
481
480
482
481
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
483
482
{
484
- if is_x86_feature_detected ! ( "avx512bw" ) {
483
+ if check_x86_avx512_features ( ) {
485
484
unsafe {
486
485
if pos_is_winner_avx512 ( pos) {
487
486
return -EVAL_INF + _ply;
@@ -571,7 +570,7 @@ fn eval(pos: &Pos, _ply: i32) -> i32 {
571
570
// check if opp has live4 which will win playing next move
572
571
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
573
572
{
574
- if is_x86_feature_detected ! ( "avx512bw" ) {
573
+ if check_x86_avx512_features ( ) {
575
574
unsafe {
576
575
if check_patternlive4_avx512 ( pos, def) {
577
576
return -4096 ;
@@ -594,7 +593,7 @@ fn eval(pos: &Pos, _ply: i32) -> i32 {
594
593
// check if self has live4 which will win playing next move
595
594
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
596
595
{
597
- if is_x86_feature_detected ! ( "avx512bw" ) {
596
+ if check_x86_avx512_features ( ) {
598
597
unsafe {
599
598
if check_patternlive4_avx512 ( pos, atk) {
600
599
return 2560 ;
@@ -617,7 +616,7 @@ fn eval(pos: &Pos, _ply: i32) -> i32 {
617
616
// check if self has dead4 which will win playing next move
618
617
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
619
618
{
620
- if is_x86_feature_detected ! ( "avx512bw" ) {
619
+ if check_x86_avx512_features ( ) {
621
620
unsafe {
622
621
if check_patterndead4_avx512 ( pos, atk) > 0 {
623
622
return 2560 ;
@@ -639,7 +638,7 @@ fn eval(pos: &Pos, _ply: i32) -> i32 {
639
638
640
639
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
641
640
{
642
- if is_x86_feature_detected ! ( "avx512bw" ) {
641
+ if check_x86_avx512_features ( ) {
643
642
unsafe {
644
643
let n_c4: i32 = check_patterndead4_avx512 ( pos, def) ;
645
644
let n_c3: i32 = check_patternlive3_avx512 ( pos, def) ;
@@ -854,16 +853,18 @@ fn check_patternlive3(pos: &Pos, sd: Side) -> i32 {
854
853
n
855
854
}
856
855
857
- #[ target_feature( enable = "avx512f,avx512bw" ) ]
856
+ #[ target_feature( enable = "avx512f,avx512bw,popcnt " ) ]
858
857
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
859
- unsafe fn pos_is_winner_avx512 ( pos : & Pos ) -> bool {
858
+ fn pos_is_winner_avx512 ( pos : & Pos ) -> bool {
860
859
let current_side = side_opp ( pos. p_turn ) ;
861
860
let coloridx = current_side as usize ;
862
861
863
- let board0org: [ __m512i ; 2 ] = [
864
- _mm512_loadu_epi32 ( & pos. bitboard [ coloridx] [ 0 ] [ 0 ] ) ,
865
- _mm512_loadu_epi32 ( & pos. bitboard [ coloridx] [ 1 ] [ 0 ] ) ,
866
- ] ; // load states from bitboard
862
+ let board0org: [ __m512i ; 2 ] = unsafe {
863
+ [
864
+ _mm512_loadu_epi32 ( & pos. bitboard [ coloridx] [ 0 ] [ 0 ] ) ,
865
+ _mm512_loadu_epi32 ( & pos. bitboard [ coloridx] [ 1 ] [ 0 ] ) ,
866
+ ]
867
+ } ; // load states from bitboard
867
868
868
869
#[ rustfmt:: skip]
869
870
let answer = _mm512_set1_epi16 ( ( 1 <<15 ) |( 1 <<14 ) |( 1 <<13 ) |( 1 <<12 ) |( 1 <<11 ) ) ; // an unbroken chain of five moves
@@ -928,9 +929,9 @@ unsafe fn pos_is_winner_avx512(pos: &Pos) -> bool {
928
929
count_match > 0
929
930
}
930
931
931
- #[ target_feature( enable = "avx512f,avx512bw" ) ]
932
+ #[ target_feature( enable = "avx512f,avx512bw,popcnt " ) ]
932
933
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
933
- unsafe fn check_patternlive4_avx512 ( pos : & Pos , sd : Side ) -> bool {
934
+ fn check_patternlive4_avx512 ( pos : & Pos , sd : Side ) -> bool {
934
935
let coloridx = sd as usize ;
935
936
let emptyidx = Color :: Empty as usize ;
936
937
@@ -952,14 +953,18 @@ unsafe fn check_patternlive4_avx512(pos: &Pos, sd: Side) -> bool {
952
953
0b00_10_10_11_11_11_11_11_10_10_10_10_10_11_11_10 ,
953
954
0b00_10_10_10_11_11_11_10_10_10_10_10_11_11_11_10 ,
954
955
0b00_10_10_10_10_11_10_10_10_10_10_11_11_11_11_10 ] ;
955
- let board0org: [ __m512i ; 2 ] = [
956
- _mm512_loadu_epi32 ( & pos. bitboard [ coloridx] [ 0 ] [ 0 ] ) ,
957
- _mm512_loadu_epi32 ( & pos. bitboard [ coloridx] [ 1 ] [ 0 ] ) ,
958
- ] ;
959
- let board1org: [ __m512i ; 2 ] = [
960
- _mm512_loadu_epi32 ( & pos. bitboard [ emptyidx] [ 0 ] [ 0 ] ) ,
961
- _mm512_loadu_epi32 ( & pos. bitboard [ emptyidx] [ 1 ] [ 0 ] ) ,
962
- ] ;
956
+ let board0org: [ __m512i ; 2 ] = unsafe {
957
+ [
958
+ _mm512_loadu_epi32 ( & pos. bitboard [ coloridx] [ 0 ] [ 0 ] ) ,
959
+ _mm512_loadu_epi32 ( & pos. bitboard [ coloridx] [ 1 ] [ 0 ] ) ,
960
+ ]
961
+ } ;
962
+ let board1org: [ __m512i ; 2 ] = unsafe {
963
+ [
964
+ _mm512_loadu_epi32 ( & pos. bitboard [ emptyidx] [ 0 ] [ 0 ] ) ,
965
+ _mm512_loadu_epi32 ( & pos. bitboard [ emptyidx] [ 1 ] [ 0 ] ) ,
966
+ ]
967
+ } ;
963
968
964
969
let mut count_match: i32 = 0 ;
965
970
@@ -990,9 +995,9 @@ unsafe fn check_patternlive4_avx512(pos: &Pos, sd: Side) -> bool {
990
995
count_match > 0
991
996
}
992
997
993
- #[ target_feature( enable = "avx512f,avx512bw" ) ]
998
+ #[ target_feature( enable = "avx512f,avx512bw,popcnt " ) ]
994
999
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
995
- unsafe fn check_patterndead4_avx512 ( pos : & Pos , sd : Side ) -> i32 {
1000
+ fn check_patterndead4_avx512 ( pos : & Pos , sd : Side ) -> i32 {
996
1001
let coloridx = sd as usize ;
997
1002
let emptyidx = Color :: Empty as usize ;
998
1003
@@ -1023,14 +1028,18 @@ unsafe fn check_patterndead4_avx512(pos: &Pos, sd: Side) -> i32 {
1023
1028
0b00_10_10_11_11_11_11_11_10_10_10_10_11_11_11_10 ,
1024
1029
0b00_10_10_10_11_11_11_10_10_10_10_11_11_11_11_10 ,
1025
1030
0b00_10_10_10_10_11_10_10_10_10_11_11_11_11_11_10 ] ;
1026
- let board0org: [ __m512i ; 2 ] = [
1027
- _mm512_loadu_epi32 ( & pos. bitboard [ coloridx] [ 0 ] [ 0 ] ) ,
1028
- _mm512_loadu_epi32 ( & pos. bitboard [ coloridx] [ 1 ] [ 0 ] ) ,
1029
- ] ;
1030
- let board1org: [ __m512i ; 2 ] = [
1031
- _mm512_loadu_epi32 ( & pos. bitboard [ emptyidx] [ 0 ] [ 0 ] ) ,
1032
- _mm512_loadu_epi32 ( & pos. bitboard [ emptyidx] [ 1 ] [ 0 ] ) ,
1033
- ] ;
1031
+ let board0org: [ __m512i ; 2 ] = unsafe {
1032
+ [
1033
+ _mm512_loadu_epi32 ( & pos. bitboard [ coloridx] [ 0 ] [ 0 ] ) ,
1034
+ _mm512_loadu_epi32 ( & pos. bitboard [ coloridx] [ 1 ] [ 0 ] ) ,
1035
+ ]
1036
+ } ;
1037
+ let board1org: [ __m512i ; 2 ] = unsafe {
1038
+ [
1039
+ _mm512_loadu_epi32 ( & pos. bitboard [ emptyidx] [ 0 ] [ 0 ] ) ,
1040
+ _mm512_loadu_epi32 ( & pos. bitboard [ emptyidx] [ 1 ] [ 0 ] ) ,
1041
+ ]
1042
+ } ;
1034
1043
1035
1044
let mut count_match: i32 = 0 ;
1036
1045
@@ -1063,16 +1072,16 @@ unsafe fn check_patterndead4_avx512(pos: &Pos, sd: Side) -> i32 {
1063
1072
count_match
1064
1073
}
1065
1074
1066
- #[ target_feature( enable = "avx512f,avx512bw" ) ]
1075
+ #[ target_feature( enable = "avx512f,avx512bw,popcnt " ) ]
1067
1076
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
1068
- unsafe fn check_patternlive3_avx512 ( pos : & Pos , sd : Side ) -> i32 {
1077
+ fn check_patternlive3_avx512 ( pos : & Pos , sd : Side ) -> i32 {
1069
1078
let coloridx = sd as usize ;
1070
1079
let emptyidx = Color :: Empty as usize ;
1071
1080
1072
1081
#[ rustfmt:: skip]
1073
- let board0org: [ __m512i ; 2 ] = [ _mm512_loadu_epi32 ( & pos. bitboard [ coloridx] [ 0 ] [ 0 ] ) , _mm512_loadu_epi32 ( & pos. bitboard [ coloridx] [ 1 ] [ 0 ] ) ] ;
1082
+ let board0org: [ __m512i ; 2 ] = unsafe { [ _mm512_loadu_epi32 ( & pos. bitboard [ coloridx] [ 0 ] [ 0 ] ) , _mm512_loadu_epi32 ( & pos. bitboard [ coloridx] [ 1 ] [ 0 ] ) ] } ;
1074
1083
#[ rustfmt:: skip]
1075
- let board1org: [ __m512i ; 2 ] = [ _mm512_loadu_epi32 ( & pos. bitboard [ emptyidx] [ 0 ] [ 0 ] ) , _mm512_loadu_epi32 ( & pos. bitboard [ emptyidx] [ 1 ] [ 0 ] ) ] ;
1084
+ let board1org: [ __m512i ; 2 ] = unsafe { [ _mm512_loadu_epi32 ( & pos. bitboard [ emptyidx] [ 0 ] [ 0 ] ) , _mm512_loadu_epi32 ( & pos. bitboard [ emptyidx] [ 1 ] [ 0 ] ) ] } ;
1076
1085
1077
1086
#[ rustfmt:: skip]
1078
1087
let answer_color: [ __m512i ; 1 ] = [ _mm512_set1_epi16 ( ( 1 <<14 ) |( 1 <<13 ) |( 1 <<12 ) ) ] ;
@@ -1170,10 +1179,15 @@ unsafe fn check_patternlive3_avx512(pos: &Pos, sd: Side) -> i32 {
1170
1179
count_match
1171
1180
}
1172
1181
1182
+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
1183
+ fn check_x86_avx512_features ( ) -> bool {
1184
+ is_x86_feature_detected ! ( "avx512bw" ) && is_x86_feature_detected ! ( "popcnt" )
1185
+ }
1186
+
1173
1187
fn main ( ) {
1174
1188
#[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
1175
1189
{
1176
- if is_x86_feature_detected ! ( "avx512bw" ) {
1190
+ if check_x86_avx512_features ( ) {
1177
1191
println ! ( "\n \n The program is running with avx512f and avx512bw intrinsics\n \n " ) ;
1178
1192
} else {
1179
1193
println ! ( "\n \n The program is running with NO intrinsics.\n \n " ) ;
0 commit comments