Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
# Elements to allocate to threads - always will be used even in case when parallelism is not required
If( sParFilter @= '' );
    # MDX that is used by default to drive parallelization set when no filter is specified
    sDimClrMDX = Expand( 'TM1FILTERBYLEVEL(DESCENDANTS([%sDimParClr%].[Total %sDimParClr%]), 0)' );
Else;
    # We need to provide MDX out of Bedrock style filter depending on the threadID
    sFind = sParFilter;
    nTokens = 0;
    sElemMDX = '';
    While( sFind @<> '' );
        nToken = SCAN( cElementDelim, sFind );
        nToken = IF( nToken = 0, LONG( sFind ) + 1, nToken );
        sToken = TRIM( SUBST( sFind, 1, nToken - 1 ));
        sElemMDX = sElemMDX | If( nTokens = 0, '', '+' ) | Expand( 'TM1FILTERBYLEVEL(DESCENDANTS([%pDimPar%].[%sToken%]), 0)' );
        sFind = DELET( sFind, 1, nToken );
        nTokens = nTokens + 1;
    End;
    If( nElementReplace <> 0 );
        sDimClrMDX = Expand( 'GENERATE(%sElemMDX%, FILTER(TM1SUBSETALL([%sDimParClr%]), [%pDimPar%].CurrentMember.Properties(''%sDimParClr% ID'') = [%sDimParClr%].CurrentMember.Name))' );
    Else;
        #Note: sDimParClr = pDimPar makes this possible
        sDimClrMDX = sElemMDX;
    EndIf;
EndIf;

sSubClrLen = cSubSrc | '_CLR_LEN';
ExecuteProcess('}bedrock.hier.sub.create.bymdx',
  'pDim', sDimParClr,
  'pSub', sSubClrLen,
  'pMDXExpr', sDimClrMDX,
  'pConvertToStatic', 1,
  'pTemp', cTemp
);
nElementsClr = SubsetGetSize( sDimParClr, sSubClrLen );
  • Prolog (after spawning child threads)

Code Block
If ( nMaxThreads > 1 & nThreadID >= 0 );
  # Allocate working space to threads - indices start and step
  If( cThreadMonitoringEnabled <> 0 );
    nLowerIndex = nThreadID;
    nThreadStep = nThreads - 1;
  Else;
    nLowerIndex = nThreadID + 1;
    nThreadStep = nThreads;        
  EndIf;
Else;
  # Regular processing - single thread
  nThreadStep = 1;
  nLowerIndex = 1;
EndIf;
  • Prolog (when creating source and target views)

