<commit_before>export { Base }; // Stage.BlockParamsCreator.Base

import * as Pool from "../../../util/Pool.js";
import * as Recyclable from "../../../util/Recyclable.js";
import * as ValueDesc from "../../../Unpacker/ValueDesc.js";
import * as Block from "../../Block.js";
import { Params } from "../Stage_Params.js";

/**
 * Base class for all Stage.BlockParamsCreator.Xxx classes.
 *
 *
 * @member {number} output0_channelCount
 *   The output0's channel count in current configuration.
 *
 * @member {number} output1_channelCount
 *   The output1's channel count in current configuration.
 *
 */
class Base extends Recyclable.Root {

  /**
   * Used as default Stage.BlockParamsCreator.Base provider for conforming to Recyclable interface.
   */
  static Pool = new Pool.Root( "Stage.BlockParamsCreator.Base.Pool", Base, Base.setAsConstructor );

  /**
   * @param {Params} stageParams
   *   The Stage.Params object which provides basic parameters. It will be referenced (i.e. not cloned, not owned, not released)
   * by this Stage.BlockParamsCreator.Base onject.
   */
  constructor( stageParams ) {
    super();
    Base.setAsConstructor_self.call( this, stageParams );
  }

  /** @override */
  static setAsConstructor( stageParams ) {
    super.setAsConstructor();
    Base.setAsConstructor_self.call( this, stageParams );
    return this;
  }

  /** @override */
  static setAsConstructor_self( stageParams ) {
    this.stageParams = stageParams;
  }

  /** @override */
  disposeResources() {
    this.channelShuffler_dispose();

    this.blockCount = undefined; // How many block should be in the stage.
    this.depthwiseFilterHeight_Default = undefined;
    this.depthwiseFilterWidth_Default = undefined; // The default depthwise filter size.
    this.depthwiseFilterHeight_Last = undefined;
    this.depthwiseFilterWidth_Last = undefined;    // The last block's depthwise filter size.
    this.output0_channelCount = undefined;
    this.output1_channelCount = undefined;

    this.bKeepInputTensor = undefined;
    this.nActivationId = undefined;
    this.bSqueezeExcitationPrefix = undefined;
    this.nSqueezeExcitationChannelCountDivisor = undefined;
    this.pointwise20ActivationId = undefined;
    this.pointwise20ChannelCount = undefined;
    this.depthwiseActivationId = undefined;
    this.depthwiseStridesPad = undefined;
    this.depthwiseFilterWidth = undefined;
    this.depthwiseFilterHeight = undefined;
    this.depthwise_AvgMax_Or_ChannelMultiplier = undefined;
    this.pointwise1ChannelCount = undefined;
    this.nConvBlockTypeId = undefined;
    this.input0_channelCount = undefined;
    this.input0_width = undefined;
    this.input0_height = undefined;

    this.stageParams = undefined; // Just nullify it. Do not release it here.

    super.disposeResources();
  }

  /**
   *
   */
  channelShuffler_dispose() {
    if ( this.channelShuffler ) {
      this.channelShuffler.disposeResources_and_recycleToPool();
      this.channelShuffler = false;
    }
  }

  /** Called to determine blockCount, depthwiseFilterHeight_Default, depthwiseFilterWidth_Default, depthwiseFilterHeight_Last,
    * depthwiseFilterWidth_Last.
    *
    * Sub-class could override this method to adjust data members.
    */
  determine_blockCount_depthwiseFilterHeightWidth_Default_Last() {
    let stageParams = this.stageParams;
    this.blockCount = stageParams.blockCountRequested; // By default, the block count is just the original block count.

    // By default, all blocks uses the original depthwise filter size.
    this.depthwiseFilterHeight_Default = this.depthwiseFilterHeight_Last = stageParams.depthwiseFilterHeight;
    this.depthwiseFilterWidth_Default = this.depthwiseFilterWidth_Last = stageParams.depthwiseFilterWidth;
  }

