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

[WebGL] Fix Vao usage for parallel compile feature #7587

Merged
merged 6 commits into from
Apr 17, 2023

Conversation

Linchenn
Copy link
Collaborator

@Linchenn Linchenn commented Apr 14, 2023

For #7577

Problem

If we create VAO for each webgl program, then we have to set VAO for each program and bind it before execution. Right now, setting VAO happens in createProgram and createProgram is involved in compilation stage. However, setting VAO has blocking-call getAttribLocation, so setting VAO should be called after compilation stage.

This should work similar as what we do for getUniformLocations. We moved getUniformLocations call out of createProgram/compilation-stage, because it has blocking-call.

Evaluation

before #6913 is merged (tfjs 4.0.0)

image
checkCompileCompletion takes the majority time for warm up.

after #6913 is merged (tfjs 4.1.0)

image

checkCompileCompletion takes the trivial time for warm up.
image
getAttribLocation is blocking in the compilation stage.

after this PR

image

checkCompileCompletion takes the majority time for warm up.

codes

I used the following codes to reproduce the problem

<!DOCTYPE html>
<html>
  <body>

    // Local build
    <script src="https://unpkg.com/@tensorflow/tfjs-core@latest/dist/tf-core.js"></script>
    <script src="https://unpkg.com/@tensorflow/tfjs-converter@latest/dist/tf-converter.js"></script>
    <script src="./dist/bin/tfjs-backend-webgl/dist/tf-backend-webgl.js"></script>

    // After https://github.com/tensorflow/tfjs/pull/6913/files is merged
    <!-- <script src="https://unpkg.com/@tensorflow/[email protected]/dist/tf-core.js"></script>
    <script src="https://unpkg.com/@tensorflow/[email protected]/dist/tf-converter.js"></script>
    <script src="https://unpkg.com/@tensorflow/[email protected]/dist/tf-backend-webgl.js"></script> -->

    // Before https://github.com/tensorflow/tfjs/pull/6913/files is merged
    <!-- <script src="https://unpkg.com/@tensorflow/[email protected]/dist/tf-core.js"></script>
    <script src="https://unpkg.com/@tensorflow/[email protected]/dist/tf-converter.js"></script>
    <script src="https://unpkg.com/@tensorflow/[email protected]/dist/tf-backend-webgl.js"></script> -->


    <script>
      const url = `https://tfhub.dev/google/tfjs-model/imagenet/mobilenet_v3_small_075_224/classification/5/default/1`;
      model = tf.loadGraphModel(url, {fromTFHub: true});

      function normalWarmUp() {
        const input = tf.randomNormal([1, 224, 224, 3]);
        return model.predict(input);
      }

      function parallelWarmUp() {
        const input = tf.randomNormal([1, 224, 224, 3]);
        tf.env().set('ENGINE_COMPILE_ONLY', true);
        model.predict(input);
        tf.env().set('ENGINE_COMPILE_ONLY', false);
        tf.backend().checkCompileCompletion();
        tf.backend().getUniformLocations();
        return model.predict(input);
      }

      function cleanUp() {
        tf.backend().binaryCache = {};
      }

      async function benchmark(fn) {
        model = await model;
        const start = performance.now();
        fn().dataSync();
        return performance.now() - start;
      }

    </script>
  </body>
</html>

To see the logs from the Cloud Build CI, please join either our discussion or announcement mailing list.


This change is Reviewable

@Linchenn Linchenn requested a review from pyu10055 April 14, 2023 00:16
@Linchenn
Copy link
Collaborator Author

The problem is caused by #6913, which is trying to bind VAO before each webgl program execution. I think the idea makes sense, even though TFJS's vertex shaders are same, because users may use the same canvas and write their own webgl program with different vertex shaders.

@@ -1277,6 +1277,7 @@ export class MathBackendWebGL extends KernelBackend {

getUniformLocations() {
for (const binary of Object.values(this.binaryCache)) {
this.gpgpu.buildVao(binary.webGLProgram);
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It does not make sense to add this code within getUniformLocations and theoratically we should move it to a new function, like 'setVao'. However, since we have told some users to use this to utilize parallel compilation feature, making setVao and requiring users to call it are breaking change for them.

Copy link
Member

Choose a reason for hiding this comment

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

Nit: Can you add a TODO here explaining this? Thanks!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Done. Thanks!

Copy link
Collaborator

@pyu10055 pyu10055 left a comment

Choose a reason for hiding this comment

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

thanks for fixing the issue!

@@ -253,6 +254,7 @@ export function runProgram<T extends Tensor, K extends Tensor>(
outTex.texture, outTexShape[0], outTexShape[1]);
}
gpgpu.setProgram(binary.webGLProgram);
Copy link
Collaborator

Choose a reason for hiding this comment

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

should this two line be the same as just call gpgpu.buildVao(binary.webGLProgram)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

IICU, buildVao is to initialize VAO, while here it is using initialized VAO. Specifically, VAO initialization has to bind all attributes, while using initialized VAO does not need to.

@Linchenn Linchenn requested a review from mattsoulanille April 17, 2023 21:49
Copy link
Member

@mattsoulanille mattsoulanille 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 a nit.

@@ -1277,6 +1277,7 @@ export class MathBackendWebGL extends KernelBackend {

getUniformLocations() {
for (const binary of Object.values(this.binaryCache)) {
this.gpgpu.buildVao(binary.webGLProgram);
Copy link
Member

Choose a reason for hiding this comment

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

Nit: Can you add a TODO here explaining this? Thanks!

Copy link
Member

@mattsoulanille mattsoulanille left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks for adding the TODO.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants