Setting options on matrices obtained from a DM
On Thu, Jul 23, 2009 at 8:15 AM, Jed Brown jed at 59a2.org wrote: Matthew Knepley wrote: On Wed, Jul 22, 2009 at 3:57 PM, Jed Brown jed at 59a2.org wrote: Matthew Knepley wrote: No comments? Not even This is complete shit!? Heh, it might be overkill and, if I understand you correctly, I think it could be a headache. There is a reasonable amount of code in the various interfaces to ensure some sequencing, but delayed evaluation is tough to reason about. When I call a function, I expect strict evaluation, but if you somehow store that call away until it's dependencies are satisfied, I'm likely to see confusing behavior. They way we resole this in configure is to have an execute function. I think this would be pretty much the behavior people expect. What would the calling sequence look like for getting a Mat from a DM? MatCreate() in any order the setup functions, such as MatSetSizes() MatPreallocate() MatSetType() each one of these calls a private function like MatSetSizes_outoforder() which registers the method and user data for later processing MatSetUp() (which can be called by anyone, executes) Who calls execute? Am I not allowed to call MatSetXXX() after Whoever calls setup. This allows the user to choose to do it, or not, and its the current paradigm for most objects in PETSc. MatExecute()? What about MatGetXXX() before MatExecute()? It will reregister that function, so you would need another SetUp() call, exactly the same interface we have now. MatGet() has exactly the same interface too, namely things might not be available. That object would not have to be seen. You would just have a pc.require(SetSizes, m, n); pc.require(...) pc.setup() Is the Mat/PC/whatever interface or implementation calling this? No, wrappers as I show above. The user interface would not change. The config object would need to take ownership of the various arguments, including those that are not PetscObject (like preallocation arrays). No, the registered call would. The fact that someone has to explicitly call execute makes this solution look a lot like a factory, minus the type-level distinction. With configure, the environment is fixed and once a given set of dependencies are satisfied, an immutable object can be created. With PETSc objects, the user might insert arbitrary imperative code (including queries and setting up one object based on the state of another) during the definition of the environment. I fear that a set properties, then execute model would be frusratingly restrictive. It is what we have now. I do not understand any of your objections. Matt Jed -- What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead. -- Norbert Wiener -- next part -- An HTML attachment was scrubbed... URL: http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20090723/f7c8c3ff/attachment.html
Setting options on matrices obtained from a DM
Matthew Knepley wrote: MatExecute()? What about MatGetXXX() before MatExecute()? It will reregister that function, so you would need another SetUp() call, exactly the same interface we have now. But the user wants to call MatGetXXX() and use the result right away (instead of getting a request object or passing a continuation to be executed when the result is available). The whole point of the continuation is to perform a side-effect which is going to cause confusing behavior. Currently they get an error if the result isn't available. With the register attributes, then execute model, the result will almost never be available so everything they might do would go into a continuation. We could probably make this work (even with reasonable syntax) in a language like Haskell, but in an impure strict language I think it will snowball into a mess of side-effecting continuations being called at peculiar times. Jed -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 260 bytes Desc: OpenPGP digital signature URL: http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20090723/7c7ba99f/attachment.pgp
Setting options on matrices obtained from a DM
On Thu, Jul 23, 2009 at 9:45 AM, Jed Brown jed at 59a2.org wrote: Matthew Knepley wrote: MatExecute()? What about MatGetXXX() before MatExecute()? It will reregister that function, so you would need another SetUp() call, exactly the same interface we have now. But the user wants to call MatGetXXX() and use the result right away (instead of getting a request object or passing a continuation to be executed when the result is available). The whole point of the continuation is to perform a side-effect which is going to cause confusing behavior. Currently they get an error if the result isn't available. With the register attributes, then execute model, the result will almost never be available so everything they might do would go into a continuation. We could probably make this work (even with reasonable syntax) in a language like Haskell, but in an impure strict language I think it will snowball into a mess of side-effecting continuations being called at peculiar times. It would be impossible for me to disagree more strongly. A user cannot get information that is not setup in the current model. I really do not understand your objection, and the Haskell discussion is bizarre. All I am suggestion is that we use a better model for remembering what to do. Barry suggests that individual functions remember data and when to execute it. I am suggesting we use a uniform model for both remembering the data and the dependecies. That is it. Very simple. Matt Jed -- What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead. -- Norbert Wiener -- next part -- An HTML attachment was scrubbed... URL: http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20090723/844d5fe4/attachment.html
Setting options on matrices obtained from a DM
Matthew Knepley wrote: It would be impossible for me to disagree more strongly. A user cannot get information that is not setup in the current model. I really do not understand your objection, and the Haskell discussion is bizarre. All I am suggestion is that we use a better model for remembering what to do. If I call MatGetXXX(), I expect to either get a meaningful and usable result, or get an error. As I understand your suggestion, I wouldn't get that unless SetUp had been called. But I wanted to do something with that result which means that I will either get a request object (I keep control of when I do that thing with the result, this will be a PITA) or I give you a continuation for whatever I wanted to do with it (but then I don't know when it will be executed which is confusing because the continuation will have side-effects, and it's a PITA to do continuations in C/C++/etc). In Haskell, it's possible to maintain control of side-effects and have sane syntax for all these continuations, but we don't have (or want to be using) Haskell for this. To be concrete, someone is going to do: TSGetSNES SNESGetKSP KSPGetPC PCGetOperators MatGetVecs /* do something with the matrices and vectors */ If the objects are not sufficiently set up when this is called, the current model will give an error which is easy to understand. With your model, if we haven't called SetUp(), none of these objects will be available, so instead we'll pass a continuation for everything to do with them. In pseudo-Haskell and skipping the obvious sugar, we'd have something like TSGetSNES ts (\snes - SNESGetKSP snes (\ksp - KSPGetPC ksp (\pc - PCGetOperators pc (\(a,p) - MatGetVecs p (\(x,y) - -- do something with a,x,y ) The monad that this runs under would be able to control side-effects. That is, we have a type signature like XXXGetYYY :: x - (y - M a) - M a where the monad M controls the side-effects. Doing this in C would be insane which means that I must be misunderstanding what you want to do. Jed -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 260 bytes Desc: OpenPGP digital signature URL: http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20090723/cdab5073/attachment.pgp
Setting options on matrices obtained from a DM
On Thu, Jul 23, 2009 at 10:21 AM, Jed Brown jed at 59a2.org wrote: Matthew Knepley wrote: It would be impossible for me to disagree more strongly. A user cannot get information that is not setup in the current model. I really do not understand your objection, and the Haskell discussion is bizarre. All I am suggestion is that we use a better model for remembering what to do. If I call MatGetXXX(), I expect to either get a meaningful and usable result, or get an error. As I understand your suggestion, I wouldn't get that unless SetUp had been called. But I wanted to do something with that result which means that I will either get a request object (I keep control of when I do that thing with the result, this will be a PITA) or I give you a continuation for whatever I wanted to do with it There is no way we would be doing conintuations. Why even bring this up? This just complicates the discussion and distracts from the main issues. The answer is incredibly easy and straightforward. Just like MANY functions in PETSc, you will not get the correct answer until things have been initialized. This just sounds like arguing for the sake of argument. Matt (but then I don't know when it will be executed which is confusing because the continuation will have side-effects, and it's a PITA to do continuations in C/C++/etc). In Haskell, it's possible to maintain control of side-effects and have sane syntax for all these continuations, but we don't have (or want to be using) Haskell for this. To be concrete, someone is going to do: TSGetSNES SNESGetKSP KSPGetPC PCGetOperators MatGetVecs /* do something with the matrices and vectors */ If the objects are not sufficiently set up when this is called, the current model will give an error which is easy to understand. With your model, if we haven't called SetUp(), none of these objects will be available, so instead we'll pass a continuation for everything to do with them. In pseudo-Haskell and skipping the obvious sugar, we'd have something like TSGetSNES ts (\snes - SNESGetKSP snes (\ksp - KSPGetPC ksp (\pc - PCGetOperators pc (\(a,p) - MatGetVecs p (\(x,y) - -- do something with a,x,y ) The monad that this runs under would be able to control side-effects. That is, we have a type signature like XXXGetYYY :: x - (y - M a) - M a where the monad M controls the side-effects. Doing this in C would be insane which means that I must be misunderstanding what you want to do. Jed -- What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead. -- Norbert Wiener -- next part -- An HTML attachment was scrubbed... URL: http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20090723/9a58b9d5/attachment.html
Setting options on matrices obtained from a DM
Matthew Knepley wrote: There is no way we would be doing conintuations. Why even bring this up? This just complicates the discussion and distracts from the main issues. The answer is incredibly easy and straightforward. Just like MANY functions in PETSc, you will not get the correct answer until things have been initialized. This just sounds like arguing for the sake of argument. I should of course get an error, not a wrong answer, but that's not the issue here. It is useful to be able to call XGetY() once the X has enough information to provide Y, but before it has enough information for XSetUp() to be called. This is fine with the current model. With your model, it looks like I would always have to wait until *after* SetUp has been called. I believe there are several circumstances where it is not possible to get access to the object after setup and before whatever else happens. This apparent locking causes (at least in other codes) the introduction of multiple SetUp-like calls which are more of a pain. If you are confident that you can restructure things so that it is always possible for XSetUp() to called before you need to call XGetY(), then I have no objections. Jed PS: Continuations are a way to make whatever you want happen at the appropriate time with respect to SetUp, but they are obviously insane for this purpose. Request objects are probably worse. -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 260 bytes Desc: OpenPGP digital signature URL: http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20090723/89ceaa12/attachment.pgp
Setting options on matrices obtained from a DM
If I get a matrix from a DM, I usually do something like PetscOptionsGetString(NULL,-q1_mat_type,mtype,sizeof(mtype),NULL); DMGetMatrix(dm,mtype,Jp); so that the type can be changed on the command line (I frequently switch between preconditioners that can use BAIJ and those that cannot). But, MatSetFromOptions never gets called. If I add MatSetOptionsPrefix(Jp,q1_); MatSetFromOptions(Jp); after the above, then preallocation will be blown if I change anything on the command line. This includes setting block size for AIJ formats (I think BAIJ should implement MatSetBlockSize and just confirm that it matches, but that's a separate issue) so MatSetValuesBlocked cannot even assemble the correct matrix. To rectify this, I think that DMGetMatrix either must have enough information to call MatSetFromOptions (like the prefix) or preallocation should be separated from setting the sizes (so the user can get the matrix, call MatSetFromOptions, and then ask the DM to preallocate). In the former case, we have functionality that is essentially inaccessible from code (PetscOptionsSetValue is a workaround). The latter significantly complicates matters. Note that since the user may get multiple matrices from a DM, to be used for different purposes, it's not okay to use the DM's prefix as the Mat's prefix. Any preferences here? I'm happy with any solution in which the user doesn't have to do an inordinate amount of work to make the following work. -q1_mat_type baij -q1_mat_type aij -mat_no_inode -q1_mat_type crl Jed -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 260 bytes Desc: OpenPGP digital signature URL: http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20090722/785e6308/attachment.pgp
Setting options on matrices obtained from a DM
Barry Smith wrote: My eventual goal is to remove all hidden MatCreate()'s and instead have Mat's passed in as arguments. So MatLoad() would take a Mat as an argument, as would DAGetMatrix() One could then set as much or a as little as a Mat as they like before passing it in. They could set the type, they could set the sizes, they could set the prefix. Right, though setting sizes before DAGetMatrix() wouldn't be meaningful. I think this is the direction you want? Will it satisfy all your needs? MatCreate(). MatSetOptionsPrefix() MatSetFromOptions() DAGetMatrix() This will work at present, but it's not perfect (without Mat adjustments). Some options would be set as a consequence of the MatSetSizes() which occurs within DMGetMatrix() (ops-create() is saved until the sizes are known). If a matrix type implements MatSetFromOptions (currently just SchurComplement), that function would never get called in this scheme (because that operation won't be set until the sizes are known). This could be handled by modifying the matrix types so that MatCreate_XXX() could be called before MatSetSizes(), but this is nontrivial. Jed -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 260 bytes Desc: OpenPGP digital signature URL: http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20090722/1bfbe283/attachment.pgp
Setting options on matrices obtained from a DM
Barry Smith wrote: Could you call MatSetFromOptions() twice, once before the DAGetMatrix() call to set the type and then after the DAGetMatrix() to set particular options for what you set? This is okay as long as we don't get more global matrix options (this state appears to be stable). It's a little clumsy to have to call that function twice, and because preallocation comes last in the usual idiom: MatCreate MatSetSizes MatSetFromOptions MatXXXSetPreallocation If the matrix type wants anything (programmatic) to be done before preallocation, we don't have a way to do it with your scheme. That is, although we might have set the type before calling DAGetMatrix(), the type isn't actually set until the sizes are known, so we can't call any MatXXXSetYYY() before calling DAGetMatrix(). At the moment, I can't think of a case were this would be a problem. The same applies to anything that could be set by MatSetFromOptions_XXX, but needs to be done before preallocation. The hypothetical DMGetMatrix /* sets sizes, not preallocation or type */ MatSetOptionsPrefix MatSetFromOptions DMSetMatPreallocation makes it possible to set all the options in MatSetFromOptions, and allows any MatXXXSetYYY to be called before preallocation. I can't think of a case where this is more limiting, but that doesn't mean it doesn't exist. It does mean two DM functions rather than one which is not ideal. We decided along time ago to cluster all the option setting in XXXSetFromOptions() but it does impose some limitations. Too many limitations. Are there other models? Having random XXGetOption() in any old method is dangerous because it is hard to know what and where options are going to be set so I think we are stuck with the XXXSetFromOptions() model. I agree that keeping as much as possible in XXXSetFromOptions is the best alternative. I've seen the mess caused by having too many places in which options are consulted. The PETSc creation model is much nicer to work with than factory objects which enforce more sequencing. Jed -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 260 bytes Desc: OpenPGP digital signature URL: http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20090722/5b139481/attachment.pgp
Setting options on matrices obtained from a DM
On Wed, Jul 22, 2009 at 12:20 AM, Barry Smithbsmith at mcs.anl.gov wrote: On Jul 21, 2009, at 7:47 PM, Jed Brown wrote: Barry Smith wrote: ? ?This is just a limitation of the current implementation due to the way the design evolved over time. There is nothing intrinsic to the abstract design of PETSc that prevents the type from being properly processed before the sizes are set. I agree 100% with you.. the only issue are tons of code to review and fix :-( ? This is really yucky API you propose here; that no sane person would propose except to work around a shortfall in the current implementation. We could start fixing Vec, next go for Mat ... -- Lisandro Dalc?n --- Centro Internacional de M?todos Computacionales en Ingenier?a (CIMEC) Instituto de Desarrollo Tecnol?gico para la Industria Qu?mica (INTEC) Consejo Nacional de Investigaciones Cient?ficas y T?cnicas (CONICET) PTLC - G?emes 3450, (3000) Santa Fe, Argentina Tel/Fax: +54-(0)342-451.1594
Setting options on matrices obtained from a DM
On Jul 22, 2009, at 9:56 AM, Lisandro Dalcin wrote: On Wed, Jul 22, 2009 at 12:20 AM, Barry Smithbsmith at mcs.anl.gov wrote: On Jul 21, 2009, at 7:47 PM, Jed Brown wrote: Barry Smith wrote: This is just a limitation of the current implementation due to the way the design evolved over time. There is nothing intrinsic to the abstract design of PETSc that prevents the type from being properly processed before the sizes are set. I agree 100% with you.. the only issue are tons of code to review and fix :-( This is really yucky API you propose here; that no sane person would propose except to work around a shortfall in the current implementation. We could start fixing Vec, Ok. VecCreate_Seq()/VecCreate_Seq_Private() and VecCreate_MPI_Private() do the following 1) create the Vec_xxx struct and copy over the function tables (setting the methods) 2) use PetscMapSetUp() to determine the local/global sizes 3) allocate space for the array if needed. What we want is if the sizes are not yet set then it should still copy over the function table (1), but delay (2) and (3) until the sizes are set. This could be done by removing the following from VecSetType() if (vec-map-n 0 vec-map-N 0) { vec-ops-create = r; } else { ierr = (*r)(vec);CHKERRQ(ierr); } and instead have each individual VecCreate_xxx() do the method setup and then if sizes set) do the PetscMapSetUp() and allocate space else) set the vec-ops-create pointer to a new function that does the PetscMapSetUp() and allocate space In other words split the VecCreate_xxx() into two functions and call the second when the sizes are available. Something similar for Matrices? Barry Barry next go for Mat ... -- Lisandro Dalc?n --- Centro Internacional de M?todos Computacionales en Ingenier?a (CIMEC) Instituto de Desarrollo Tecnol?gico para la Industria Qu?mica (INTEC) Consejo Nacional de Investigaciones Cient?ficas y T?cnicas (CONICET) PTLC - G?emes 3450, (3000) Santa Fe, Argentina Tel/Fax: +54-(0)342-451.1594
Setting options on matrices obtained from a DM
On Wed, Jul 22, 2009 at 12:19 PM, Barry Smithbsmith at mcs.anl.gov wrote: On Jul 22, 2009, at 9:56 AM, Lisandro Dalcin wrote: On Wed, Jul 22, 2009 at 12:20 AM, Barry Smithbsmith at mcs.anl.gov wrote: On Jul 21, 2009, at 7:47 PM, Jed Brown wrote: Barry Smith wrote: ? This is just a limitation of the current implementation due to the way the design evolved over time. There is nothing intrinsic to the abstract design of PETSc that prevents the type from being properly processed before the sizes are set. I agree 100% with you.. the only issue are tons of code to review and fix :-( ?This is really yucky API you propose here; that no sane person would propose except to work around a shortfall in the current implementation. We could start fixing Vec, ? Ok. VecCreate_Seq()/VecCreate_Seq_Private() and VecCreate_MPI_Private() do the following 1) create the Vec_xxx struct and copy over the function tables (setting the methods) 2) use PetscMapSetUp() to determine the local/global sizes 3) allocate space for the array if needed. ?What we want is if the sizes are not yet set then it should still copy over the function table (1), but delay (2) and (3) until the sizes are set. This could be done by removing the following from VecSetType() ?if (vec-map-n 0 vec-map-N 0) { ? ?vec-ops-create = r; ?} else { ? ?ierr = (*r)(vec);CHKERRQ(ierr); ?} and instead have each individual VecCreate_xxx() do the method setup and then if sizes set) do the PetscMapSetUp() and allocate space else) set the vec-ops-create pointer to a new function that does the PetscMapSetUp() and allocate space In other words split the VecCreate_xxx() into two functions and call the second when the sizes are available. Something in such direction should work... However... ?Something similar for Matrices? If you do MatSetType(A, MATAIJ), you end-up having a MATSEQAIJ or a MPIMPIAIJ... Vec does not have such aliasing on type names ... I'll try to give look at Vec to figure out what to do in a way that can be ported to Mat taking into account my previous comment. -- Lisandro Dalc?n --- Centro Internacional de M?todos Computacionales en Ingenier?a (CIMEC) Instituto de Desarrollo Tecnol?gico para la Industria Qu?mica (INTEC) Consejo Nacional de Investigaciones Cient?ficas y T?cnicas (CONICET) PTLC - G?emes 3450, (3000) Santa Fe, Argentina Tel/Fax: +54-(0)342-451.1594
Setting options on matrices obtained from a DM
Lisandro Dalcin wrote: If you do MatSetType(A, MATAIJ), you end-up having a MATSEQAIJ or a MPIMPIAIJ... Vec does not have such aliasing on type names ... How is this a problem? You aren't matching type names, you're just setting a function to be called after the sizes are known. Since this happens in MatCreate_{Seq,MPI}AIJ, it doesn't matter whether MatSetType was called with MATAIJ. Also note that we currently have mat-ops-setsizes (only implemented by SeqDense) so we should either use it or remove it, as long as we value one-way-to-do-it. Jed -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 260 bytes Desc: OpenPGP digital signature URL: http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20090722/9135cfd4/attachment.pgp
Setting options on matrices obtained from a DM
No comments? Not even This is complete shit!? Matt On Tue, Jul 21, 2009 at 8:56 PM, Matthew Knepley knepley at gmail.com wrote: Actually, this seems like the same problem that Lisandro is having, just with different functions. I propose making data structures do the work for us rather than complicated organization in an imperative program. We could use the same mechanism we use in configure to handle issues of object setup. We have a setup object that takes a) an object to be setup b) a set of functions to be called for setup, and c) any functions which must be called prior to each given function This way we can flexibly add as many functions as necessary, and then they can be topologically sorted and executed. There will be some implementation issues in C, due to severe limitations with calling conventions, but I think these can all be solved. Comments? Matt On Tue, Jul 21, 2009 at 7:47 PM, Jed Brown jed at 59a2.org wrote: Barry Smith wrote: Could you call MatSetFromOptions() twice, once before the DAGetMatrix() call to set the type and then after the DAGetMatrix() to set particular options for what you set? This is okay as long as we don't get more global matrix options (this state appears to be stable). It's a little clumsy to have to call that function twice, and because preallocation comes last in the usual idiom: MatCreate MatSetSizes MatSetFromOptions MatXXXSetPreallocation If the matrix type wants anything (programmatic) to be done before preallocation, we don't have a way to do it with your scheme. That is, although we might have set the type before calling DAGetMatrix(), the type isn't actually set until the sizes are known, so we can't call any MatXXXSetYYY() before calling DAGetMatrix(). At the moment, I can't think of a case were this would be a problem. The same applies to anything that could be set by MatSetFromOptions_XXX, but needs to be done before preallocation. The hypothetical DMGetMatrix /* sets sizes, not preallocation or type */ MatSetOptionsPrefix MatSetFromOptions DMSetMatPreallocation makes it possible to set all the options in MatSetFromOptions, and allows any MatXXXSetYYY to be called before preallocation. I can't think of a case where this is more limiting, but that doesn't mean it doesn't exist. It does mean two DM functions rather than one which is not ideal. We decided along time ago to cluster all the option setting in XXXSetFromOptions() but it does impose some limitations. Too many limitations. Are there other models? Having random XXGetOption() in any old method is dangerous because it is hard to know what and where options are going to be set so I think we are stuck with the XXXSetFromOptions() model. I agree that keeping as much as possible in XXXSetFromOptions is the best alternative. I've seen the mess caused by having too many places in which options are consulted. The PETSc creation model is much nicer to work with than factory objects which enforce more sequencing. Jed -- What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead. -- Norbert Wiener -- What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead. -- Norbert Wiener -- next part -- An HTML attachment was scrubbed... URL: http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20090722/0a1e13cc/attachment.html
Setting options on matrices obtained from a DM
Matthew Knepley wrote: No comments? Not even This is complete shit!? Heh, it might be overkill and, if I understand you correctly, I think it could be a headache. There is a reasonable amount of code in the various interfaces to ensure some sequencing, but delayed evaluation is tough to reason about. When I call a function, I expect strict evaluation, but if you somehow store that call away until it's dependencies are satisfied, I'm likely to see confusing behavior. On Tue, Jul 21, 2009 at 8:56 PM, Matthew Knepley knepley at gmail.com wrote: Actually, this seems like the same problem that Lisandro is having, just with different functions. I propose making data structures do the work for us rather than complicated organization in an imperative program. We could use the same mechanism we use in configure to handle issues of object setup. We have a setup object that takes a) an object to be setup b) a set of functions to be called for setup, and c) any functions which must be called prior to each given function How would you specify these? In the general case, we have a partial ordering on setup functions. I suppose you are suggesting that any time you register a setup function, all dependencies would be given explicitly (hence added to the DAG, or referenced if they were already there). It seems to me that we have rather few setup steps that require a particular sequence, some of which are not necessary. I would rather refactor to eliminate unnecessary dependencies than deal with delayed evaluation. If that looks especially complex, some dependency-handling object might help (probably just within the implementations for which it is necessarily complex), but I don't think it should be visible to the user. I think it would help to enumerate the dependencies that really are fundamental, and those that could (with work) be eliminated. Here's a start, I'm certainly missing some. Vec * sizes before type, not fundamental Mat * sizes before type, not fundamental, currently cached when type is set first which causes other problems * type before preallocation, fundamental KSP/PC * operators set before SetFromOptions, is this fundamental? * operators set before SetUp, fundamental SNES * function/Jacobian before SetFromOptions, is this fundamental? * function/Jacobian before SetUp, fundamental TS * similar to SNES Some cases, such as PC_ASM and PC_FieldSplit, would need different options management in order to set all the options in SetFromOptions. They create new matrices and KSP objects from the preconditioning matrix which doesn't exist before Solve/SetUp. It would be possible to move most of this into PCSetFromOptions_XXX if we could call KSPSetFromOptions before KSPSetOperators. It would also make it possible for the user to control these programmatically (currently the inner KSP cannot be created until solve, at which point it's too late for the user to manipulate it). Ideally we would have no dependencies between personality (types and options) and mechanics (for lack of a better term -- sizes, operators, preallocation). The former can influence the latter (changing the type changes the mechanics), but I think a mandatory ordering is bad (except where necessary, setting an option for a specific type obviously must happen after that type is set). Jed -- next part -- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 260 bytes Desc: OpenPGP digital signature URL: http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20090722/f03e611c/attachment.pgp
Setting options on matrices obtained from a DM
My eventual goal is to remove all hidden MatCreate()'s and instead have Mat's passed in as arguments. So MatLoad() would take a Mat as an argument, as would DAGetMatrix() One could then set as much or a as little as a Mat as they like before passing it in. They could set the type, they could set the sizes, they could set the prefix. I think this is the direction you want? Will it satisfy all your needs? MatCreate(). MatSetOptionsPrefix() MatSetFromOptions() DAGetMatrix() Barry On Jul 21, 2009, at 5:54 PM, Jed Brown wrote: If I get a matrix from a DM, I usually do something like PetscOptionsGetString(NULL,-q1_mat_type,mtype,sizeof(mtype),NULL); DMGetMatrix(dm,mtype,Jp); so that the type can be changed on the command line (I frequently switch between preconditioners that can use BAIJ and those that cannot). But, MatSetFromOptions never gets called. If I add MatSetOptionsPrefix(Jp,q1_); MatSetFromOptions(Jp); after the above, then preallocation will be blown if I change anything on the command line. This includes setting block size for AIJ formats (I think BAIJ should implement MatSetBlockSize and just confirm that it matches, but that's a separate issue) so MatSetValuesBlocked cannot even assemble the correct matrix. To rectify this, I think that DMGetMatrix either must have enough information to call MatSetFromOptions (like the prefix) or preallocation should be separated from setting the sizes (so the user can get the matrix, call MatSetFromOptions, and then ask the DM to preallocate). In the former case, we have functionality that is essentially inaccessible from code (PetscOptionsSetValue is a workaround). The latter significantly complicates matters. Note that since the user may get multiple matrices from a DM, to be used for different purposes, it's not okay to use the DM's prefix as the Mat's prefix. Any preferences here? I'm happy with any solution in which the user doesn't have to do an inordinate amount of work to make the following work. -q1_mat_type baij -q1_mat_type aij -mat_no_inode -q1_mat_type crl Jed
Setting options on matrices obtained from a DM
On Jul 21, 2009, at 7:00 PM, Jed Brown wrote: Barry Smith wrote: My eventual goal is to remove all hidden MatCreate()'s and instead have Mat's passed in as arguments. So MatLoad() would take a Mat as an argument, as would DAGetMatrix() One could then set as much or a as little as a Mat as they like before passing it in. They could set the type, they could set the sizes, they could set the prefix. Right, though setting sizes before DAGetMatrix() wouldn't be meaningful. I think this is the direction you want? Will it satisfy all your needs? MatCreate(). MatSetOptionsPrefix() MatSetFromOptions() DAGetMatrix() This will work at present, but it's not perfect (without Mat adjustments). Some options would be set as a consequence of the MatSetSizes() which occurs within DMGetMatrix() (ops-create() is saved until the sizes are known). If a matrix type implements MatSetFromOptions (currently just SchurComplement), that function would never get called in this scheme (because that operation won't be set until the sizes are known). This could be handled by modifying the matrix types so that MatCreate_XXX() could be called before MatSetSizes(), but this is nontrivial. Could you call MatSetFromOptions() twice, once before the DAGetMatrix() call to set the type and then after the DAGetMatrix() to set particular options for what you set? We decided along time ago to cluster all the option setting in XXXSetFromOptions() but it does impose some limitations. Too many limitations. Are there other models? Having random XXGetOption() in any old method is dangerous because it is hard to know what and where options are going to be set so I think we are stuck with the XXXSetFromOptions() model. Barry Jed
Setting options on matrices obtained from a DM
Actually, this seems like the same problem that Lisandro is having, just with different functions. I propose making data structures do the work for us rather than complicated organization in an imperative program. We could use the same mechanism we use in configure to handle issues of object setup. We have a setup object that takes a) an object to be setup b) a set of functions to be called for setup, and c) any functions which must be called prior to each given function This way we can flexibly add as many functions as necessary, and then they can be topologically sorted and executed. There will be some implementation issues in C, due to severe limitations with calling conventions, but I think these can all be solved. Comments? Matt On Tue, Jul 21, 2009 at 7:47 PM, Jed Brown jed at 59a2.org wrote: Barry Smith wrote: Could you call MatSetFromOptions() twice, once before the DAGetMatrix() call to set the type and then after the DAGetMatrix() to set particular options for what you set? This is okay as long as we don't get more global matrix options (this state appears to be stable). It's a little clumsy to have to call that function twice, and because preallocation comes last in the usual idiom: MatCreate MatSetSizes MatSetFromOptions MatXXXSetPreallocation If the matrix type wants anything (programmatic) to be done before preallocation, we don't have a way to do it with your scheme. That is, although we might have set the type before calling DAGetMatrix(), the type isn't actually set until the sizes are known, so we can't call any MatXXXSetYYY() before calling DAGetMatrix(). At the moment, I can't think of a case were this would be a problem. The same applies to anything that could be set by MatSetFromOptions_XXX, but needs to be done before preallocation. The hypothetical DMGetMatrix /* sets sizes, not preallocation or type */ MatSetOptionsPrefix MatSetFromOptions DMSetMatPreallocation makes it possible to set all the options in MatSetFromOptions, and allows any MatXXXSetYYY to be called before preallocation. I can't think of a case where this is more limiting, but that doesn't mean it doesn't exist. It does mean two DM functions rather than one which is not ideal. We decided along time ago to cluster all the option setting in XXXSetFromOptions() but it does impose some limitations. Too many limitations. Are there other models? Having random XXGetOption() in any old method is dangerous because it is hard to know what and where options are going to be set so I think we are stuck with the XXXSetFromOptions() model. I agree that keeping as much as possible in XXXSetFromOptions is the best alternative. I've seen the mess caused by having too many places in which options are consulted. The PETSc creation model is much nicer to work with than factory objects which enforce more sequencing. Jed -- What most experimenters take for granted before they begin their experiments is infinitely more interesting than any results to which their experiments lead. -- Norbert Wiener -- next part -- An HTML attachment was scrubbed... URL: http://lists.mcs.anl.gov/pipermail/petsc-dev/attachments/20090721/072f81e6/attachment.html
Setting options on matrices obtained from a DM
On Jul 21, 2009, at 7:47 PM, Jed Brown wrote: Barry Smith wrote: Could you call MatSetFromOptions() twice, once before the DAGetMatrix() call to set the type and then after the DAGetMatrix() to set particular options for what you set? This is okay as long as we don't get more global matrix options (this state appears to be stable). It's a little clumsy to have to call that function twice, and because preallocation comes last in the usual idiom: MatCreate MatSetSizes MatSetFromOptions MatXXXSetPreallocation If the matrix type wants anything (programmatic) to be done before preallocation, we don't have a way to do it with your scheme. That is, although we might have set the type before calling DAGetMatrix(), the type isn't actually set until the sizes are known, so we can't call any MatXXXSetYYY() before calling DAGetMatrix(). This is just a limitation of the current implementation due to the way the design evolved over time. There is nothing intrinsic to the abstract design of PETSc that prevents the type from being properly processed before the sizes are set. At the moment, I can't think of a case were this would be a problem. The same applies to anything that could be set by MatSetFromOptions_XXX, but needs to be done before preallocation. The hypothetical DMGetMatrix /* sets sizes, not preallocation or type */ MatSetOptionsPrefix MatSetFromOptions DMSetMatPreallocation makes it possible to set all the options in MatSetFromOptions, and allows any MatXXXSetYYY to be called before preallocation. I can't think of a case where this is more limiting, but that doesn't mean it doesn't exist. It does mean two DM functions rather than one which is not ideal. This is really yucky API you propose here; that no sane person would propose except to work around a shortfall in the current implementation. Barry We decided along time ago to cluster all the option setting in XXXSetFromOptions() but it does impose some limitations. Too many limitations. Are there other models? Having random XXGetOption() in any old method is dangerous because it is hard to know what and where options are going to be set so I think we are stuck with the XXXSetFromOptions() model. I agree that keeping as much as possible in XXXSetFromOptions is the best alternative. I've seen the mess caused by having too many places in which options are consulted. The PETSc creation model is much nicer to work with than factory objects which enforce more sequencing. Jed