Code Block
If( nLowerIndex <= nElementsClr & (nMaxThreads =1 % nMaxThreads > 1 & ( cThreadMonitoringEnabled <> 0 & nThreadID <> 0 % cThreadMonitoringEnabled = 0)));
  # Allocate working space within parallelized dimension
  SubsetCreate( sDimParClr, cSubClr, cTemp );
  
  n = nLowerIndex;
  nSubsetItem = 1;
  sElemMDX = '';
  While ( n <= nElementsClr );
    sElem = SubsetGetElementName( sDimParClr, sSubClrLen, n );
    If( nLogOutput > 1 );
      LogOutput( 'Info', Expand( 'Thread %pThreadID% allocating %sElem% for target data clear.' ));
    EndIf;
    SubsetElementInsert( sDimParClr, cSubClr, sElem, nSubsetItem );
    sElemMDX = sElemMDX | IF( sElemMDX @= '', '', '+' ) | Expand('{[%sDimParClr%].[%sElem%]}');
    nSubsetItem = nSubsetItem + 1;
    n = n + nThreadStep;
  End;
  
  If( nElementReplace <> 0 );
      sMDX = Expand( 'TM1FILTERBYLEVEL(GENERATE(%sElemMDX%, FILTER(TM1SUBSETALL([%pDimPar%]), [%pDimPar%].CurrentMember.Properties(''%sDimParClr% ID'') = [%sDimParClr%].CurrentMember.Name)), 0)' );
  Else;
      #Note: sDimParClr = pDimPar makes this possible
      sMDX = sElemMDX;
  EndIf;
  
  ExecuteProcess('}bedrock.hier.sub.create.bymdx',
    'pDim', pDimPar,
    'pSub', cParSubSrc,
    'pMDXExpr', sMDX,
    'pConvertToStatic', 1,
    'pTemp', cTemp
  );
  
  If( nLogOutput <> 0 );
    nElem = SubsetGetSize( pDimPar, cParSubSrc );
    nElemClr = SubsetGetSize( sDimParClr, cSubClr );
    If( nLogOutput > 1 );
        nSubsetItem = 1;
        While ( nSubsetItem <= nElem );
            sElem = SubsetGetElementName( pDimPar, cParSubSrc, nSubsetItem );
            LogOutput( 'Info', Expand( 'Thread %pThreadID% allocating %sElem% for data source.' ));
            nSubsetItem = nSubsetItem + 1;
        End;
    EndIf;
    sElem = NumberToString( nElem );
    sElemClr = NumberToString( nElemClr );
    LogOutput( 'Info', Expand( 'Thread %pThreadID% allocated %sElem% elements from %pDimPar% for data source and %sElemClr% elements from %sDimParClr% for target data clear.' ));
  EndIf;
  
  #Region Prepare Source Data Filters
  #TODO: Repeat for every dimension that is allowed for parallel processing, define process parameter for each
  sDimName = 'DIMENSION_NAME_1';
  sPar = pDIMENSION_NAME_1;
  If( TRIM( sPar ) @<> '' & pDimPar @<> sDimName );
    sFilter = sFilter | cDimensionDelim | sDimName | cElementStartDelim | sPar;
  EndIf;
  #EndRegion Prepare Source Data Filters
  
  #Region Create Data Source
  #EndRegion Create Data Source
  
  # Elements in parallel dimenison as per thread allocation were already present in the subset - we need to exclude elements that were provided by Bedrock by default as we have omitted the parallel dimension from filter - these follow after all elements generated for parallel processing
  SubsetDeleteAllElements( pDimPar, cSubSrc );
  nElem = 1;
  nElems = SubsetGetSize( pDimPar, cParSubSrc );
  While( nElem <= nElems );
    sElem = SubsetGetElementName( pDimPar, cParSubSrc, nElem );
    SubsetElementInsert( pDimPar, cSubSrc, sElem, nElem );
    nElem = nElem + 1;
  End;
  
  #Region Create Data Target
  #EndRegion Create Data Target

  #TODO: Repeat for every dimension that is allowed for parallel processing, define process parameter for each  
  sParVal = Expand( '%pDIMENSION_NAME_1%' );
  sDimNameOp = 'DIMENSION_NAME_1';
  sDimNamePlan = 'DIMENSION_EQ_NAME_1';
  If( TRIM( sParVal ) @<> '' & pDimPar @<> sDimNameOp );
      sFind = sParVal;
      nTokens = 0;
      sElemMDX = '';
      While( sFind @<> '' );
          nToken = SCAN( cElementDelim, sFind );
          nToken = IF( nToken = 0, LONG( sFind ) + 1, nToken );
          sToken = TRIM( SUBST( sFind, 1, nToken - 1 ));
          sElemMDX = sElemMDX | If( nTokens = 0, '', '+' ) | Expand( 'TM1FILTERBYLEVEL(DESCENDANTS([%sDimNameOp%].[%sToken%]), 0)' );
          sFind = DELET( sFind, 1, nToken );
          nTokens = nTokens + 1;
      End;
      sMDX = Expand( 'GENERATE(%sElemMDX%, FILTER(TM1SUBSETALL([%sDimNamePlan%]), [%sDimNameOp%].CurrentMember.Properties(''%sDimNamePlan% ID'') = [%sDimNamePlan%].CurrentMember.Name))' );
      SubsetCreateByMDX( cSubClr, sMDX, sDimNamePlan, cTemp );
      SubsetElementInsert( sDimNamePlan, cSubClr, DIMNM( sDimNamePlan, 1 ), 1 );
      SubsetElementDelete( sDimNamePlan, cSubClr, 1 );
      ViewSubsetAssign( cCubTgt, cViewClr, sDimNamePlan, cSubClr );
  EndIf;
  
  #Region Clear Data Target
  #EndRegion Clear Data Target
  
  #Region Assign Data Source to TI
  #EndRegion Assign Data Source to TI
Else;
  DataSourceType = 'NULL';
EndIf;