#include <stdlib.h>
#include "anamod.h"
#include "anamodsalsamodules.h"
#include "anamatrix.h"
#include "petscerror.h"
#include "petscmat.h"
#include "petscis.h"
#include "src/mat/impls/aij/mpi/mpiaij.h"
#include "src/mat/impls/aij/seq/aij.h"
Go to the source code of this file.
Functions | |
static PetscErrorCode | LookAtUncolouredVar (int compare, int this_var, Mat A, PetscScalar *clr_array, PetscScalar *ran_array, PetscReal this_rand, int *neighb, int *nneigh, PetscTruth *colour_now) |
static PetscErrorCode | JonesPlassmannColouring (Mat A, PetscTruth *flg) |
static PetscErrorCode | NColours (AnaModNumericalProblem prob, AnalysisItem *rv, int *lv, PetscTruth *flg) |
static PetscErrorCode | ColourSizes (AnaModNumericalProblem prob, AnalysisItem *rv, int *lv, PetscTruth *flg) |
static PetscErrorCode | ColourOffsets (AnaModNumericalProblem prob, AnalysisItem *rv, int *lv, PetscTruth *flg) |
static PetscErrorCode | Colours (AnaModNumericalProblem prob, AnalysisItem *rv, int *lv, PetscTruth *flg) |
PetscErrorCode | RegisterJPLModules (void) |
PetscErrorCode RegisterJPLModules();
Compute these elements with
ComputeQuantity("jpl","element",A,(void*)&res,&flg);
Available elements are:
This routine works in parallel; the stored result is distributed over all participating processors.
@article{JoPl:heuristic, author = {M.T. Jones and P.E. Plassmann}, title = {A parallel graph coloring heuristic}, journal = SJSSC, volume = {14}, year = {1993}, keywords = {incomplete factorization, multicolouring, matrix graph} } @inproceedings{JoPl:parallelunstructured, author = {M.T. Jones and P.E. Plassmann}, title = {Parallel solution of unstructed, sparse systems of linear equations}, booktitle = {Proceedings of the Sixth SIAM conference on Parallel Processing for Scientific Computing}, editor = {R.F. Sincovec and D.E. Keyes and M.R. Leuze and L.R. Petzold and D.A. Reed}, publisher = {SIAM}, address = {Philadelphia}, pages = {471--475}, year = {1993} \section Disclaimer Unabashed use of British spelling of `colour' needs no disclaimer. }
Definition in file jpl.c.
static PetscErrorCode ColourOffsets | ( | AnaModNumericalProblem | prob, | |
AnalysisItem * | rv, | |||
int * | lv, | |||
PetscTruth * | flg | |||
) | [static] |
Compute an array that has the offsets of the locations of the colours, on this processor. If computing the colouring is done in parallel, then the multicolouring is stored in parallel: it is not gathered onto any processor.
Definition at line 451 of file jpl.c.
References GetDataID(), HASTOEXIST, id, AnalysisItem::ii, and JonesPlassmannColouring().
Referenced by RegisterJPLModules().
00452 { 00453 Mat A = (Mat)prob; 00454 int llv=0,*v = NULL; PetscTruth has; int id,id2; PetscErrorCode ierr; 00455 PetscFunctionBegin; 00456 00457 ierr = GetDataID("jpl","n-colours",&id2,&has); CHKERRQ(ierr); 00458 HASTOEXIST(has); 00459 ierr = PetscObjectComposedDataGetInt 00460 ((PetscObject)A,id2,llv,*flg); CHKERRQ(ierr); 00461 if (*flg) { 00462 if (lv) *lv = llv; 00463 ierr = GetDataID("jpl","colour-offsets",&id,&has); CHKERRQ(ierr); 00464 HASTOEXIST(has); 00465 ierr = PetscObjectComposedDataGetIntstar 00466 ((PetscObject)A,id,v,*flg); CHKERRQ(ierr); 00467 } 00468 if (*flg) rv->ii = v; 00469 else { 00470 ierr = JonesPlassmannColouring(A,flg); CHKERRQ(ierr); 00471 if (*flg) { 00472 ierr = PetscObjectComposedDataGetIntstar 00473 ((PetscObject)A,id,v,*flg); CHKERRQ(ierr); 00474 if (*flg) rv->ii = v; 00475 ierr = PetscObjectComposedDataGetInt 00476 ((PetscObject)A,id2,llv,*flg); CHKERRQ(ierr); 00477 if (*flg) 00478 if (lv) *lv = llv; 00479 } 00480 } 00481 00482 PetscFunctionReturn(0); 00483 }
static PetscErrorCode Colours | ( | AnaModNumericalProblem | prob, | |
AnalysisItem * | rv, | |||
int * | lv, | |||
PetscTruth * | flg | |||
) | [static] |
Compute an array that has the colour sets on this processor. In order to know where a set starts or ends, the result of ColourOffsets() is needed.
If computing the colouring is done in parallel, then the multicolouring is stored in parallel: it is not gathered onto any processor.
Definition at line 497 of file jpl.c.
References GetDataID(), HASTOEXIST, id, AnalysisItem::ii, and JonesPlassmannColouring().
Referenced by RegisterJPLModules().
00498 { 00499 Mat A = (Mat)prob; int N; 00500 int *v = NULL; PetscTruth has; int id; PetscErrorCode ierr; 00501 PetscFunctionBegin; 00502 ierr = MatGetLocalSize(A,&N,PETSC_NULL); CHKERRQ(ierr); 00503 if (lv) *lv = N; 00504 ierr = GetDataID("jpl","colours",&id,&has); CHKERRQ(ierr); 00505 HASTOEXIST(has); 00506 ierr = PetscObjectComposedDataGetIntstar 00507 ((PetscObject)A,id,v,*flg); CHKERRQ(ierr); 00508 if (*flg) rv->ii = v; 00509 else { 00510 ierr = JonesPlassmannColouring(A,flg); CHKERRQ(ierr); 00511 if (*flg) { 00512 ierr = PetscObjectComposedDataGetIntstar 00513 ((PetscObject)A,id,v,*flg); CHKERRQ(ierr); 00514 if (*flg) rv->ii = v; 00515 } 00516 } 00517 00518 PetscFunctionReturn(0); 00519 }
static PetscErrorCode ColourSizes | ( | AnaModNumericalProblem | prob, | |
AnalysisItem * | rv, | |||
int * | lv, | |||
PetscTruth * | flg | |||
) | [static] |
Compute an array that has the number of points of each colour, on this processor. If computing the colouring is done in parallel, then the multicolouring is stored in parallel: it is not gathered onto any processor.
Definition at line 408 of file jpl.c.
References GetDataID(), HASTOEXIST, id, AnalysisItem::ii, and JonesPlassmannColouring().
Referenced by RegisterJPLModules().
00409 { 00410 Mat A = (Mat)prob; 00411 int llv=0,*v = NULL; PetscTruth has; int id,id2; PetscErrorCode ierr; 00412 PetscFunctionBegin; 00413 00414 ierr = GetDataID("jpl","n-colours",&id2,&has); CHKERRQ(ierr); 00415 HASTOEXIST(has); 00416 ierr = PetscObjectComposedDataGetInt 00417 ((PetscObject)A,id2,llv,*flg); CHKERRQ(ierr); 00418 if (*flg) { 00419 if (lv) *lv = llv; 00420 ierr = GetDataID("jpl","colour-set-sizes",&id,&has); CHKERRQ(ierr); 00421 HASTOEXIST(has); 00422 ierr = PetscObjectComposedDataGetIntstar 00423 ((PetscObject)A,id,v,*flg); CHKERRQ(ierr); 00424 } 00425 if (*flg) rv->ii = v; 00426 else { 00427 ierr = JonesPlassmannColouring(A,flg); CHKERRQ(ierr); 00428 if (*flg) { 00429 ierr = PetscObjectComposedDataGetIntstar 00430 ((PetscObject)A,id,v,*flg); CHKERRQ(ierr); 00431 if (*flg) rv->ii = v; 00432 ierr = PetscObjectComposedDataGetInt 00433 ((PetscObject)A,id2,llv,*flg); CHKERRQ(ierr); 00434 if (*flg) 00435 if (lv) *lv = llv; 00436 } 00437 } 00438 00439 PetscFunctionReturn(0); 00440 }
static PetscErrorCode JonesPlassmannColouring | ( | Mat | A, | |
PetscTruth * | flg | |||
) | [static] |
Compute a multicolour ordering of a matrix, in parallel.
This is the main computational routine.
Definition at line 129 of file jpl.c.
References GetDataID(), id, LookAtUncolouredVar(), and MatrixComputeQuantity().
Referenced by ColourOffsets(), Colours(), ColourSizes(), and NColours().
00130 { 00131 MPI_Comm comm; const MatType type; 00132 Mat dia,off; Vec rand,ran_bord, clrs,clrs_bkp,clr_bord; VecScatter sctr; 00133 PetscScalar *ran_array,*bran_array,*clr_array,*clr_bkp_array,*bclr_array; 00134 int *neighb,ncoloured,total_coloured,pass,max_clr, 00135 global_maxclr,local_size,total_size, id; 00136 PetscTruth parallel,sequential; PetscErrorCode ierr; 00137 00138 PetscFunctionBegin; 00139 00140 *flg = PETSC_FALSE; 00141 00142 /* 00143 * What is the matrix type? We only handle AIJ (nonblocked) types 00144 */ 00145 ierr = PetscObjectGetComm((PetscObject)A,&comm); CHKERRQ(ierr); 00146 ierr = MatGetType(A,&type); CHKERRQ(ierr); 00147 ierr = PetscStrcmp(type,MATSEQAIJ,&sequential); CHKERRQ(ierr); 00148 ierr = PetscStrcmp(type,MATMPIAIJ,¶llel); CHKERRQ(ierr); 00149 if (!(sequential || parallel)) { 00150 *flg = PETSC_FALSE; 00151 PetscFunctionReturn(0); 00152 } 00153 00154 /* 00155 * Set up the matrices and vectors 00156 */ 00157 if (parallel) { 00158 Mat_MPIAIJ *aij = (Mat_MPIAIJ *) A->data; 00159 dia=aij->A; off=aij->B; clr_bord = aij->lvec; sctr = aij->Mvctx; 00160 ierr = VecDuplicate(aij->lvec,&ran_bord); CHKERRQ(ierr); 00161 } else { 00162 dia = A; off = NULL; clr_bord = NULL; sctr = NULL; 00163 } 00164 ierr = MatGetSize(A,&total_size,PETSC_NULL); CHKERRQ(ierr); 00165 ierr = MatGetLocalSize(A,&local_size,PETSC_NULL); CHKERRQ(ierr); 00166 00167 /* A temporary array for storing neighbour information */ 00168 { 00169 int l1,l2,len; PetscTruth f; 00170 ierr = MatrixComputeQuantity 00171 (dia,"structure","max-nnzeros-per-row",(AnalysisItem*)&l1,PETSC_NULL, 00172 &f); CHKERRQ(ierr); 00173 if (parallel) { 00174 ierr = MatrixComputeQuantity 00175 (off,"structure","max-nnzeros-per-row",(AnalysisItem*)&l2,PETSC_NULL, 00176 &f); CHKERRQ(ierr); 00177 if (f) len=l1+l2; else len = local_size; 00178 } else len = l1; 00179 ierr = PetscMalloc((len+1)*sizeof(int),&neighb); CHKERRQ(ierr); 00180 } 00181 00182 /* 00183 * Create the vectors for random and colours 00184 */ 00185 { 00186 if (parallel) { 00187 ierr = VecCreateMPI(comm,local_size,PETSC_DECIDE,&rand); CHKERRQ(ierr); 00188 } else { 00189 ierr = VecCreateSeq(MPI_COMM_SELF,local_size,&rand); CHKERRQ(ierr); 00190 } 00191 { 00192 PetscRandom rctx; 00193 ierr = PetscRandomCreate(MPI_COMM_SELF,&rctx); CHKERRQ(ierr); 00194 ierr = PetscRandomSetType(rctx,PETSCRAND48); CHKERRQ(ierr); 00195 ierr = VecSetRandom(rand,rctx); CHKERRQ(ierr); 00196 ierr = PetscRandomDestroy(rctx); CHKERRQ(ierr); 00197 } 00198 ierr = VecDuplicate(rand,&clrs); CHKERRQ(ierr); 00199 ierr = VecDuplicate(rand,&clrs_bkp); CHKERRQ(ierr); 00200 ierr = VecSet(clrs,0.); CHKERRQ(ierr); 00201 if (parallel) { 00202 ierr = VecScatterBegin 00203 (sctr,rand,ran_bord,INSERT_VALUES,SCATTER_FORWARD); CHKERRQ(ierr); 00204 ierr = VecScatterEnd 00205 (sctr,rand,ran_bord,INSERT_VALUES,SCATTER_FORWARD); CHKERRQ(ierr); 00206 ierr = VecGetArray(ran_bord,&bran_array); CHKERRQ(ierr); 00207 ierr = VecGetArray(clr_bord,&bclr_array); CHKERRQ(ierr); 00208 } 00209 ierr = VecGetArray(rand,&ran_array); CHKERRQ(ierr); 00210 ierr = VecGetArray(clrs,&clr_array); CHKERRQ(ierr); 00211 ierr = VecGetArray(clrs_bkp,&clr_bkp_array); CHKERRQ(ierr); 00212 } 00213 00214 /* 00215 * Here is the main loop. 00216 * Iterate until everything is coloured. 00217 */ 00218 ncoloured = 0; max_clr = 0; 00219 for (pass=0; ; pass++) { 00220 PetscTruth busy = PETSC_FALSE,gbusy; int var; 00221 /*printf(".. pass %d :",pass);*/ 00222 if (max_clr>pass) 00223 SETERRQ2(1,"This can not happen: maxclr=%d in pass %d",max_clr,pass); 00224 ierr = PetscMemcpy 00225 (clr_bkp_array,clr_array,local_size*sizeof(PetscScalar)); CHKERRQ(ierr); 00226 00227 /* 00228 * Loop over all variables in every pass 00229 */ 00230 for (var=0; var<local_size; var++) { 00231 int nn = 0; PetscTruth now; 00232 00233 /* Skip already coloured variables */ 00234 if (clr_array[var]>0) continue; 00235 00236 /* All others, look at all connections */ 00237 ierr = LookAtUncolouredVar 00238 (var,var,dia,clr_bkp_array,ran_array,ran_array[var], 00239 neighb,&nn,&now); CHKERRQ(ierr); 00240 if (now && parallel) { 00241 if (parallel) { 00242 ierr = LookAtUncolouredVar 00243 (-1,var,off,bclr_array,bran_array,ran_array[var], 00244 neighb,&nn,&now); CHKERRQ(ierr); 00245 } 00246 } 00247 00248 /* If this variable has the highest value among uncoloured neighbours, 00249 * colour it now. */ 00250 if (now) { 00251 int clr=1,i; 00252 attempt: 00253 for (i=0; i<nn; i++) 00254 if (neighb[i]==clr) {clr++; goto attempt;} 00255 clr_array[var] = (PetscScalar) clr; 00256 if (clr>max_clr) max_clr = clr; 00257 ncoloured++; busy = PETSC_TRUE; 00258 /*printf(" %d->%d",var,clr);*/ 00259 } else { 00260 /*printf(" %d.",var);*/ 00261 } 00262 } /*printf("\n");*/ 00263 00264 /* Exit if all points are coloured */ 00265 MPI_Allreduce 00266 ((void*)&ncoloured,(void*)&total_coloured,1,MPI_INT,MPI_SUM,comm); 00267 if (total_coloured==total_size) break; 00268 00269 /* If nothing was coloured in this pass, we're stuck */ 00270 MPI_Allreduce 00271 ((void*)&busy,(void*)&gbusy,1,MPI_INT,MPI_MAX,comm); 00272 if (!gbusy) SETERRQ(1,"We are stuck"); 00273 00274 if (parallel) { 00275 ierr = VecScatterBegin 00276 (sctr,clrs,clr_bord,INSERT_VALUES,SCATTER_FORWARD); CHKERRQ(ierr); 00277 ierr = VecScatterEnd 00278 (sctr,clrs,clr_bord,INSERT_VALUES,SCATTER_FORWARD); CHKERRQ(ierr); 00279 } 00280 } 00281 00282 /* 00283 * Store the number of colours 00284 */ 00285 MPI_Allreduce 00286 ((void*)&max_clr,(void*)&global_maxclr,1,MPI_INT,MPI_MAX,comm); 00287 ierr = GetDataID("jpl","n-colours",&id,PETSC_NULL); CHKERRQ(ierr); 00288 ierr = PetscObjectComposedDataSetInt 00289 ((PetscObject)A,id,global_maxclr); CHKERRQ(ierr); 00290 00291 /* 00292 * Count how many points of each colour 00293 */ 00294 { 00295 int *colour_count,*colour_offsets,*ptr,*colours,clr,i; 00296 ierr = PetscMalloc 00297 ((global_maxclr+1)*sizeof(int),&colour_count); CHKERRQ(ierr); 00298 colour_count[0] = global_maxclr; 00299 for (clr=0; clr<global_maxclr; clr++) 00300 colour_count[clr+1] = 0; 00301 for (i=0; i<local_size; i++) 00302 colour_count[(int)(clr_array[i])]++; /* colours are from 1 */ 00303 /* 00304 printf("coloured:"); 00305 for (i=0; i<local_size; i++) printf(" %e",clr_array[i]); 00306 printf("\n"); 00307 printf("counts:"); 00308 for (i=0; i<colour_count[0]; i++) printf(" %d",colour_count[i+1]); 00309 printf("\n"); 00310 */ 00311 ierr = GetDataID("jpl","colour-set-sizes",&id,PETSC_NULL); CHKERRQ(ierr); 00312 ierr = PetscObjectComposedDataSetIntstar 00313 ((PetscObject)A,id,colour_count); CHKERRQ(ierr); 00314 00315 ierr = PetscMalloc 00316 ((global_maxclr+1)*sizeof(int),&colour_offsets); CHKERRQ(ierr); 00317 colour_offsets[0] = global_maxclr; 00318 colour_offsets[1] = 0; 00319 for (clr=1; clr<global_maxclr; clr++) 00320 colour_offsets[1+clr] = colour_offsets[clr]+colour_count[clr]; 00321 /* 00322 printf("offsets:"); 00323 for (i=0; i<colour_offsets[0]; i++) printf(" %d",colour_offsets[i+1]); 00324 printf("\n"); 00325 */ 00326 ierr = GetDataID("jpl","colour-offsets",&id,PETSC_NULL); CHKERRQ(ierr); 00327 ierr = PetscObjectComposedDataSetIntstar 00328 ((PetscObject)A,id,colour_offsets); CHKERRQ(ierr); 00329 00330 ierr = PetscMalloc((local_size+1)*sizeof(int),&colours); CHKERRQ(ierr); 00331 colours[0] = local_size; 00332 ierr = PetscMalloc(global_maxclr*sizeof(int),&ptr); CHKERRQ(ierr); 00333 PetscMemcpy(ptr,colour_offsets+1,global_maxclr*sizeof(int)); 00334 for (i=0; i<local_size; i++) { 00335 int c=(int)(clr_array[i]); 00336 colours[1+ptr[c-1]++] = i; 00337 } 00338 ierr = PetscFree(ptr); CHKERRQ(ierr); 00339 /* 00340 printf("colours:"); 00341 for (i=0; i<colours[0]; i++) printf(" %d",colours[i+1]); 00342 printf("\n"); 00343 */ 00344 ierr = GetDataID("jpl","colours",&id,PETSC_NULL); CHKERRQ(ierr); 00345 ierr = PetscObjectComposedDataSetIntstar 00346 ((PetscObject)A,id,colours); CHKERRQ(ierr); 00347 } 00348 00349 /* Clean up */ 00350 ierr = PetscFree(neighb); CHKERRQ(ierr); 00351 ierr = VecRestoreArray(rand,&ran_array); CHKERRQ(ierr); 00352 ierr = VecDestroy(rand); CHKERRQ(ierr); 00353 ierr = VecRestoreArray(clrs,&clr_array); CHKERRQ(ierr); 00354 ierr = VecDestroy(clrs); CHKERRQ(ierr); 00355 ierr = VecRestoreArray(clrs_bkp,&clr_bkp_array); CHKERRQ(ierr); 00356 ierr = VecDestroy(clrs_bkp); CHKERRQ(ierr); 00357 if (parallel) { 00358 ierr = VecRestoreArray(ran_bord,&bran_array); CHKERRQ(ierr); 00359 ierr = VecDestroy(ran_bord); CHKERRQ(ierr); 00360 ierr = VecRestoreArray(clr_bord,&bclr_array); CHKERRQ(ierr); 00361 /* clr_bord is the aij->lvec array; not to be destroyed */ 00362 } 00363 00364 *flg = PETSC_TRUE; 00365 00366 00367 PetscFunctionReturn(0); 00368 }
static PetscErrorCode LookAtUncolouredVar | ( | int | compare, | |
int | this_var, | |||
Mat | A, | |||
PetscScalar * | clr_array, | |||
PetscScalar * | ran_array, | |||
PetscReal | this_rand, | |||
int * | neighb, | |||
int * | nneigh, | |||
PetscTruth * | colour_now | |||
) | [static] |
Investigate the local and remote connections of a variable to see whether it needs to be coloured, and if so, with what colour.
Definition at line 77 of file jpl.c.
Referenced by JonesPlassmannColouring().
00080 { 00081 00082 int nnz,j; const int *idx; PetscErrorCode ierr; 00083 00084 PetscFunctionBegin; 00085 00086 *colour_now = PETSC_TRUE; 00087 00088 ierr = MatGetRow(A,this_var,&nnz,&idx,PETSC_NULL); CHKERRQ(ierr); 00089 for (j=0; j<nnz; j++) { 00090 /* loop over all points connected to 'this_var' */ 00091 int other,clr; 00092 other=idx[j]; clr = (int)(clr_array[other]); 00093 00094 /* no need to look at ourselves */ 00095 if (other==compare) continue; 00096 /* this really shouldn't happen */ 00097 /* 00098 if (ran_array[other]==this_rand) 00099 SETERRQ3(1,"Use a better random: %e @ %d,%d",this_rand,compare,other); 00100 */ 00101 /* 00102 * If the other variable is uncoloured and has a higher random value, 00103 * we can not colour the current variable. 00104 */ 00105 if ( (clr==0 && ran_array[other]>this_rand) || 00106 (ran_array[other]==this_rand && other>this_var) ) { 00107 *colour_now = PETSC_FALSE; 00108 goto exit; 00109 } 00110 /* 00111 * Otherwise, we take note of the colour of the other variable 00112 * for the computation of the colour of this variable later 00113 */ 00114 neighb[(*nneigh)++] = clr; 00115 } 00116 exit: 00117 ierr = MatRestoreRow(A,this_var,&nnz,&idx,PETSC_NULL); CHKERRQ(ierr); 00118 00119 PetscFunctionReturn(0); 00120 }
static PetscErrorCode NColours | ( | AnaModNumericalProblem | prob, | |
AnalysisItem * | rv, | |||
int * | lv, | |||
PetscTruth * | flg | |||
) | [static] |
Compute the global number of colours. Note that any given processor does not need to have all the colours.
Definition at line 377 of file jpl.c.
References GetDataID(), HASTOEXIST, AnalysisItem::i, id, and JonesPlassmannColouring().
Referenced by RegisterJPLModules().
00378 { 00379 Mat A = (Mat)prob; 00380 int v = 0; PetscTruth has; int id; PetscErrorCode ierr; 00381 PetscFunctionBegin; 00382 ierr = GetDataID("jpl","n-colours",&id,&has); CHKERRQ(ierr); 00383 HASTOEXIST(has); 00384 ierr = PetscObjectComposedDataGetInt 00385 ((PetscObject)A,id,v,*flg); CHKERRQ(ierr); 00386 if (*flg) rv->i = v; 00387 else { 00388 ierr = JonesPlassmannColouring(A,flg); CHKERRQ(ierr); 00389 if (*flg) { 00390 ierr = PetscObjectComposedDataGetInt 00391 ((PetscObject)A,id,v,*flg); CHKERRQ(ierr); 00392 if (*flg) rv->i = v; 00393 } 00394 } 00395 00396 PetscFunctionReturn(0); 00397 }
PetscErrorCode RegisterJPLModules | ( | void | ) |
Definition at line 523 of file jpl.c.
References ANALYSISINTARRAY, ANALYSISINTEGER, ColourOffsets(), Colours(), ColourSizes(), NColours(), and RegisterModule().
Referenced by AnaModRegisterSalsaModules(), and AnaModRegisterStandardModules().
00524 { 00525 PetscErrorCode ierr; 00526 PetscFunctionBegin; 00527 00528 ierr = RegisterModule 00529 ("jpl","n-colours",ANALYSISINTEGER,&NColours); CHKERRQ(ierr); 00530 ierr = RegisterModule 00531 ("jpl","colour-set-sizes",ANALYSISINTARRAY,&ColourSizes); CHKERRQ(ierr); 00532 ierr = RegisterModule 00533 ("jpl","colour-offsets",ANALYSISINTARRAY,&ColourOffsets); CHKERRQ(ierr); 00534 ierr = RegisterModule 00535 ("jpl","colours",ANALYSISINTARRAY,&Colours); CHKERRQ(ierr); 00536 00537 PetscFunctionReturn(0); 00538 }