license import { device_util , env } from '@tensorflow/tfjs-core' ; import { getMaxTexturesInShader , getWebGLDisjointQueryTimerVersion , getWebGLMaxTextureSize , isCapableOfRenderingToFloatTexture , isDownloadFloatTextureEnabled , isWebGLFenceEnabled , isWebGLVersionEnabled } from './webgl_util' ; const ENV = env ( ) ; /**
 * This file contains WebGL-specific flag registrations.
 */ /**
 * True if WebGL is supported.
 */ ENV . registerFlag ( 'HAS_WEBGL' , ( ) => ENV . getNumber ( 'WEBGL_VERSION' ) > 0 ) ; /** 0: No WebGL, 1: WebGL 1.0, 2: WebGL 2.0. */ ENV . registerFlag ( 'WEBGL_VERSION' , ( ) => { if ( isWebGLVersionEnabled ( 2 ) ) { return 2 ; } else if ( isWebGLVersionEnabled ( 1 ) ) { return 1 ; } return 0 ; } ) ; /** Whether to check for numerical representation problems. */ ENV . registerFlag ( 'WEBGL_CHECK_NUMERICAL_PROBLEMS' , ( ) => false ) ; ENV . registerFlag ( 'WEBGL_BUFFER_SUPPORTED' , ( ) => ENV . get ( 'WEBGL_VERSION' ) === 2 ) ; /** Whether the WebGL backend will sometimes forward ops to the CPU. */ ENV . registerFlag ( 'WEBGL_CPU_FORWARD' , ( ) => true ) ; /** Whether the WebGL backend will always use f16 textures for rendering. */ ENV . registerFlag ( 'WEBGL_FORCE_F16_TEXTURES' , ( ) => false ) ; /** Whether to turn all packing related flags on. */ ENV . registerFlag ( 'WEBGL_PACK' , ( ) => ENV . getBool ( 'HAS_WEBGL' ) ) ; /** Whether we will pack the batchnormalization op. */ ENV . registerFlag ( 'WEBGL_PACK_NORMALIZATION' , ( ) => ENV . getBool ( 'WEBGL_PACK' ) ) ; /** Whether we will pack the clip op. */ ENV . registerFlag ( 'WEBGL_PACK_CLIP' , ( ) => ENV . getBool ( 'WEBGL_PACK' ) ) ; /** Whether we will pack the depthwise conv op. */ ENV . registerFlag ( 'WEBGL_PACK_DEPTHWISECONV' , ( ) => ENV . getBool ( 'WEBGL_PACK' ) ) ; /** Whether we will pack binary ops. */ ENV . registerFlag ( 'WEBGL_PACK_BINARY_OPERATIONS' , ( ) => ENV . getBool ( 'WEBGL_PACK' ) ) ; /** Whether we will pack unary ops. */ ENV . registerFlag ( 'WEBGL_PACK_UNARY_OPERATIONS' , ( ) => ENV . getBool ( 'WEBGL_PACK' ) ) ; /** Whether we will pack array ops. */ ENV . registerFlag ( 'WEBGL_PACK_ARRAY_OPERATIONS' , ( ) => ENV . getBool ( 'WEBGL_PACK' ) ) ; /** Whether we will pack image ops. */ ENV . registerFlag ( 'WEBGL_PACK_IMAGE_OPERATIONS' , ( ) => ENV . getBool ( 'WEBGL_PACK' ) ) ; /** Whether we will pack reduce ops. */ ENV . registerFlag ( 'WEBGL_PACK_REDUCE' , ( ) => ENV . getBool ( 'WEBGL_PACK' ) ) ; /** Whether packed WebGL kernels lazily unpack their outputs. */ ENV . registerFlag ( 'WEBGL_LAZILY_UNPACK' , ( ) => ENV . getBool ( 'WEBGL_PACK' ) ) ; /** Whether we will use the im2col algorithm to speed up convolutions. */ ENV . registerFlag ( 'WEBGL_CONV_IM2COL' , ( ) => ENV . getBool ( 'WEBGL_PACK' ) ) ; /** The maximum texture dimension. */ ENV . registerFlag ( 'WEBGL_MAX_TEXTURE_SIZE' , ( ) => getWebGLMaxTextureSize ( ENV . getNumber ( 'WEBGL_VERSION' ) ) ) ; /** The maximum texture dimension. */ ENV . registerFlag ( 'WEBGL_MAX_TEXTURES_IN_SHADER' , ( ) => getMaxTexturesInShader ( ENV . getNumber ( 'WEBGL_VERSION' ) ) ) ; /**
 * The disjoint_query_timer extension version.
 * 0: disabled, 1: EXT_disjoint_timer_query, 2:
 * EXT_disjoint_timer_query_webgl2.
 * In Firefox with WebGL 2.0,
 * EXT_disjoint_timer_query_webgl2 is not available, so we must use the
 * WebGL 1.0 extension.
 */ ENV . registerFlag ( 'WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION' , ( ) => { const webGLVersion = ENV . getNumber ( 'WEBGL_VERSION' ) ; if ( webGLVersion === 0 ) { return 0 ; } return getWebGLDisjointQueryTimerVersion ( webGLVersion ) ; } ) ; /**
 * Whether the timer object from the disjoint_query_timer extension gives
 * timing information that is reliable.
 */ ENV . registerFlag ( 'WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE' , ( ) => ENV . getNumber ( 'WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION' ) > 0 && ! device_util . isMobile ( ) ) ; /**
 * Whether the device is physically capable of rendering to float32 textures.
 */ ENV . registerFlag ( 'WEBGL_RENDER_FLOAT32_CAPABLE' , ( ) => isCapableOfRenderingToFloatTexture ( ENV . getNumber ( 'WEBGL_VERSION' ) ) ) ; /**
 * Whether rendering to float32 textures is enabled. If disabled, renders to
 * float16 textures.
 */ ENV . registerFlag ( 'WEBGL_RENDER_FLOAT32_ENABLED' , ( ) => { return ENV . getBool ( 'WEBGL_FORCE_F16_TEXTURES' ) ? false : ENV . getBool ( 'WEBGL_RENDER_FLOAT32_CAPABLE' ) ; } ) ; /**
 * Whether downloading float textures is enabled (16 or 32 bit). If disabled,
 * uses IEEE 754 encoding of the float32 values to 4 uint8 when downloading.
 */ ENV . registerFlag ( 'WEBGL_DOWNLOAD_FLOAT_ENABLED' , ( ) => isDownloadFloatTextureEnabled ( ENV . getNumber ( 'WEBGL_VERSION' ) ) ) ; /** Whether the fence API is available. */ ENV . registerFlag ( 'WEBGL_FENCE_API_ENABLED' , ( ) => isWebGLFenceEnabled ( ENV . getNumber ( 'WEBGL_VERSION' ) ) ) ; /**
 * Tensors with size <= than this will be uploaded as uniforms, not textures.
 */ ENV . registerFlag ( 'WEBGL_SIZE_UPLOAD_UNIFORM' , ( ) => { const useUniforms = ENV . getBool ( 'WEBGL_RENDER_FLOAT32_ENABLED' ) ; return useUniforms ? 4 : 0 ; } ) ; /**
 * If the total number of bytes allocated on the GPU is greater than this
 * number, we will aggressively delete textures upon disposal with
 * gl.deleteMatrixTexture, rather than making them available for reuse.
 *
 * Default value -1 indicates that we will never aggressively delete textures.
 */ ENV . registerFlag ( 'WEBGL_DELETE_TEXTURE_THRESHOLD' , ( ) => { return - 1 ; } , threshold => { if ( threshold < 0 && threshold !== - 1 ) { throw new Error ( `WEBGL_DELETE_TEXTURE_THRESHOLD must be -1 (indicating never ` + `delete) or at least 0, but got ${ threshold }.` ) ; } } ) ; /**
 * Trigger a manual GL command flush if the threshold of time has passed since
 * previous Kernel execution. This can be useful for Andorid device where GL
 * command flush are delayed un til the end of javascript task. This value is
 * measured in millisecond. Typically you want to set this value to close to 1.
 *
 * Default value 1 for mobile chrome, and -1 for rest cases. -1 indicates that
 * we will not enforce manual flush and depend on system default flush schedule.
 */ ENV . registerFlag ( 'WEBGL_FLUSH_THRESHOLD' , ( ) => { return device_util . isMobile ( ) ? 1 : - 1 ; } , threshold => { if ( threshold < 0 && threshold !== - 1 ) { throw new Error ( `WEBGL_FLUSH_THRESHOLD must be -1 (indicating never ` + `manual flush) or at least 0, but got ${ threshold }.` ) ; } } ) ; /**
 * Threshold for input tensor size that determines whether WebGL backend will
 * delegate computation to CPU.
 *
 * Default value is 128.
 */ ENV . registerFlag ( 'CPU_HANDOFF_SIZE_THRESHOLD' , ( ) => 128 ) ; /** Whether we will use shapes uniforms. */ ENV . registerFlag ( 'WEBGL_USE_SHAPES_UNIFORMS' , ( ) => false ) ; /**
 * Threshold for last dimension of input tensor that determines whether
 * WebGL backend for the Top K op will delegate computation to CPU. If input
 * is smaller than threshold then CPU will be used
 *
 * Default value is 100000.
 */ ENV . registerFlag ( 'TOPK_LAST_DIM_CPU_HANDOFF_SIZE_THRESHOLD' , ( ) => 100000 ) ; /**
 * Threshold for K that determines whether
 * WebGL backend for the Top K op will delegate computation to CPU. If k
 * is larger than threshold then CPU will be used
 *
 * Default value is 128.
 */ ENV . registerFlag ( 'TOPK_K_CPU_HANDOFF_THRESHOLD' , ( ) => 128 ) ;