2929//! each move.
3030
3131#![ allow( internal_features) ]
32- #![ allow( unsafe_op_in_unsafe_fn) ]
3332#![ feature( avx512_target_feature) ]
3433#![ cfg_attr( target_arch = "x86" , feature( stdarch_x86_avx512, stdarch_internal) ) ]
3534#![ cfg_attr( target_arch = "x86_64" , feature( stdarch_x86_avx512, stdarch_internal) ) ]
@@ -419,12 +418,12 @@ fn pos_is_draw(pos: &Pos) -> bool {
419418 found && !pos_is_winner ( pos)
420419}
421420
422- #[ target_feature( enable = "avx512f,avx512bw" ) ]
421+ #[ target_feature( enable = "avx512f,avx512bw,popcnt " ) ]
423422#[ 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 {
425424 let empty = Color :: Empty as usize ;
426425
427- let board0org = _mm512_loadu_epi32 ( & pos. bitboard [ empty] [ 0 ] [ 0 ] ) ;
426+ let board0org = unsafe { _mm512_loadu_epi32 ( & pos. bitboard [ empty] [ 0 ] [ 0 ] ) } ;
428427
429428 let answer = _mm512_set1_epi32 ( 0 ) ;
430429
@@ -481,7 +480,7 @@ fn search(pos: &Pos, alpha: i32, beta: i32, depth: i32, _ply: i32) -> i32 {
481480
482481 #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
483482 {
484- if is_x86_feature_detected ! ( "avx512bw" ) {
483+ if check_x86_avx512_features ( ) {
485484 unsafe {
486485 if pos_is_winner_avx512 ( pos) {
487486 return -EVAL_INF + _ply;
@@ -571,7 +570,7 @@ fn eval(pos: &Pos, _ply: i32) -> i32 {
571570 // check if opp has live4 which will win playing next move
572571 #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
573572 {
574- if is_x86_feature_detected ! ( "avx512bw" ) {
573+ if check_x86_avx512_features ( ) {
575574 unsafe {
576575 if check_patternlive4_avx512 ( pos, def) {
577576 return -4096 ;
@@ -594,7 +593,7 @@ fn eval(pos: &Pos, _ply: i32) -> i32 {
594593 // check if self has live4 which will win playing next move
595594 #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
596595 {
597- if is_x86_feature_detected ! ( "avx512bw" ) {
596+ if check_x86_avx512_features ( ) {
598597 unsafe {
599598 if check_patternlive4_avx512 ( pos, atk) {
600599 return 2560 ;
@@ -617,7 +616,7 @@ fn eval(pos: &Pos, _ply: i32) -> i32 {
617616 // check if self has dead4 which will win playing next move
618617 #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
619618 {
620- if is_x86_feature_detected ! ( "avx512bw" ) {
619+ if check_x86_avx512_features ( ) {
621620 unsafe {
622621 if check_patterndead4_avx512 ( pos, atk) > 0 {
623622 return 2560 ;
@@ -639,7 +638,7 @@ fn eval(pos: &Pos, _ply: i32) -> i32 {
639638
640639 #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
641640 {
642- if is_x86_feature_detected ! ( "avx512bw" ) {
641+ if check_x86_avx512_features ( ) {
643642 unsafe {
644643 let n_c4: i32 = check_patterndead4_avx512 ( pos, def) ;
645644 let n_c3: i32 = check_patternlive3_avx512 ( pos, def) ;
@@ -854,16 +853,18 @@ fn check_patternlive3(pos: &Pos, sd: Side) -> i32 {
854853 n
855854}
856855
857- #[ target_feature( enable = "avx512f,avx512bw" ) ]
856+ #[ target_feature( enable = "avx512f,avx512bw,popcnt " ) ]
858857#[ 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 {
860859 let current_side = side_opp ( pos. p_turn ) ;
861860 let coloridx = current_side as usize ;
862861
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
867868
868869 #[ rustfmt:: skip]
869870 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 {
928929 count_match > 0
929930}
930931
931- #[ target_feature( enable = "avx512f,avx512bw" ) ]
932+ #[ target_feature( enable = "avx512f,avx512bw,popcnt " ) ]
932933#[ 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 {
934935 let coloridx = sd as usize ;
935936 let emptyidx = Color :: Empty as usize ;
936937
@@ -952,14 +953,18 @@ unsafe fn check_patternlive4_avx512(pos: &Pos, sd: Side) -> bool {
952953 0b00_10_10_11_11_11_11_11_10_10_10_10_10_11_11_10 ,
953954 0b00_10_10_10_11_11_11_10_10_10_10_10_11_11_11_10 ,
954955 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+ } ;
963968
964969 let mut count_match: i32 = 0 ;
965970
@@ -990,9 +995,9 @@ unsafe fn check_patternlive4_avx512(pos: &Pos, sd: Side) -> bool {
990995 count_match > 0
991996}
992997
993- #[ target_feature( enable = "avx512f,avx512bw" ) ]
998+ #[ target_feature( enable = "avx512f,avx512bw,popcnt " ) ]
994999#[ 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 {
9961001 let coloridx = sd as usize ;
9971002 let emptyidx = Color :: Empty as usize ;
9981003
@@ -1023,14 +1028,18 @@ unsafe fn check_patterndead4_avx512(pos: &Pos, sd: Side) -> i32 {
10231028 0b00_10_10_11_11_11_11_11_10_10_10_10_11_11_11_10 ,
10241029 0b00_10_10_10_11_11_11_10_10_10_10_11_11_11_11_10 ,
10251030 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+ } ;
10341043
10351044 let mut count_match: i32 = 0 ;
10361045
@@ -1063,16 +1072,16 @@ unsafe fn check_patterndead4_avx512(pos: &Pos, sd: Side) -> i32 {
10631072 count_match
10641073}
10651074
1066- #[ target_feature( enable = "avx512f,avx512bw" ) ]
1075+ #[ target_feature( enable = "avx512f,avx512bw,popcnt " ) ]
10671076#[ 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 {
10691078 let coloridx = sd as usize ;
10701079 let emptyidx = Color :: Empty as usize ;
10711080
10721081 #[ 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 ] ) ] } ;
10741083 #[ 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 ] ) ] } ;
10761085
10771086 #[ rustfmt:: skip]
10781087 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 {
11701179 count_match
11711180}
11721181
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+
11731187fn main ( ) {
11741188 #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
11751189 {
1176- if is_x86_feature_detected ! ( "avx512bw" ) {
1190+ if check_x86_avx512_features ( ) {
11771191 println ! ( "\n \n The program is running with avx512f and avx512bw intrinsics\n \n " ) ;
11781192 } else {
11791193 println ! ( "\n \n The program is running with NO intrinsics.\n \n " ) ;
0 commit comments