On Sat, Jul 14, 2012 at 2:57 PM, Barry Smith <span dir="ltr"><<a href="mailto:bsmith@mcs.anl.gov" target="_blank">bsmith@mcs.anl.gov</a>></span> wrote:<br><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
   It's already there! :-) From petscsys.h<br>
<br>
/*EC<br>
<br>
    PetscPrecision - indicates what precision the object is using. This is currently not used.<br>
<br>
    Level: advanced<br>
<br>
.seealso: PetscObjectSetPrecision()<br>
E*/<br>
typedef enum { PETSC_PRECISION_SINGLE=4,PETSC_PRECISION_DOUBLE=8 } PetscPrecision;<br>
PETSC_EXTERN const char *PetscPrecisions[];<br>
<br>
<br>
   Matt,<br>
<br>
     The biggest stumbling block I've had with doing this in C is not the part you talk about below but the access like VecSetValues(),   VecAXPY() etc (and all the Mat ones) that<br>
take a scale argument or worse array of scales. How to manage that?  You can pass any precision into any object, or only the precision of the object? Always double precision for these arguments? but that is too limiting .... It is hard for me to see how to prevent an explosion of "templated" interfaces of some kind or another.<br>
</blockquote><div><br></div><div>I am fine with all the regular functions to take PetscScalar. That keeps the interface simple, and I don't think you can make</div><div>a single argument against casting around single scalars or small arrays like VecMDot().</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
   VecGetArray() requesting the precision type may be useful as a starting point.</blockquote><div><br></div><div>I think the only ones we need to be careful with are the direct value access, MatSetValues(), VecGetArray(), etc. For this, I</div>
<div>recommend what I said, have another function which takes an explicit precision, and have the normal method do automatic</div><div>conversion.</div><div><br></div><div>If there are no objections more damaging than that, I think we might as well try it.</div>
<div><br></div><div>   Matt</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="HOEnZb"><font color="#888888"><br>
   Barry<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
<br>
On Jul 14, 2012, at 10:09 AM, Matthew Knepley wrote:<br>
<br>
> I saw a good talk by Chris Baker at SIAM about multiprecision solvers, and was suitably embarrassed that we cannot do<br>
> this. I still strongly believe that templates are the wrong solution, and mucking up perfectly good interfaces with a<br>
> bunch of types we do not care about is wrong. I now have a proposal, outlined below.<br>
><br>
> We start with the idea of a solver with a certain precision, so that each solver can report the precision it computes<br>
> in. Let's restrict ourselves to solvers that only do simple vector operations for the time being. For this then, we<br>
> need a Vec object which stores values and computes with this precision, which will be discussed below. Upon entering,<br>
> we call VecConvert() on the input vector to get the correct precision, which just references the object if no conversion<br>
> is necessary. We VecConvert() the output vector as well before filling it, and the VecConvert() to the output on the way<br>
> out. If not conversion is necessary, we get the ssme pointer for the first convert, and no-op for the second. All<br>
> internal vectors are created with the solver precision. This all depends on having Vec objects of different precisions.<br>
><br>
> I propose we have a different Vec implementation for each precision, maybe saving code by having configure or make<br>
> generate the different precisions from a single template. Most Vec operations work by first calling VecGetArray() and<br>
> then some BLAS calls. I would now have VecGetArray() do copy-in/copy-out if internal storage has a different precision<br>
> than PetscScalar, and add the function VecGetArrayPrecise(Vec v, PetscDataType precision, void **array) which returns<br>
> the internal storage if it is the correct precision, and fails otherwise. If we switch implementations to<br>
> VecGetArrayPrecise(), then vectors will work with other vectors of the same precision and fail otherwise. I think this<br>
> is the correct level of sanity with multi-precision code (demand explicit conversions of dissimilar types).<br>
><br>
> I am only really interested in trying this with float+double (Chris spent all of his time on qd128 which I think has<br>
> no real scientific relevance, but of course we will do this too). The code changes are relatively minor:<br>
>   - Add a precision (PetscDataType) to Vec<br>
>   - One new Vec method, VecGetArrayPrecise()<br>
>   - Make VecDuplicate() respect precision<br>
>   - New Vec implementation for float, built from a template by Python<br>
> If we give a float Vec to Picard, it should compute everything in float since the Vecs are duplicated. We can add the<br>
> solver convert code later if everything works as expected. I think the first interesting test would be a nonlinear float<br>
> preconditioner for a double SNES.<br>
><br>
> I am not interested in being able to use whatever type I want everywhere. That will never work, and its not clear there is<br>
> any benefit anyway. What I want is just to have solvers of different precisions work together with explicit conversion at<br>
> the boundary.<br>
><br>
> Why will this not work? If it will, why will it not be as easy as stated above?<br>
><br>
>     Matt<br>
><br>
> --<br>
> What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead.<br>
> -- Norbert Wiener<br>
<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead.<br>
-- Norbert Wiener<br>