3. API changes¶
The following changes have been made to the PopART API in SDK 1.2. This may require you to change your code.
3.1. Breaking changes¶
Warning
These will require changes to any code that uses them.
3.1.1. Deprecated session options removed¶
The deprecated option ignoreData has been removed.
# Old
opts.ignoreData = True
# New equivalent:
opts.syntheticDataMode = popart.SyntheticDataMode.Zeros
The deprecated enableVirtualGraphs and autoVirtualGraph options have
been removed.
# Old (manual sharding):
opts0.enableVirtualGraphs = True
opts0.autoVirtualGraph = False # the default
# New equivalent:
opts0.virtualGraphMode = popart.VirtualGraphMode.Manual
# Old (auto sharding):
opts1.enableVirtualGraphs = True
opts1.autoVirtualGraph = True
# New equivalent:
opts1.virtualGraphMode = popart.VirtualGraphMode.Auto
3.1.2. Optimizer updating API¶
Session::updateOptimizerandSession::optimizerFromHosthave been merged into a single call,Session::updateOptimizerFromHost.The first call to
Session::optimizerFromHosthas been moved insideSession::prepareDevice, so it need only be called when updating the optimizer from that used to construct theSessioninstance.Since the methods must be called together anyway in order to have an effect on the session, they have been merged to reduce the number of required API calls.
# Old:
session.prepareDevice()
session.optimizerFromHost()
session.run(stepio)
session.updateOptimizer(newOpt)
session.optimizerFromHost()
session.run(stepio)
# New equivalent:
session.prepareDevice()
session.run(stepio)
session.updateOptimizerFromHost(newOpt)
session.run(stepio)
3.1.3. Loss API¶
The three
Losstypes supported by PopART (L1Loss,NllLossandIdentityLoss) are now all exposed to theBuilderinterface. This means that they will act like other operators. As in torch, users can sum and scale the output value of losses to produce a combined loss scalar.These losses still take a reduction argument. However, the former
popart.ReductionType.MEANandpopart.ReductionType.SUM, have been renamed topopart.ReductionType.Meanandpopart.ReductionType.Sumrespectively (see Consistent enumeration styles).Previously, the reduction did not actually take place but simply affected the gradient calculation. This did not affect training, but was restrictive as it could mean that two losses outputting different size tensors could not be added together. These reduction arguments now result in a reduction to scalar which is consistent with
meanandsumreduction in PyTorch and allows losses of any input shape to be added together.There is now an additional reduction type,
popart.ReductionType.NoReductionwhich produces a tensor output similar to reduction typenonein PyTorch. ForL1Loss, the output is the same size as the input, so this is semantically equivalent toAbswith an optional scale parameter.The
InferenceSessionconstructor no longer takes alossesinput argument. Any losses you wish to add to your model for the purposes of evaluation must be done in the ONNX model.The
TrainingSessionconstructor no longer takes a list ofpopart.Loss` instances as a ``lossesargument. Instead it takes theTensorIdof a scalar loss tensor as a (renamed)lossargument.The default
ReductionTypefor all losses has changed fromReductionType::SumtoReductionType::Meanto match that of PyTorch
## For an InferenceSession with loss for evaluation
# Old:
probs = builder.aiOnnx.softmax([finalActs])
losses = [popart.NllLoss(probs, labels, "nllLoss")
session = popart.InferenceSession(losses=losses, dataFeed=popart.DataFlow(1, ["nllLoss"]), ...)
# New equivalent:
probs = builder.aiOnnx.softmax([finalActs])
nll = builder.aiGraphcore.nllloss([probs, label])
session = popart.InferenceSession(dataFlow=popart.DataFlow(1, [nll]), ...)
## For a TrainingSession
# Old:
probs = builder.aiOnnx.softmax([finalActs])
losses = [popart.NllLoss(probs, labels, "nllLoss") # can optionally reduce to scalar
session = popart.TrainingSession(losses=losses, ...)
# New equivalent:
probs = builder.aiOnnx.softmax([finalActs])
nll = builder.aiGraphcore.nllloss([probs, label], reduction=popart.ReductionType.Mean) # must reduce to scalar
session = popart.TrainingSession(loss=nll, ...)
3.1.4. Consistent enumeration styles¶
All enums are now PascalCase and some have changed to avoid conflicts with the
Python None keyword.
Old |
New |
|---|---|
|
|
# Old:
popart.PatternsLevel.NONE
popart,InitType.NONE
popart,InitType.ZERO
# New equivalent:
popart.PatternsLevel.NoPatterns
popart.InitType.NoInit
popart.InitType.Zero
All other enums have the same name, just with PascalCase, in place of ALLCAPS, where it wasn’t already.
3.1.5. Session constructor argument names¶
dataFeedhas changed todataFlowto match the PopART C++ class name.passeshas changed topatternsto match the PopART C++ class name.
# Old:
session = popart.TrainingSession(
dataFeed=popart.DataFlow(1, []),
passes=popart.Patterns(popart.PatternsLevel.NONE), ...)
# New equivalent:
session = popart.TrainingSession(
dataFlow=popart.DataFlow(1, []),
patterns=popart.Patterns(popart.PatternsLevel.None), ...)
3.1.6. Exception name change¶
PrepareDeviceException is now renamed popart.OutOfMemoryException.
# Old:
try:
session.prepareDevice()
except popart.PrepareDeviceException as e:
#handle exception
# New equivalent:
try:
session.prepareDevice()
except popart.OutOfMemoryException as e:
#handle exception
3.2. Non-breaking changes¶
These changes are designed to reduce the verbosity of PopART code.
3.2.1. Overloaded DataFlow constructor¶
# Old:
anchorMap = {
t0: popart.AnchorReturnType("ALL")
t1: popart.AnchorReturnType("ALL")
}
dataFlow = popart.DataFlow(1, anchorMap)
# New equivalent:
dataFlow = popart.DataFlow(1, [t0, t1])
# Old:
anchorMap = {
t0: popart.AnchorReturnType("FINAL")
t1: popart.AnchorReturnType("FINAL")
}
dataFlow = popart.DataFlow(1, anchorMap)
# New equivalent:
dataFlow = popart.DataFlow(1, [t0, t1], popart.AnchorReturnType("FINAL"))
3.2.2. Overloaded Builder::addInputTensor method¶
# Old:
to_info = popart.TensorInfo("FLOAT", [2, 3, 4])
t0 = popart.addInputTensor(to_info)
# New equivalent:
t0 = popart.addInputTensor("FLOAT", [2, 3, 4])