...
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; |