fn encode<'a>(
        &self,
        queue: &wgpu::Queue,
        encoder: &mut CommandEncoder,
        inputs: &HashMap<String, InputTensor<'a>>,
    ) -> Result<(), GpuError> {
        match self {
            GpuStep::None | GpuStep::Forward(_) | GpuStep::Initializer(_) => {
                // Buffer already filled, no need to encode anything at this point.
                Ok(())
            }
            GpuStep::Input(input_name, input_buffer) => {
                // Encode a command to write the input data to the corresponding input buffer (which was created empty
                // by `GpuModel::from`
                let input_data = inputs
                    .get(input_name)
                    .ok_or_else(|| GpuError::InferenceInputMissing(input_name.to_string()))?;
                log::info!("- write input data for {}", input_name);

                match input_data {
                    InputTensor::F32(float_input) => {
                        queue.write_buffer(
                            input_buffer,
                            0,
                            bytemuck::cast_slice(&resize(float_input.to_vec())),
                        );
                    }
                    InputTensor::I32(int_input) => {
                        queue.write_buffer(
                            input_buffer,
                            0,
                            bytemuck::cast_slice(&resize(int_input.to_vec())),
                        );
                    }
                    InputTensor::I64(int_input) => {
                        log::warn!("reading int64 input as int32 (int64 is not supported for calculation but can be used as input as long as values fit in int32)");
                        let int32_input = int_input
                            .iter()
                            .map(|i| i32::from_i64(*i).ok_or(GpuError::OutOfBoundsError))
                            .collect::<Result<_, _>>()?;
                        queue.write_buffer(
                            input_buffer,
                            0,
                            bytemuck::cast_slice(&resize(int32_input)),
                        );
                    }
                }

                Ok(())
            }
            GpuStep::Operator {
                pipeline,
                bind_groups,
                threads,
                ..
            } => {
                // Encode a command for invocation of a shader.
                let mut compute_pass =
                    encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { label: None });
                compute_pass.set_pipeline(pipeline);
                for (index, bind_group) in bind_groups.iter().enumerate() {
                    compute_pass.set_bind_group(index as u32, bind_group, &[]);
                }
                let (x, y, z) = *threads;
                compute_pass.dispatch(x, y, z);
                Ok(())
            }
        }
    }
/// Writes the necessary commands for the GPU to execute this step into the command queue. Among other things this means
/// writing the inference input data to the appropriate (already created) buffers.
Writes the necessary commands for the GPU to execute this step into the command queue. Among other things this means
writing the inference input data to the appropriate (already created) buffers.
Writes the necessary commands for the GPU to execute this step into the command queue . Among other things this means writing the inference input data to the appropriate ( already created ) buffers .
fn encode<'a>(
        &self,
        queue: &wgpu::Queue,
        encoder: &mut CommandEncoder,
        inputs: &HashMap<String, InputTensor<'a>>,
    ) -> Result<(), GpuError> {
        match self {
            GpuStep::None | GpuStep::Forward(_) | GpuStep::Initializer(_) => {
                // Buffer already filled, no need to encode anything at this point.
                Ok(())
            }
            GpuStep::Input(input_name, input_buffer) => {
                // Encode a command to write the input data to the corresponding input buffer (which was created empty
                // by `GpuModel::from`
                let input_data = inputs
                    .get(input_name)
                    .ok_or_else(|| GpuError::InferenceInputMissing(input_name.to_string()))?;
                log::info!("- write input data for {}", input_name);
                match input_data {
                    InputTensor::F32(float_input) => {
                        queue.write_buffer(
                            input_buffer,
                            0,
                            bytemuck::cast_slice(&resize(float_input.to_vec())),
                        );
                    }
                    InputTensor::I32(int_input) => {
                        queue.write_buffer(
                            input_buffer,
                            0,
                            bytemuck::cast_slice(&resize(int_input.to_vec())),
                        );
                    }
                    InputTensor::I64(int_input) => {
                        log::warn!("reading int64 input as int32 (int64 is not supported for calculation but can be used as input as long as values fit in int32)");
                        let int32_input = int_input
                            .iter()
                            .map(|i| i32::from_i64(*i).ok_or(GpuError::OutOfBoundsError))
                            .collect::<Result<_, _>>()?;
                        queue.write_buffer(
                            input_buffer,
                            0,
                            bytemuck::cast_slice(&resize(int32_input)),
                        );
                    }
                }
                Ok(())
            }
            GpuStep::Operator {
                pipeline,
                bind_groups,
                threads,
                ..
            } => {
                // Encode a command for invocation of a shader.
                let mut compute_pass =
                    encoder.begin_compute_pass(&wgpu::ComputePassDescriptor { label: None });
                compute_pass.set_pipeline(pipeline);
                for (index, bind_group) in bind_groups.iter().enumerate() {
                    compute_pass.set_bind_group(index as u32, bind_group, &[]);
                }
                let (x, y, z) = *threads;
                compute_pass.dispatch(x, y, z);
                Ok(())
            }
        }
    }
fn encode < ' a > ( & self , queue : & wgpu :: Queue , encoder : & mut CommandEncoder , inputs : & HashMap < String , InputTensor < ' a > > , ) -> Result < ( ) , GpuError > { match self { GpuStep :: None | GpuStep :: Forward ( _ ) | GpuStep :: Initializer ( _ ) => { // Buffer already filled, no need to encode anything at this point. Ok ( ( ) ) } GpuStep :: Input ( input_name , input_buffer ) => { // Encode a command to write the input data to the corresponding input buffer (which was created empty // by `GpuModel::from` let input_data = inputs . get ( input_name ) . ok_or_else ( | | GpuError :: InferenceInputMissing ( input_name . to_string ( ) ) ) ? ; log :: info ! ( " " input_name ) ; match input_data { InputTensor :: F32 ( float_input ) => { queue . write_buffer ( input_buffer , 0 , bytemuck :: cast_slice ( & resize ( float_input . to_vec ( ) ) ) , ) ; } InputTensor :: I32 ( int_input ) => { queue . write_buffer ( input_buffer , 0 , bytemuck :: cast_slice ( & resize ( int_input . to_vec ( ) ) ) , ) ; } InputTensor :: I64 ( int_input ) => { log :: warn ! ( " " ) ; let int32_input = int_input . iter ( ) . map ( | i | i32 :: from_i64 ( * i ) . ok_or ( GpuError :: OutOfBoundsError ) ) . collect :: < Result < _ , _ > > ( ) ? ; queue . write_buffer ( input_buffer , 0 , bytemuck :: cast_slice ( & resize ( int32_input ) ) , ) ; } } Ok ( ( ) ) } GpuStep :: Operator { pipeline , bind_groups , threads , .. } => { // Encode a command for invocation of a shader. let mut compute_pass = encoder . begin_compute_pass ( & wgpu :: ComputePassDescriptor { label : None } ) ; compute_pass . set_pipeline ( pipeline ) ; for ( index , bind_group ) in bind_groups . iter ( ) . enumerate ( ) { compute_pass . set_bind_group ( index as u32 , bind_group , & [ ] ) ; } let ( x , y , z ) = * threads ; compute_pass . dispatch ( x , y , z ) ; Ok ( ( ) ) } } }
Writes the necessary commands for the GPU to execute this step into the command queue.
Writes the necessary commands for the GPU to execute this step into the command queue .
&self
queue
&wgpu::Queue
encoder
&mut CommandEncoder
inputs
&HashMap<String, InputTensor<'a>>
&self
queue
&wgpu::Queue
encoder
&mut CommandEncoder
inputs
&HashMap<String, InputTensor<'a>>