Since Microsoft released most recent update of Dynamics AX (I mean SP1 rollup 7), I would like to point the readers of my blog to very important update in this version, which can dramatically increase performance of one of the critical, but slow operations from production module of Axapta.

I am talking about BOM Calculation process, which in previous version can only be started in single-thread mode. I heard about implementations, where BOM recalculation for all BOMs in the system were taking more then 2 days.

Somewhere in the last December, Microsoft released hotfix KB2487033, which supported multi-threaded execution of BOM calculation and now this feature included into RollUp7.

This nice feature works only if BOM Calculation is started not for a given ItemId, but for all BOMs in the system (say – from costing version form) and if user specified batch-mode calculation of this batch job. In this case, the system behaves the following way:

BOM levels are recalculated

Tables bomCalcItemTask and bomCalcItemInventoryDimensionTask are populated with item ids and item inventory dimensions to calculate. (These two steps are also executed in standalone, single-threaded mode of calculation).

In single-threaded mode, the system starts to iterate over the items to calculate, starting from the lowest level components (with numerically highest BOM Level).

In multi-threaded mode, system SPAWNS a certain number of helper tasks for EVERY BOM level to be calculated. It also set dependencies between tasks of every BOM Level, so jobs of BOM Level 7 starts only after tasks of BOM Levels 8 and 9 are completed, tasks of BOM Level 5 depends on tasks of BOM levels 9,8,7,6 and so on…

Then in multi-threaded mode, system just calculates every BOM level in parallel. It is quite meditative experience – to look onto progress of tasks in you BOM Calculation Batch job. 🙂 It also saves you a lot of time. In my case, calculation time dropped from one night to something like 20-30 minutes, moreover 10 minutes of it, were taken for BOM Level recalculation (I guess, it is principally not parallelizable task by it nature).

Nevertheless, there are a few issues, which I would like to share here:

The BOM Calculation process is not robust. If one of the BOMs has an error (quite typical if data were imported from heritage system), then on the first BOM with error, one of the BOM recalculation tasks will terminate. Then next task will try to recalculate the same BOM and terminate again, then next, and so on. As a result, usually, after first calculation you will find out that only 20-30 percent of you items has new prices. Solution for the issue is simple: You should simply put try {} except block somewhere inside BOMCalcJob_All.runBOMCalculation() method, so error in BOM would not terminate the whole job.

When system calculates the number of helper threads, which will be used for BOM Calculation, it is implicitly assumes, that all available batch servers will be used for the calculation. Say, if you have 3 batch servers and every server has 8 maximum batch threads specified in batch server configuration, the system will spawn 24 helper threads for every BOM level. First of all, the number itself is too big, normally 8-12 threads should be enough. Morever, if you going to use only one batch server (out of three) for given BOM Calculation batch group, these 24 helper threads will be executed in three steps (8 threads each). So, I recommend to modify BomCalcJobItemTaskBatchManager.numberOfBatchSessions() method to return more reasonable number of threads if you have more then 1 batch server or if your batch server has too many batch threads available.

Also, as kind of shameless self-promotion 🙂 , I want to mention that for one of my project I made a clone of the feature, but the clone, which calculates in parallel only ONE BOM with all dependent sum-BOMs and items.