Conversation
Memory benchmark result| Test Name | %Δ | Master (MB) | PR (MB) | Δ (MB) | Time PR (s) | Time Master (s) |
| -------------------------------------- | ------------ | ------------------ | ------------------ | ------------ | ------------------ | ------------------ |
test_objective_jac_w7x | 5.13 % | 3.836e+03 | 4.033e+03 | 196.80 | 36.55 | 31.33 |
test_proximal_jac_w7x_with_eq_update | -0.57 % | 6.799e+03 | 6.760e+03 | -38.56 | 161.42 | 159.80 |
test_proximal_freeb_jac | -0.18 % | 1.317e+04 | 1.315e+04 | -24.30 | 78.62 | 78.32 |
test_proximal_freeb_jac_blocked | -0.61 % | 7.640e+03 | 7.593e+03 | -46.61 | 67.77 | 69.78 |
test_proximal_freeb_jac_batched | -0.06 % | 7.599e+03 | 7.595e+03 | -4.29 | 68.28 | 69.39 |
test_proximal_jac_ripple | -1.73 % | 7.619e+03 | 7.487e+03 | -131.84 | 69.21 | 70.22 |
test_proximal_jac_ripple_spline | -1.05 % | 3.481e+03 | 3.444e+03 | -36.45 | 70.70 | 73.12 |
test_eq_solve | -2.02 % | 2.062e+03 | 2.021e+03 | -41.73 | 124.94 | 125.97 |For the memory plots, go to the summary of |
f0uriest
left a comment
There was a problem hiding this comment.
Is there still a plan to have classes for different diagnostics? I didn't realize those would each be objectives. I thought it would be something like
class AbstractDiagonstic(ABC, Optimizeable?):
def compute_measurement(self, eq, field):
...
def _compute_from_B(self, B):
...
class RogowskiCoil(AbstractDiagnostic):
...
class MeasurementError(_Objective):
def __init__(self, eq, field, diagnostic, target, weight):
...
def compute(self, params):
B = self.field.compute_magnetic_field(...)
return self.diagnostic._compute_from_B(B)I like the idea of separate classes for different diagnostics, independent from the Objective API for doing analysis etc. The diagnostic only knows about how to compute a synthetic measurement, but nothing about the expected value from experiment. The objective then couples the diagonstic class with the target/bounds/uncertainty from experiment to compute a residual/z score.
Another thing to consider is uncertainties. We can handle simple uncorrelated uncertainty with weight=1/uncertainty but often there are off diagonal terms in the covariance matrix that are important. This might require the Measurement objective to have special logic in compute_scaled_error etc.
At some point we may also want to consider optimizing the placement of diagnostics, this is something that a lot of experimentalists think about and could be a good use of DESC. So then AbstractDiagnostic would also inherit from Optimizeable
|
|
||
| """ | ||
| super().build(use_jit=use_jit, verbose=verbose) | ||
| assert hasattr(self, "_all_eval_x_rpz"), ( |
There was a problem hiding this comment.
_all_eval_x_rpz might be better as an abstract property/attribute itself?
Also, the variable name implies it but should document somewhere that x here is in R,phi,Z. And that the compute function should expect B in R,phi,Z basis as well
There was a problem hiding this comment.
I can do that, but it seems that that way does not explicitly require that the attributes themselves be set, only that the properties exist?
Like one still could instantiate a subclass with the property _all_eval_x_rpz but never fill it?
| _compute_A_or_B_from_CurrentPotentialField, | ||
| ) | ||
|
|
||
| self._compute_A_or_B_from_CurrentPotentialField = ( |
There was a problem hiding this comment.
can't this just be a class method?
There was a problem hiding this comment.
I can't import it without getting a circular import so I have to import it locally. I could do that as a class method I guess
These are all good points, I mainly shied away from the optmizable diagnostics part because it is gonna add a lot more hassle on my part and I just wanted to get something working for my project... |
|
Yeah, I'm definitely not saying we have to worry about optimizing sensor placement or dealing with full covariance matrices now, but I just want to make sure we give it a bit of thought so that we don't design ourselves into a corner that will require major API changes to add those features later. I think broadly we could copy the API from For correlated uncertainty, if its only correlated within a single objective that could be handled by just allowing |
|
API Issues I am wrestling with currently:
|
|
One possible idea would be to add something like a |
Doing something like this might involve making many redundant classes just to have for example a RogowskiCoil for each curve type: RogowskiCoilFourierXYZ, RogowskiCoilSplineXYZ etc. I can not think of a way to have separate diagnostics which are also optimizable and avoid this |
|
For correlated measurements, we should be able to use most of our existing machinery if we just make a new objective called something like MeasurementError which takes in all of the diagnostics, and the passed-in weights can be either a single numpy array (corresponding to a diagonal covariance matrix, where the weights passed in are the inverse of the square root of the diagonal variances), or it can be a (positive def, symmetric) matrix W which is assumed to be the inverse of the (also positive def, symmetric) covariance matrix Since these are pos def symmetric, we can do Cholesky to factor Then we can modify its compute_scaled (or maybe its _scale or whatever) to return where |
Adds new class
AbstractDiagnosticwhich is a new base class for synthetic diagnostic objects.AbstractDiagnosticrealizations must_compute_datamethod already in this_computemethod which takes in the magnetic field (or vector potential) at the points they require (for e.g. integration over a rogowski coil), as well as a dict of aux data_compute_datamethod for compiting this aux data fromeq_params,field_paramsas well as its owndiag_params(here for example aRogowskiCoilcomputes its geometric information. A ThomsonScattering may here compute the intersection of the chord and the plasma, as another example)Current realizations:
RogowskiCoilXXXfor each coil type,PointBMeasurementsfor ptwise B measurements like magnetic probes.DiagnosticSetobjects are collections ofAbstractDiagnosticrealizationsMixedCoilSetfor now, its job is to collect the diagnostics in one object,MeasurementErrorit can be computed efficientlyTODO
_diagnosticsto be a static attr to avoid JAX issues withMeasurementErrorbut not sure why, maybe because we are using its method? but that should be fine I thought... so I dont think that is the issueMeasurementError, allow weights to be a matrix and assume it to be the inverse of the covariance, and Cholesky factor it and make _scale method for this class using that factorizationResolves #1783