@@ -928,16 +928,20 @@ def initialize_all_tensors(self) -> None:
928928 # transferred to GPU each step via transfer_bookkeeping_to_gpu().
929929 # Layout matches ContextGPUView._buf so a single cudaMemcpyAsync
930930 # suffices. Int64 token fields come first (8-byte aligned automatically),
931- # then int32 token fields, then int32 request-staging fields.
932- # token_to_input_ids (int64, max_tokens)
933- # token_to_pos_ids (int64, max_tokens)
934- # token_to_block_idx (int32, max_tokens)
935- # token_to_local_position_within_kv_block (int32, max_tokens)
936- # token_to_request_idx (int32, max_tokens)
937- # token_to_position_in_request (int32, max_tokens)
938- # request_in_prefill_status (staging) (int32, max_requests)
939- # request_query_lengths (staging) (int32, max_requests)
940- # request_kv_length_offsets (staging) (int32, max_requests)
931+ # then int32 token fields, then int32/float32 request-staging fields.
932+ # token_to_input_ids (int64, max_tokens)
933+ # token_to_pos_ids (int64, max_tokens)
934+ # token_to_block_idx (int32, max_tokens)
935+ # token_to_local_position_within_kv_block (int32, max_tokens)
936+ # token_to_request_idx (int32, max_tokens)
937+ # token_to_position_in_request (int32, max_tokens)
938+ # request_in_prefill_status (staging) (int32, max_requests)
939+ # request_query_lengths (staging) (int32, max_requests)
940+ # request_kv_length_offsets (staging) (int32, max_requests)
941+ # temperature (staging) (float32, max_requests)
942+ # top_k (staging) (int32, max_requests)
943+ # top_p (staging) (float32, max_requests)
944+ # active_request_last_token_idxs (alias) (int32, max_requests)
941945 #
942946 # Token fields are aliased with the source-of-truth attributes
943947 # (`self.token_to_input_ids`, etc.) because the forward pass reads
@@ -948,7 +952,8 @@ def initialize_all_tensors(self) -> None:
948952 # slice from the persistent `request_*` tensors above.
949953 _tok_int64_bytes = self .max_tokens * 8
950954 _tok_int32_bytes = self .max_tokens * 4
951- _req_int32_bytes = self .max_requests * 4
955+ # Request-level fields are all 4 bytes wide (5 int32 + 2 float32 = 7 fields).
956+ _req_4byte_bytes = self .max_requests * 4
952957 # MHA section: 5 fields (int32) shared between GraphedMHAMetadata and
953958 # NonGraphedMHAMetadata. max_bs == max_requests.
954959 _mha_query_lengths_bytes = self .max_requests * 4
@@ -983,7 +988,7 @@ def initialize_all_tensors(self) -> None:
983988 _total_bytes = (
984989 2 * _tok_int64_bytes
985990 + 4 * _tok_int32_bytes
986- + 3 * _req_int32_bytes
991+ + 7 * _req_4byte_bytes
987992 + _mha_query_lengths_bytes
988993 + _mha_cu_query_seq_lengths_bytes
989994 + _mha_kv_seq_lengths_bytes
@@ -1043,19 +1048,40 @@ def initialize_all_tensors(self) -> None:
10431048 # CPU (refreshed from persistent tensors in transfer_bookkeeping_to_gpu);
10441049 # read-only on GPU via matching slots in ContextGPUView._buf.
10451050 self ._staging_request_in_prefill_status = self ._cpu_bookkeeping_buf [
1046- _off : _off + _req_int32_bytes
1051+ _off : _off + _req_4byte_bytes
10471052 ].view (torch .int32 )
1048- _off += _req_int32_bytes
1053+ _off += _req_4byte_bytes
10491054 self ._staging_request_query_lengths = self ._cpu_bookkeeping_buf [
1050- _off : _off + _req_int32_bytes
1055+ _off : _off + _req_4byte_bytes
10511056 ].view (torch .int32 )
1052- _off += _req_int32_bytes
1057+ _off += _req_4byte_bytes
10531058 self ._staging_request_kv_length_offsets = self ._cpu_bookkeeping_buf [
1054- _off : _off + _req_int32_bytes
1059+ _off : _off + _req_4byte_bytes
10551060 ].view (torch .int32 )
1056- _off += _req_int32_bytes
1061+ _off += _req_4byte_bytes
10571062
1058- self .active_request_last_token_idxs = torch .empty_like (self .request_query_lengths )
1063+ # Sampling-parameter staging slots, refreshed from `active_request_metadata`
1064+ # in transfer_bookkeeping_to_gpu(). FlashInfer reads these via
1065+ # `gpu_view.{temperature, top_k, top_p}`.
1066+ self ._staging_temperature = self ._cpu_bookkeeping_buf [_off : _off + _req_4byte_bytes ].view (
1067+ torch .float32
1068+ )
1069+ _off += _req_4byte_bytes
1070+ self ._staging_top_k = self ._cpu_bookkeeping_buf [_off : _off + _req_4byte_bytes ].view (
1071+ torch .int32
1072+ )
1073+ _off += _req_4byte_bytes
1074+ self ._staging_top_p = self ._cpu_bookkeeping_buf [_off : _off + _req_4byte_bytes ].view (
1075+ torch .float32
1076+ )
1077+ _off += _req_4byte_bytes
1078+
1079+ # Per-request last-token row indices. Aliased with the matching gpu_view slot:
1080+ # build_active_slices/pad_active_slices populate this CPU view.
1081+ self .active_request_last_token_idxs = self ._cpu_bookkeeping_buf [
1082+ _off : _off + _req_4byte_bytes
1083+ ].view (torch .int32 )
1084+ _off += _req_4byte_bytes
10591085
10601086 # Static tensor addresses to make `last_token_logits` graphable with speculative decoding.
10611087 max_logit_idxs = self .max_requests * (self .num_speculative_tokens + 1 )
@@ -2244,7 +2270,7 @@ def transfer_bookkeeping_to_gpu(self) -> None:
22442270 All copies use non_blocking=True with pinned CPU memory. CUDA stream
22452271 ordering guarantees the forward pass sees completed transfers.
22462272
2247- The 9 bookkeeping fields are backed by one contiguous pinned CPU buffer
2273+ The bookkeeping fields are backed by one contiguous pinned CPU buffer
22482274 and one contiguous GPU buffer; a single cudaMemcpyAsync suffices.
22492275 Request-level staging slots are refreshed from the persistent CPU
22502276 tensors immediately before the H2D (GPU reads them at `[:n_active]`
@@ -2255,16 +2281,25 @@ def transfer_bookkeeping_to_gpu(self) -> None:
22552281 padded_active = max (n_active , self .padded_active_request_count )
22562282
22572283 # Refresh request-level staging slots from the persistent CPU source.
2258- # CPU-to-CPU slice assignment on pinned memory (~7.5 KB total for 3
2259- # int32 fields at max_requests=624). Negligible vs. the launch overhead
2260- # we save by merging 9 H2D memcpys into 1.
2284+ # CPU-to-CPU slice assignment on pinned memory (~15 KB total for 6
2285+ # 4-byte fields at max_requests=624). Negligible vs. the launch overhead
2286+ # we save by merging the H2D memcpys into 1.
22612287 self ._staging_request_in_prefill_status [:n_active ] = self .request_in_prefill_status_tensor [
22622288 active_slice
22632289 ]
22642290 self ._staging_request_query_lengths [:n_active ] = self .request_query_lengths [active_slice ]
22652291 self ._staging_request_kv_length_offsets [:n_active ] = self .request_kv_length_offsets [
22662292 active_slice
22672293 ]
2294+ # Sampling-parameter staging slots: read from `active_request_metadata`,
2295+ # which `build_active_slices` + `pad_active_slices` already populated for
2296+ # `[:padded_active]` (active values + neutral padding defaults).
2297+ self ._staging_temperature [:padded_active ] = self .active_request_metadata ["temperature" ][
2298+ :padded_active
2299+ ]
2300+ self ._staging_top_k [:padded_active ] = self .active_request_metadata ["top_k" ][:padded_active ]
2301+ self ._staging_top_p [:padded_active ] = self .active_request_metadata ["top_p" ][:padded_active ]
2302+
22682303 # Full-iteration CUDA graphs may have captured GPU consumers with the
22692304 # padded graph request count. Keep those padded staging rows bounded so
22702305 # graph replay never builds indices from stale request lengths.
0 commit comments