  /**
   * Called before block0 is about to be created. Sub-class should override this method to adjust data members.
   *
   * Block 0.
   *
   * The special points of a stage's block 0 are:
   *   - halve the height x width. (Both ShuffleNetV2 and MobileNetV2) (by depthwise convolution with strides = 2)
   *   - Double channels. (Please see explanation of class Stage.Base)
   */
  configTo_beforeBlock0() {
    let stageParams = this.stageParams;

    this.input0_height = stageParams.sourceHeight; // block0 inputs the source image size.
    this.input0_width = stageParams.sourceWidth;
    //this.input0_channelCount; // Sub-class should determine it.

    this.activation_setup_forBlock0(); // activation of depthwise1 and pointwise2.

    this.depthwiseFilterHeight = this.depthwiseFilterHeight_Default;
    this.depthwiseFilterWidth = this.depthwiseFilterWidth_Default;

    // block0 uses depthwise ( strides = 2, pad = "same" ) to halve ( height, width ).
    this.depthwiseStridesPad = ValueDesc.StridesPad.Singleton.Ids.STRIDES_2_PAD_SAME;

    this.nSqueezeExcitationChannelCountDivisor = stageParams.nSqueezeExcitationChannelCountDivisor;

    this.bKeepInputTensor = stageParams.bKeepInputTensor; // block0 may or may not keep input tensor according to caller's necessary.

    this.output_height = stageParams.inferencedParams.outputHeightArray[ 0 ];
    this.output_width = stageParams.inferencedParams.outputWidthArray[ 0 ];
  }

  /**
   * Called before every block (excluding block0, including block1, 2, ...). Sub-class should override this method to adjust data members.
   *
   * @param {number} blockIndex
   *   The id (i.e. 1, 2, ...) of the block which will be created.
   */
  configTo_beforeBlockN_exceptBlock0( blockIndex ) {
    let stageParams = this.stageParams;

    this.input0_height = stageParams.inferencedParams.inputHeightArray[ blockIndex ];
    this.input0_width = stageParams.inferencedParams.inputWidthArray[ blockIndex ];
    //this.input0_channelCount; // Sub-class should determine it.

    // All blocks (except block0 in NoPointwise1) will not double the channel count by depthwise, because block0 has already double
    // output channel count.
    //
    this.depthwise_AvgMax_Or_ChannelMultiplier = 1;

    // All blocks (except block0) uses depthwise ( strides = 1, pad = "same" ) to keep ( height, width ).
    this.depthwiseStridesPad = ValueDesc.StridesPad.Singleton.Ids.STRIDES_1_PAD_SAME;

    this.bKeepInputTensor = false; // No matter bKeepInputTensor, all blocks (except block0) should not keep input tensor.

    this.output_height = stageParams.inferencedParams.outputHeightArray[ blockIndex ];
    this.output_width = stageParams.inferencedParams.outputWidthArray[ blockIndex ];
  }

  /**
   * Called before blockLast is about to be created. Sub-class could override this method to adjust data members.
   */
  configTo_beforeBlockLast() {

    this.input0_height = stageParams.inferencedParams.inputHeightArray[ blockIndex ];
    this.input0_width = stageParams.inferencedParams.inputWidthArray[ blockIndex ];

    // Besides, the blockLast may use a different depthwise filter size. This is especially true for NotShuffleNet_NotMobileNet.
    this.depthwiseFilterHeight = this.depthwiseFilterHeight_Last;
    this.depthwiseFilterWidth = this.depthwiseFilterWidth_Last;

    this.activation_setup_forBlockLast(); // activation of depthwise1 and pointwise2
  }

