async fn read_to_vec(
        &self,
        device: &wgpu::Device,
        queue: &wgpu::Queue,
    ) -> Result<OutputTensor, GpuError> {
        let buffer_slice = self.buffer.slice(..);

        // On wgpu we can MAP_READ a buffer that is also used as STORAGE, but WebGPU (on at least Chrome)
        // disallows this. Therefore we need to do an additional copy into a MAP_READ buffer when reading back a
        // STORAGE buffer when on WebGPU.
        #[cfg(target_arch = "wasm32")]
        let output_data = wgpu::util::DownloadBuffer::read_buffer(device, queue, &buffer_slice)
            .await
            .unwrap();

        #[cfg(not(target_arch = "wasm32"))]
        let output_data = {
            let _ = queue; // Need this because otherwise compiler complains we are not using the queue parameter
            let buffer_future = buffer_slice.map_async(wgpu::MapMode::Read);
            device.poll(wgpu::Maintain::Wait);
            buffer_future.await.expect("failed to run compute on gpu!");
            buffer_slice.get_mapped_range()
        };

        // The actual buffer may be bigger than what we should return, because buffers have a minimum size in wgpu
        // Fetch the size we should expect so we can chop the buffer to the correct size
        let output_buffer_size = self.shape.element_count() as usize;
        let result = match self.shape.data_type {
            ScalarType::F32 => {
                OutputTensor::F32(bytemuck::cast_slice(&output_data)[..output_buffer_size].to_vec())
            }
            ScalarType::I32 => {
                OutputTensor::I32(bytemuck::cast_slice(&output_data)[..output_buffer_size].to_vec())
            }
            ScalarType::I64 => {
                log::warn!("reading int64 output as int32 because internally int64 scalars are not supported");
                let result_ints: Vec<i32> =
                    bytemuck::cast_slice(&output_data)[..output_buffer_size].to_vec();
                OutputTensor::I64(result_ints.iter().map(|i| *i as i64).collect())
            }
        };
        drop(output_data);

        // On WASM we are not mapping the buffer, so we don't need to unmap
        #[cfg(not(target_arch = "wasm32"))]
        self.buffer.unmap();
        Ok(result)
    }
/// Read the tensor from GPU memory to main memory (as Vec<f32>)
Read the tensor from GPU memory to main memory (as Vec)
Read the tensor from GPU memory to main memory ( as Vec )
async fn read_to_vec(
        &self,
        device: &wgpu::Device,
        queue: &wgpu::Queue,
    ) -> Result<OutputTensor, GpuError> {
        let buffer_slice = self.buffer.slice(..);
        // On wgpu we can MAP_READ a buffer that is also used as STORAGE, but WebGPU (on at least Chrome)
        // disallows this. Therefore we need to do an additional copy into a MAP_READ buffer when reading back a
        // STORAGE buffer when on WebGPU.
        #[cfg(target_arch = "wasm32")]
        let output_data = wgpu::util::DownloadBuffer::read_buffer(device, queue, &buffer_slice)
            .await
            .unwrap();
        #[cfg(not(target_arch = "wasm32"))]
        let output_data = {
            let _ = queue; // Need this because otherwise compiler complains we are not using the queue parameter
            let buffer_future = buffer_slice.map_async(wgpu::MapMode::Read);
            device.poll(wgpu::Maintain::Wait);
            buffer_future.await.expect("failed to run compute on gpu!");
            buffer_slice.get_mapped_range()
        };
        // The actual buffer may be bigger than what we should return, because buffers have a minimum size in wgpu
        // Fetch the size we should expect so we can chop the buffer to the correct size
        let output_buffer_size = self.shape.element_count() as usize;
        let result = match self.shape.data_type {
            ScalarType::F32 => {
                OutputTensor::F32(bytemuck::cast_slice(&output_data)[..output_buffer_size].to_vec())
            }
            ScalarType::I32 => {
                OutputTensor::I32(bytemuck::cast_slice(&output_data)[..output_buffer_size].to_vec())
            }
            ScalarType::I64 => {
                log::warn!("reading int64 output as int32 because internally int64 scalars are not supported");
                let result_ints: Vec<i32> =
                    bytemuck::cast_slice(&output_data)[..output_buffer_size].to_vec();
                OutputTensor::I64(result_ints.iter().map(|i| *i as i64).collect())
            }
        };
        drop(output_data);
        // On WASM we are not mapping the buffer, so we don't need to unmap
        #[cfg(not(target_arch = "wasm32"))]
        self.buffer.unmap();
        Ok(result)
    }
async fn read_to_vec ( & self , device : & wgpu :: Device , queue : & wgpu :: Queue , ) -> Result < OutputTensor , GpuError > { let buffer_slice = self . buffer . slice ( .. ) ; // On wgpu we can MAP_READ a buffer that is also used as STORAGE, but WebGPU (on at least Chrome) // disallows this. Therefore we need to do an additional copy into a MAP_READ buffer when reading back a // STORAGE buffer when on WebGPU. # [ cfg ( target_arch " " ) ] let output_data = wgpu :: util :: DownloadBuffer :: read_buffer ( device , queue , & buffer_slice ) . await . unwrap ( ) ; # [ cfg ( not ( target_arch " " ) ) ] let output_data = { let _ = queue ; // Need this because otherwise compiler complains we are not using the queue parameter let buffer_future = buffer_slice . map_async ( wgpu :: MapMode :: Read ) ; device . poll ( wgpu :: Maintain :: Wait ) ; buffer_future . await . expect ( " " ) ; buffer_slice . get_mapped_range ( ) } ; // The actual buffer may be bigger than what we should return, because buffers have a minimum size in wgpu // Fetch the size we should expect so we can chop the buffer to the correct size let output_buffer_size = self . shape . element_count ( ) as usize ; let result = match self . shape . data_type { ScalarType :: F32 => { OutputTensor :: F32 ( bytemuck :: cast_slice ( & output_data ) [ .. output_buffer_size ] . to_vec ( ) ) } ScalarType :: I32 => { OutputTensor :: I32 ( bytemuck :: cast_slice ( & output_data ) [ .. output_buffer_size ] . to_vec ( ) ) } ScalarType :: I64 => { log :: warn ! ( " " ) ; let result_ints : Vec < i32 > = bytemuck :: cast_slice ( & output_data ) [ .. output_buffer_size ] . to_vec ( ) ; OutputTensor :: I64 ( result_ints . iter ( ) . map ( | i | * i as i64 ) . collect ( ) ) } } ; drop ( output_data ) ; // On WASM we are not mapping the buffer, so we don't need to unmap # [ cfg ( not ( target_arch " " ) ) ] self . buffer . unmap ( ) ; Ok ( result ) }
Read the tensor from GPU memory to main memory (as Vec<f32>)
Read the tensor from GPU memory to main memory ( as Vec<f32 > )
&self
device
&wgpu::Device
queue
&wgpu::Queue
&self
device
&wgpu::Device
queue
&wgpu::Queue