Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebGPU: Add fromPixelsAsync for tfjs webgpu #4139

Merged
merged 6 commits into from
Nov 2, 2020

Conversation

shaoboyan
Copy link
Contributor

@shaoboyan shaoboyan commented Oct 27, 2020

This patch add fromPixelsAsync for tfjs webgpu to handle:

  1. Convert inputs to imageBitmap in a proper way
  2. Using CopyImageBitmapToTexture + shader to handle inputs.

This change is Reviewable

@google-cla google-cla bot added the cla: yes label Oct 27, 2020
@shaoboyan
Copy link
Contributor Author

@qjia7 Please take a look if you have time

const outShape = [pixels.height, pixels.width, numChannels];
const size = util.sizeFromShape(outShape);
const uniformData: [number, number] = [size, numChannels];
//let imageData = (pixels as ImageData | backend_util.PixelData).data;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If above line is not needed, remove it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sry. Force update last CL and it has been covered. This comments has been resolved.

return await kernel.kernelFunc({inputs, attrs, backend: ENGINE.backend}) as Tensor3D;

} else {
throw new Error(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about calling the sync FromPixels here instead of throwing an error? Also you can put this checking at the beginning of this function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

[pixels.width, pixels.height];
let vals: Uint8ClampedArray|Uint8Array;
[
(pixels as HTMLVideoElement).videoWidth,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why you need to change the original fromPixels_ function?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

return;
}

// TODO(tfjs-optimization): using new mapAsync API to update the buffer.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose this comment should be added in line 99. Just curious, why do you think mapAsync is better than writeBuffer?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is due to the staging buffer. But actually for the samll sized uniform data. I think they have similar perf. (BTW, this is the legancy comments from last related patch :P) I'll remove it.

This patch add fromPixelsAsync for tfjs webgpu to handle:
1. Convert inputs to imageBitmap in a proper way
2. Using CopyImageBitmapToTexture + shader to handle inputs.
tfjs-core/src/kernel_names.ts Outdated Show resolved Hide resolved
tfjs-core/src/ops/browser.ts Outdated Show resolved Hide resolved
@qjia7
Copy link
Contributor

qjia7 commented Oct 28, 2020

Add @annxingyuan @kainino0x take a look, thanks.

Copy link
Contributor

@qjia7 qjia7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with the last two comments. Thanks.

}

const uniformBuffer = device.createBuffer({
size: 4 * 2,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

size: uniformData.byteLength? Please avoid to use the raw data.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uniformData is a normal array and it doesn't have byteLength. So I have to use uniformData.length * 4. Maybe @annxingyuan and @kainino0x have some suggestions.

tfjs-core/src/ops/browser.ts Outdated Show resolved Hide resolved
import {BROWSER_ENVS, describeWithFlags} from '../jasmine_util';
import {expectArraysClose, expectArraysEqual} from '../test_util';

describeWithFlags('fromPixelsAsync', BROWSER_ENVS, () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One issue here is that I don't know how to add test case to check the wrong input and catch the exception. Like https://github.com/tensorflow/tfjs/blob/master/tfjs-core/src/ops/from_pixels_test.ts#L248. @qjia7 @annxingyuan @kainino0x Do you have any suggestions?

@qjia7
Copy link
Contributor

qjia7 commented Nov 2, 2020

Ping @annxingyuan @kainino0x . Do you have any concern for current change?

Copy link
Contributor

@annxingyuan annxingyuan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have not closely reviewed, but I trust @qjia7 's LGTM :) Thank you @shaoboyan !

@annxingyuan annxingyuan merged commit efc773c into tensorflow:master Nov 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants