Ejemplo n.º 1
0
    def bf_piece_sum_eval(compressed_pieces_filters, relevant_piece_masks):
        squares_per_mask = popcount(relevant_piece_masks)

        decompressed_pieces = decompress_squares(compressed_pieces_filters, np.sum(squares_per_mask))
        cur_piece_values = piece_filter_values[decompressed_pieces]

        split_indices = np.r_[0,np.cumsum(squares_per_mask, dtype=np.int32)]

        to_return = np.array([np.sum(cur_piece_values[s:e]) for s, e in zip(split_indices[:-1], split_indices[1:])])
        return to_return
Ejemplo n.º 2
0
 def filter(board, move):
     if popcount(board.occupied) <= n:
         return True
     return False
Ejemplo n.º 3
0
def parse_into_ann_input_inference(max_boards, convert_to_nhwc=False):
    """
    NOTES:
    1) If a constant/operation is typed in a confusing manor, it's so the entirely of this can be done on GPU
    """
    possible_lookup_nums = np.arange(2 ** 16, dtype=np.uint16)
    num_bits = popcount(possible_lookup_nums.astype(np.uint64))

    location_lookup_ary = np.array([[[chess.square_rank(loc), chess.square_file(loc)] for loc in chess.SQUARES_180]], np.int32)
    location_lookup_ary = np.ones([max_boards, 1, 1], np.int32) * location_lookup_ary

    location_lookup_ary = location_lookup_ary.reshape([max_boards, 8, 8, 2])[:, ::-1]
    location_lookup_ary = location_lookup_ary.reshape([max_boards, 4, 16, 2])

    mask_getter = lambda n: np.unpackbits(np.frombuffer(n, dtype=np.uint8)[::-1])[::-1]
    masks_to_gather_ary = np.array(list(map(mask_getter, possible_lookup_nums)), dtype=np.bool_)

    pieces_from_nums = lambda n: [n >> 4, (n & np.uint8(0x0F))]
    piece_lookup_ary = np.array(list(map(pieces_from_nums, possible_lookup_nums)), dtype=np.int32)

    range_repeater = numpy_style_repeat_1d_creator(max_multiple=33, max_to_repeat=max_boards, out_type=tf.int64)

    popcount_lookup = tf.constant(num_bits, tf.int64)
    locations_for_masking = tf.constant(location_lookup_ary, tf.int64)
    occupancy_mask_table = tf.constant(masks_to_gather_ary, tf.half)
    piece_lookup_table = tf.constant(piece_lookup_ary, tf.int64)

    ones_to_slice = tf.constant(np.ones(33 * max_boards), dtype=tf.float32)  # This is used since there seems to be no simple/efficient way to broadcast for scatter_nd

    piece_indicators = tf.placeholder(tf.int32, shape=[None], name="piece_filters")  #Given as an array of uint8s
    occupied_bbs = tf.placeholder(tf.int64, shape=[None], name="occupied_bbs")       #Given as an array of uint64s

    # The code below this comment defines ops which are run during inference

    occupied_bitcasted = tf.cast(tf.bitcast(occupied_bbs, tf.uint16), dtype=tf.int32)

    partial_popcounts = tf.gather(popcount_lookup, occupied_bitcasted, "byte_popcount_loopkup")
    partial_popcounts = tf.cast(partial_popcounts, tf.int32)
    occupied_popcounts = tf.reduce_sum(partial_popcounts, axis=-1, name="popcount_lookup_sum")

    location_mask = tf.gather(occupancy_mask_table, occupied_bitcasted, "gather_location_mask")
    location_mask = tf.cast(location_mask, tf.bool)
    piece_coords = tf.boolean_mask(locations_for_masking, location_mask, "mask_desired_locations")

    gathered_pieces = tf.gather(piece_lookup_table, piece_indicators, "gather_pieces")
    piece_filter_indices = tf.reshape(gathered_pieces, [-1, 1])

    repeated_board_numbers = range_repeater(occupied_popcounts)
    board_numbers_for_concat = tf.expand_dims(repeated_board_numbers, -1)

    # Removes either the last piece filter, or no filters (based on if the number of filters was odd and half of the final uint8 was padding)
    piece_filter_indices = piece_filter_indices[:tf.shape(board_numbers_for_concat)[0]]

    one_indices = tf.concat([board_numbers_for_concat, piece_filter_indices, piece_coords], axis=-1) #Should figure out how this can be done with (or similarly to) tf.parallel_stack

    boards = tf.scatter_nd(
        indices=one_indices,
        updates=ones_to_slice[:tf.shape(one_indices)[0]],
        shape=[tf.shape(occupied_bbs, out_type=tf.int64)[0], 15, 8, 8])

    if convert_to_nhwc:
        boards = tf.transpose(boards, [0,2,3,1])

    return (piece_indicators, occupied_bbs), boards