  /**
   * Config the activation of pointwise1, depthwise1, pointwise2 and squeeze-and-excitation for block0.
   */
  activation_setup_forBlock0() {
    let stageParams = this.stageParams;

    // 1. depthwise
    {
      // MobileNetV2_Xxx's depthwise has activation (before prefix squeeze-and-excitation and to remedy its pointwise2's no activation).
      //
      if ( ValueDesc.ConvStageType.isMobileNetV2( stageParams.nConvStageTypeId ) ) {
        this.depthwiseActivationId = stageParams.nActivationId;

      // non-MobileNetV2_Xxx's depthwise has no activation. (since they will be done at pointwise2.)
      //<commit_msg>stageParams<commit_after>export { Base }; // Stage.BlockParamsCreator.Base

import * as Pool from "../../../util/Pool.js";
import * as Recyclable from "../../../util/Recyclable.js";
import * as ValueDesc from "../../../Unpacker/ValueDesc.js";
import * as Block from "../../Block.js";
import { Params } from "../Stage_Params.js";

/**
 * Base class for all Stage.BlockParamsCreator.Xxx classes.
 *
 *
 * @member {number} output0_channelCount
 *   The output0's channel count in current configuration.
 *
 * @member {number} output1_channelCount
 *   The output1's channel count in current configuration.
 *
 */
class Base extends Recyclable.Root {

  /**
   * Used as default Stage.BlockParamsCreator.Base provider for conforming to Recyclable interface.
   */
  static Pool = new Pool.Root( "Stage.BlockParamsCreator.Base.Pool", Base, Base.setAsConstructor );

  /**
   * @param {Params} stageParams
   *   The Stage.Params object which provides basic parameters. It will be referenced (i.e. not cloned, not owned, not released)
   * by this Stage.BlockParamsCreator.Base onject.
   */
  constructor( stageParams ) {
    super();
    Base.setAsConstructor_self.call( this, stageParams );
  }

  /** @override */
  static setAsConstructor( stageParams ) {
    super.setAsConstructor();
    Base.setAsConstructor_self.call( this, stageParams );
    return this;
  }

  /** @override */
  static setAsConstructor_self( stageParams ) {
    this.stageParams = stageParams;
  }

  /** @override */
  disposeResources() {
    this.channelShuffler_dispose();

    this.blockCount = undefined; // How many block should be in the stage.
    this.depthwiseFilterHeight_Default = undefined;
    this.depthwiseFilterWidth_Default = undefined; // The default depthwise filter size.
    this.depthwiseFilterHeight_Last = undefined;
    this.depthwiseFilterWidth_Last = undefined;    // The last block's depthwise filter size.
    this.output0_channelCount = undefined;
    this.output1_channelCount = undefined;

    this.bKeepInputTensor = undefined;
    this.nActivationId = undefined;
    this.bSqueezeExcitationPrefix = undefined;
    this.nSqueezeExcitationChannelCountDivisor = undefined;
    this.pointwise20ActivationId = undefined;
    this.pointwise20ChannelCount = undefined;
    this.depthwiseActivationId = undefined;
    this.depthwiseStridesPad = undefined;
    this.depthwiseFilterWidth = undefined;
    this.depthwiseFilterHeight = undefined;
    this.depthwise_AvgMax_Or_ChannelMultiplier = undefined;
    this.pointwise1ChannelCount = undefined;
    this.nConvBlockTypeId = undefined;
    this.input0_channelCount = undefined;
    this.input0_width = undefined;
    this.input0_height = undefined;

    this.stageParams = undefined; // Just nullify it. Do not release it here.

    super.disposeResources();
  }

  /**
   *
   */
  channelShuffler_dispose() {
    if ( this.channelShuffler ) {
      this.channelShuffler.disposeResources_and_recycleToPool();
      this.channelShuffler = false;
    }
  }

  /** Called to determine blockCount, depthwiseFilterHeight_Default, depthwiseFilterWidth_Default, depthwiseFilterHeight_Last,
    * depthwiseFilterWidth_Last.
    *
    * Sub-class could override this method to adjust data members.
    */
  determine_blockCount_depthwiseFilterHeightWidth_Default_Last() {
    let stageParams = this.stageParams;
    this.blockCount = stageParams.blockCountRequested; // By default, the block count is just the original block count.

    // By default, all blocks uses the original depthwise filter size.
    this.depthwiseFilterHeight_Default = this.depthwiseFilterHeight_Last = stageParams.depthwiseFilterHeight;
    this.depthwiseFilterWidth_Default = this.depthwiseFilterWidth_Last = stageParams.depthwiseFilterWidth;
  }

  /**
   * Called before block0 is about to be created. Sub-class should override this method to adjust data members.
   *
   * Block 0.
   *
   * The special points of a stage's block 0 are:
   *   - halve the height x width. (Both ShuffleNetV2 and MobileNetV2) (by depthwise convolution with strides = 2)
   *   - Double channels. (Please see explanation of class Stage.Base)
   */
  configTo_beforeBlock0() {
    let stageParams = this.stageParams;

    this.input0_height = stageParams.sourceHeight; // block0 inputs the source image size.
    this.input0_width = stageParams.sourceWidth;
    //this.input0_channelCount; // Sub-class should determine it.

    this.activation_setup_forBlock0(); // activation of depthwise1 and pointwise2.

    this.depthwiseFilterHeight = this.depthwiseFilterHeight_Default;
    this.depthwiseFilterWidth = this.depthwiseFilterWidth_Default;

    // block0 uses depthwise ( strides = 2, pad = "same" ) to halve ( height, width ).
    this.depthwiseStridesPad = ValueDesc.StridesPad.Singleton.Ids.STRIDES_2_PAD_SAME;

    this.nSqueezeExcitationChannelCountDivisor = stageParams.nSqueezeExcitationChannelCountDivisor;

    this.bKeepInputTensor = stageParams.bKeepInputTensor; // block0 may or may not keep input tensor according to caller's necessary.

    this.output_height = stageParams.inferencedParams.outputHeightArray[ 0 ];
    this.output_width = stageParams.inferencedParams.outputWidthArray[ 0 ];
  }

  /**
   * Called before every block (excluding block0, including block1, 2, ...). Sub-class should override this method to adjust data members.
   *
   * @param {number} blockIndex
   *   The id (i.e. 1, 2, ...) of the block which will be created.
   */
  configTo_beforeBlockN_exceptBlock0( blockIndex ) {
    let stageParams = this.stageParams;

    this.input0_height = stageParams.inferencedParams.inputHeightArray[ blockIndex ];
    this.input0_width = stageParams.inferencedParams.inputWidthArray[ blockIndex ];
    //this.input0_channelCount; // Sub-class should determine it.

    // All blocks (except block0 in NoPointwise1) will not double the channel count by depthwise, because block0 has already double
    // output channel count.
    //
    this.depthwise_AvgMax_Or_ChannelMultiplier = 1;

    // All blocks (except block0) uses depthwise ( strides = 1, pad = "same" ) to keep ( height, width ).
    this.depthwiseStridesPad = ValueDesc.StridesPad.Singleton.Ids.STRIDES_1_PAD_SAME;

    this.bKeepInputTensor = false; // No matter bKeepInputTensor, all blocks (except block0) should not keep input tensor.

    this.output_height = stageParams.inferencedParams.outputHeightArray[ blockIndex ];
    this.output_width = stageParams.inferencedParams.outputWidthArray[ blockIndex ];
  }

  /**
   * Called before blockLast is about to be created. Sub-class could override this method to adjust data members.
   */
  configTo_beforeBlockLast() {

    // Besides, the blockLast may use a different depthwise filter size. This is especially true for NotShuffleNet_NotMobileNet.
    this.depthwiseFilterHeight = this.depthwiseFilterHeight_Last;
    this.depthwiseFilterWidth = this.depthwiseFilterWidth_Last;

    this.activation_setup_forBlockLast(); // activation of depthwise1 and pointwise2
  }

  /**
   * Config the activation of pointwise1, depthwise1, pointwise2 and squeeze-and-excitation for block0.
   */
  activation_setup_forBlock0() {
    let stageParams = this.stageParams;

    // 1. depthwise
    {
      // MobileNetV2_Xxx's depthwise has activation (before prefix squeeze-and-excitation and to remedy its pointwise2's no activation).
      //
      if ( ValueDesc.ConvStageType.isMobileNetV2( stageParams.nConvStageTypeId ) ) {
        this.depthwiseActivationId = stageParams.nActivationId;

      // non-MobileNetV2_Xxx's depthwise has no activation. (since they will be done at pointwise2.)
      //
{'fraction_non_alphanumeric': 0.09021001615508885, 'fraction_numerical': 0.00840064620355412, 'mean_word_length': 3.7182926829268292, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '667197', 'n_tokens_mistral': 4553, 'n_tokens_neox': 4389, 'n_words': 1150}