Actual source code: err.c
1: #define PETSC_DLL
2: /*
3: Code that allows one to set the error handlers
4: */
5: #include petsc.h
6: #include petscsys.h
7: #include <stdarg.h>
8: #if defined(PETSC_HAVE_STDLIB_H)
9: #include <stdlib.h>
10: #endif
12: typedef struct _EH *EH;
13: struct _EH {
14: int cookie;
15: PetscErrorCode (*handler)(int,const char*,const char*,const char *,PetscErrorCode,int,const char*,void *);
16: void *ctx;
17: EH previous;
18: };
20: static EH eh = 0;
24: /*@C
25: PetscEmacsClientErrorHandler - Error handler that uses the emacsclient program to
26: load the file where the error occured. Then calls the "previous" error handler.
28: Not Collective
30: Input Parameters:
31: + line - the line number of the error (indicated by __LINE__)
32: . func - the function where error is detected (indicated by __FUNCT__)
33: . file - the file in which the error was detected (indicated by __FILE__)
34: . dir - the directory of the file (indicated by __SDIR__)
35: . mess - an error text string, usually just printed to the screen
36: . n - the generic error number
37: . p - specific error number
38: - ctx - error handler context
40: Options Database Key:
41: . -on_error_emacs <machinename>
43: Level: developer
45: Notes:
46: You must put (server-start) in your .emacs file for the emacsclient software to work
48: Most users need not directly employ this routine and the other error
49: handlers, but can instead use the simplified interface SETERRQ, which has
50: the calling sequence
51: $ SETERRQ(number,p,mess)
53: Notes for experienced users:
54: Use PetscPushErrorHandler() to set the desired error handler. The
55: currently available PETSc error handlers include PetscTraceBackErrorHandler(),
56: PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), and PetscStopErrorHandler()
58: Concepts: emacs^going to on error
59: Concepts: error handler^going to line in emacs
61: .seealso: PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(),
62: PetscAbortErrorHandler()
63: @*/
64: PetscErrorCode PETSC_DLLEXPORT PetscEmacsClientErrorHandler(int line,const char *fun,const char* file,const char *dir,PetscErrorCode n,int p,const char *mess,void *ctx)
65: {
67: char command[PETSC_MAX_PATH_LEN];
68: const char *pdir;
69: FILE *fp;
72: /* Note: don't check error codes since this an error handler :-) */
73: PetscGetPetscDir(&pdir);
74: sprintf(command,"emacsclient +%d %s/%s%s\n",line,pdir,dir,file);
75: #if defined(PETSC_HAVE_POPEN)
76: PetscPOpen(MPI_COMM_WORLD,(char*)ctx,command,"r",&fp);
77: PetscPClose(MPI_COMM_WORLD,fp);
78: #else
79: SETERRQ(PETSC_ERR_SUP_SYS,"Cannot run external programs on this machine");
80: #endif
81: PetscPopErrorHandler(); /* remove this handler from the stack of handlers */
82: if (!eh) PetscTraceBackErrorHandler(line,fun,file,dir,n,p,mess,0);
83: else (*eh->handler)(line,fun,file,dir,n,p,mess,eh->ctx);
84: PetscFunctionReturn(ierr);
85: }
89: /*@C
90: PetscPushErrorHandler - Sets a routine to be called on detection of errors.
92: Not Collective
94: Input Parameters:
95: + handler - error handler routine
96: - ctx - optional handler context that contains information needed by the handler (for
97: example file pointers for error messages etc.)
99: Calling sequence of handler:
100: $ int handler(int line,char *func,char *file,char *dir,PetscErrorCode n,int p,char *mess,void *ctx);
102: + func - the function where the error occured (indicated by __FUNCT__)
103: . line - the line number of the error (indicated by __LINE__)
104: . file - the file in which the error was detected (indicated by __FILE__)
105: . dir - the directory of the file (indicated by __SDIR__)
106: . n - the generic error number (see list defined in include/petscerror.h)
107: . p - the specific error number
108: . mess - an error text string, usually just printed to the screen
109: - ctx - the error handler context
111: Options Database Keys:
112: + -on_error_attach_debugger <noxterm,gdb or dbx>
113: - -on_error_abort
115: Level: intermediate
117: .seealso: PetscPopErrorHandler(), PetscAttachDebuggerErrorHandler(), PetscAbortErrorHandler(), PetscTraceBackErrorHandler()
119: @*/
120: PetscErrorCode PETSC_DLLEXPORT PetscPushErrorHandler(PetscErrorCode (*handler)(int,const char *,const char*,const char*,PetscErrorCode,int,const char*,void*),void *ctx)
121: {
122: EH neweh;
126: PetscNew(struct _EH,&neweh);
127: if (eh) {neweh->previous = eh;}
128: else {neweh->previous = 0;}
129: neweh->handler = handler;
130: neweh->ctx = ctx;
131: eh = neweh;
132: return(0);
133: }
137: /*@C
138: PetscPopErrorHandler - Removes the latest error handler that was
139: pushed with PetscPushErrorHandler().
141: Not Collective
143: Level: intermediate
145: Concepts: error handler^setting
147: .seealso: PetscPushErrorHandler()
148: @*/
149: PetscErrorCode PETSC_DLLEXPORT PetscPopErrorHandler(void)
150: {
151: EH tmp;
155: if (!eh) return(0);
156: tmp = eh;
157: eh = eh->previous;
158: PetscFree(tmp);
160: return(0);
161: }
162:
163: static char PetscErrorBaseMessage[1024];
164: /*
165: The numerical values for these are defined in include/petscerror.h; any changes
166: there must also be made here
167: */
168: static const char *PetscErrorStrings[] = {
169: /*55 */ "Out of memory",
170: "No support for this operation for this object type",
171: "No support for this operation on this system",
172: /*58 */ "Operation done in wrong order",
173: /*59 */ "Signal received",
174: /*60 */ "Nonconforming object sizes",
175: "Argument aliasing not permitted",
176: "Invalid argument",
177: /*63 */ "Argument out of range",
178: "Corrupt argument: see http://www.mcs.anl.gov/petsc/petsc-as/documentation/troubleshooting.html#Corrupt",
179: "Unable to open file",
180: "Read from file failed",
181: "Write to file failed",
182: "Invalid pointer",
183: /*69 */ "Arguments must have same type",
184: "",
185: /*71 */ "Detected zero pivot in LU factorization\nsee http://www.mcs.anl.gov/petsc/petsc-as/documentation/troubleshooting.html#ZeroPivot",
186: /*72 */ "Floating point exception",
187: /*73 */ "Object is in wrong state",
188: "Corrupted Petsc object",
189: "Arguments are incompatible",
190: "Error in external library",
191: /*77 */ "Petsc has generated inconsistent data",
192: "Memory corruption",
193: "Unexpected data in file",
194: /*80 */ "Arguments must have same communicators",
195: /*81 */ "Detected zero pivot in Cholesky factorization\nsee http://www.mcs.anl.gov/petsc/petsc-as/documentation/troubleshooting.html#ZeroPivot",
196: " ",
197: " ",
198: " ",
199: /*85 */ "Null argument, when expecting valid pointer",
200: /*86 */ "Unknown type. Check for miss-spelling or missing external package needed for type"};
204: /*@C
205: PetscErrorMessage - returns the text string associated with a PETSc error code.
207: Not Collective
209: Input Parameter:
210: . errnum - the error code
212: Output Parameter:
213: + text - the error message (PETSC_NULL if not desired)
214: - specific - the specific error message that was set with SETERRxxx() or PetscError(). (PETSC_NULL if not desired)
216: Level: developer
218: Concepts: error handler^messages
220: .seealso: PetscPushErrorHandler(), PetscAttachDebuggerErrorHandler(),
221: PetscAbortErrorHandler(), PetscTraceBackErrorHandler()
222: @*/
223: PetscErrorCode PETSC_DLLEXPORT PetscErrorMessage(int errnum,const char *text[],char **specific)
224: {
226: if (text && errnum >= PETSC_ERR_MEM && errnum <= PETSC_ERR_MEM_MALLOC_0) {
227: *text = PetscErrorStrings[errnum-PETSC_ERR_MEM];
228: } else if (text) *text = 0;
230: if (specific) {
231: *specific = PetscErrorBaseMessage;
232: }
233: return(0);
234: }
236: #if defined(PETSC_USE_ERRORCHECKING)
237: PetscErrorCode PETSC_DLLEXPORT PetscErrorUncatchable[PETSC_EXCEPTIONS_MAX] = {0};
238: PetscInt PETSC_DLLEXPORT PetscErrorUncatchableCount = 0;
239: PetscErrorCode PETSC_DLLEXPORT PetscExceptions[PETSC_EXCEPTIONS_MAX] = {0};
240: PetscInt PETSC_DLLEXPORT PetscExceptionsCount = 0;
241: PetscErrorCode PETSC_DLLEXPORT PetscExceptionTmp = 0;
245: static PetscTruth PetscErrorIsCatchable(PetscErrorCode err)
246: {
247: PetscInt i;
248: for (i=0; i<PetscErrorUncatchableCount; i++) {
249: if (err == PetscErrorUncatchable[i]) return PETSC_FALSE;
250: }
251: return PETSC_TRUE;
252: }
256: /*@
257: PetscErrorSetCatchable - Sets if a PetscErrorCode can be caught with a PetscExceptionTry1()
258: PetscExceptionCaught() pair. By default all errors are catchable.
260: Input Parameters:
261: + err - error code
262: - flg - PETSC_TRUE means allow to be caught, PETSC_FALSE means do not allow to be caught
264: Level: advanced
266: Notes:
267: PETSc must not be configured using the option --with-errorchecking=0 for this to work
269: .seealso: PetscExceptionTry1(), PetscExceptionCaught()
270: @*/
271: PetscErrorCode PETSC_DLLEXPORT PetscErrorSetCatchable(PetscErrorCode err,PetscTruth flg)
272: {
274: if (!flg && PetscErrorIsCatchable(err)) {
275: /* add to list of uncatchable */
276: if (PetscErrorUncatchableCount >= PETSC_EXCEPTIONS_MAX) SETERRQ(PETSC_ERR_PLIB,"Stack for PetscErrorUncatchable is overflowed, recompile \nsrc/sys/srcd/error/err.c with a larger value for PETSC_EXCEPTIONS_MAX");
277: PetscErrorUncatchable[PetscErrorUncatchableCount++] = err;
278: } else if (flg && !PetscErrorIsCatchable(err)) {
279: /* remove from list of uncatchable */
280: PetscInt i;
281: for (i=0; i<PetscErrorUncatchableCount; i++) {
282: if (PetscErrorUncatchable[i] == err) break;
283: }
284: for (;i<PetscErrorUncatchableCount; i++) {
285: PetscErrorUncatchable[i] = PetscErrorUncatchable[i+1];
286: }
287: PetscErrorUncatchableCount--;
288: }
289: return(0);
290: }
294: PetscErrorCode PETSC_DLLEXPORT PetscExceptionPush(PetscErrorCode err)
295: {
297: if (PetscExceptionsCount >= PETSC_EXCEPTIONS_MAX) SETERRQ(PETSC_ERR_PLIB,"Stack for PetscExceptions is overflowed, recompile \nsrc/sys/srcd/error/err.c with a larger value for PETSC_EXCEPTIONS_MAX");
298: if (PetscErrorIsCatchable(err)) PetscExceptions[PetscExceptionsCount++] = err;
299: return(0);
300: }
304: void PETSC_DLLEXPORT PetscExceptionPop(PetscErrorCode err)
305: {
306: /* if (PetscExceptionsCount <= 0)SETERRQ(PETSC_ERR_PLIB,"Stack for PetscExceptions is empty"); */
307: if (PetscErrorIsCatchable(err)) PetscExceptionsCount--;
308: }
309: #endif
313: /*@C
314: PetscError - Routine that is called when an error has been detected,
315: usually called through the macro SETERRQ().
317: Not Collective
319: Input Parameters:
320: + line - the line number of the error (indicated by __LINE__)
321: . func - the function where the error occured (indicated by __FUNCT__)
322: . dir - the directory of file (indicated by __SDIR__)
323: . file - the file in which the error was detected (indicated by __FILE__)
324: . mess - an error text string, usually just printed to the screen
325: . n - the generic error number
326: . p - 1 indicates the error was initially detected, 0 indicates this is a traceback from a
327: previously detected error
328: - mess - formatted message string - aka printf
330: Level: intermediate
332: Notes:
333: Most users need not directly use this routine and the error handlers, but
334: can instead use the simplified interface SETERRQ, which has the calling
335: sequence
336: $ SETERRQ(n,mess)
338: Experienced users can set the error handler with PetscPushErrorHandler().
340: Concepts: error^setting condition
342: .seealso: PetscTraceBackErrorHandler(), PetscPushErrorHandler(), SETERRQ(), CHKERRQ(), CHKMEMQ, SETERRQ1(), SETERRQ2()
343: @*/
344: PetscErrorCode PETSC_DLLEXPORT PetscError(int line,const char *func,const char* file,const char *dir,PetscErrorCode n,int p,const char *mess,...)
345: {
346: va_list Argp;
348: char buf[2048],*lbuf = 0;
349: PetscTruth ismain,isunknown;
350: #if defined(PETSC_USE_ERRORCHECKING)
351: PetscInt i;
352: #endif
354: if (!func) func = "User provided function";
355: if (!file) file = "User file";
356: if (!dir) dir = " ";
359: /* Compose the message evaluating the print format */
360: if (mess) {
361: va_start(Argp,mess);
362: PetscVSNPrintf(buf,2048,mess,Argp);
363: va_end(Argp);
364: lbuf = buf;
365: if (p == 1) {
366: PetscStrncpy(PetscErrorBaseMessage,lbuf,1023);
367: }
368: }
370: #if defined(PETSC_USE_ERRORCHECKING)
371: /* check if user is catching this exception */
372: for (i=0; i<PetscExceptionsCount; i++) {
373: if (n == PetscExceptions[i]) PetscFunctionReturn(n);
374: }
375: #endif
377: if (!eh) PetscTraceBackErrorHandler(line,func,file,dir,n,p,lbuf,0);
378: else (*eh->handler)(line,func,file,dir,n,p,lbuf,eh->ctx);
380: /*
381: If this is called from the main() routine we call MPI_Abort() instead of
382: return to allow the parallel program to be properly shutdown.
384: Since this is in the error handler we don't check the errors below. Of course,
385: PetscStrncmp() does its own error checking which is problamatic
386: */
387: PetscStrncmp(func,"main",4,&ismain);
388: PetscStrncmp(func,"unknown",7,&isunknown);
389: if (ismain || isunknown) {
390: MPI_Abort(PETSC_COMM_WORLD,(int)ierr);
391: }
392: PetscFunctionReturn(ierr);
393: }
395: /* -------------------------------------------------------------------------*/
399: /*@C
400: PetscIntView - Prints an array of integers; useful for debugging.
402: Collective on PetscViewer
404: Input Parameters:
405: + N - number of integers in array
406: . idx - array of integers
407: - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
409: Level: intermediate
411: .seealso: PetscRealView()
412: @*/
413: PetscErrorCode PETSC_DLLEXPORT PetscIntView(PetscInt N,PetscInt idx[],PetscViewer viewer)
414: {
416: PetscInt j,i,n = N/20,p = N % 20;
417: PetscTruth iascii,issocket;
418: MPI_Comm comm;
421: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
424: PetscObjectGetComm((PetscObject)viewer,&comm);
426: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
427: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);
428: if (iascii) {
429: for (i=0; i<n; i++) {
430: PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*i);
431: for (j=0; j<20; j++) {
432: PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[i*20+j]);
433: }
434: PetscViewerASCIISynchronizedPrintf(viewer,"\n");
435: }
436: if (p) {
437: PetscViewerASCIISynchronizedPrintf(viewer,"%D:",20*n);
438: for (i=0; i<p; i++) { PetscViewerASCIISynchronizedPrintf(viewer," %D",idx[20*n+i]);}
439: PetscViewerASCIISynchronizedPrintf(viewer,"\n");
440: }
441: PetscViewerFlush(viewer);
442: #if defined(PETSC_USE_SOCKET_VIEWER)
443: } else if (issocket) {
444: PetscMPIInt rank,size,*sizes,Ntotal,*displs, NN = (PetscMPIInt)N;
445: PetscInt *array;
446: MPI_Comm_rank(comm,&rank);
447: MPI_Comm_size(comm,&size);
449: if (size > 1) {
450: if (rank) {
451: MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);
452: MPI_Gatherv(idx,NN,MPIU_INT,0,0,0,MPIU_INT,0,comm);
453: } else {
454: PetscMalloc(size*sizeof(PetscMPIInt),&sizes);
455: MPI_Gather(&NN,1,MPI_INT,sizes,1,MPIU_INT,0,comm);
456: Ntotal = sizes[0];
457: PetscMalloc(size*sizeof(PetscMPIInt),&displs);
458: displs[0] = 0;
459: for (i=1; i<size; i++) {
460: Ntotal += sizes[i];
461: displs[i] = displs[i-1] + sizes[i-1];
462: }
463: PetscMalloc(Ntotal*sizeof(PetscInt),&array);
464: MPI_Gatherv(idx,NN,MPIU_INT,array,sizes,displs,MPIU_INT,0,comm);
465: PetscViewerSocketPutInt(viewer,Ntotal,array);
466: PetscFree(sizes);
467: PetscFree(displs);
468: PetscFree(array);
469: }
470: } else {
471: PetscViewerSocketPutInt(viewer,N,idx);
472: }
473: #endif
474: } else {
475: const char *tname;
476: PetscObjectGetName((PetscObject)viewer,&tname);
477: SETERRQ1(PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname);
478: }
479: return(0);
480: }
484: /*@C
485: PetscRealView - Prints an array of doubles; useful for debugging.
487: Collective on PetscViewer
489: Input Parameters:
490: + N - number of doubles in array
491: . idx - array of doubles
492: - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
494: Level: intermediate
496: .seealso: PetscIntView()
497: @*/
498: PetscErrorCode PETSC_DLLEXPORT PetscRealView(PetscInt N,PetscReal idx[],PetscViewer viewer)
499: {
501: PetscInt j,i,n = N/5,p = N % 5;
502: PetscTruth iascii,issocket;
503: MPI_Comm comm;
506: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
509: PetscObjectGetComm((PetscObject)viewer,&comm);
511: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
512: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);
513: if (iascii) {
514: for (i=0; i<n; i++) {
515: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*i);
516: for (j=0; j<5; j++) {
517: PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*5+j]);
518: }
519: PetscViewerASCIISynchronizedPrintf(viewer,"\n");
520: }
521: if (p) {
522: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",5*n);
523: for (i=0; i<p; i++) { PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[5*n+i]);}
524: PetscViewerASCIISynchronizedPrintf(viewer,"\n");
525: }
526: PetscViewerFlush(viewer);
527: #if defined(PETSC_USE_SOCKET_VIEWER)
528: } else if (issocket) {
529: PetscMPIInt rank,size,*sizes,*displs, Ntotal,NN = (PetscMPIInt)N;
530: PetscReal *array;
532: MPI_Comm_rank(comm,&rank);
533: MPI_Comm_size(comm,&size);
535: if (size > 1) {
536: if (rank) {
537: MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);
538: MPI_Gatherv(idx,NN,MPI_DOUBLE,0,0,0,MPI_DOUBLE,0,comm);
539: } else {
540: PetscMalloc(size*sizeof(PetscMPIInt),&sizes);
541: MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);
542: Ntotal = sizes[0];
543: PetscMalloc(size*sizeof(PetscMPIInt),&displs);
544: displs[0] = 0;
545: for (i=1; i<size; i++) {
546: Ntotal += sizes[i];
547: displs[i] = displs[i-1] + sizes[i-1];
548: }
549: PetscMalloc(Ntotal*sizeof(PetscReal),&array);
550: MPI_Gatherv(idx,NN,MPI_DOUBLE,array,sizes,displs,MPI_DOUBLE,0,comm);
551: PetscViewerSocketPutReal(viewer,Ntotal,1,array);
552: PetscFree(sizes);
553: PetscFree(displs);
554: PetscFree(array);
555: }
556: } else {
557: PetscViewerSocketPutReal(viewer,N,1,idx);
558: }
559: #endif
560: } else {
561: const char *tname;
562: PetscObjectGetName((PetscObject)viewer,&tname);
563: SETERRQ1(PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname);
564: }
565: return(0);
566: }
570: /*@C
571: PetscScalarView - Prints an array of scalars; useful for debugging.
573: Collective on PetscViewer
575: Input Parameters:
576: + N - number of scalars in array
577: . idx - array of scalars
578: - viewer - location to print array, PETSC_VIEWER_STDOUT_WORLD, PETSC_VIEWER_STDOUT_SELF or 0
580: Level: intermediate
582: .seealso: PetscIntView(), PetscRealView()
583: @*/
584: PetscErrorCode PETSC_DLLEXPORT PetscScalarView(PetscInt N,PetscScalar idx[],PetscViewer viewer)
585: {
587: PetscInt j,i,n = N/3,p = N % 3;
588: PetscTruth iascii,issocket;
589: MPI_Comm comm;
592: if (!viewer) viewer = PETSC_VIEWER_STDOUT_SELF;
595: PetscObjectGetComm((PetscObject)viewer,&comm);
597: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
598: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_SOCKET,&issocket);
599: if (iascii) {
600: for (i=0; i<n; i++) {
601: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*i);
602: for (j=0; j<3; j++) {
603: #if defined (PETSC_USE_COMPLEX)
604: PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)",
605: PetscRealPart(idx[i*3+j]),PetscImaginaryPart(idx[i*3+j]));
606: #else
607: PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[i*3+j]);
608: #endif
609: }
610: PetscViewerASCIISynchronizedPrintf(viewer,"\n");
611: }
612: if (p) {
613: PetscViewerASCIISynchronizedPrintf(viewer,"%2d:",3*n);
614: for (i=0; i<p; i++) {
615: #if defined (PETSC_USE_COMPLEX)
616: PetscViewerASCIISynchronizedPrintf(viewer," (%12.4e,%12.4e)",
617: PetscRealPart(idx[n*3+i]),PetscImaginaryPart(idx[n*3+i]));
618: #else
619: PetscViewerASCIISynchronizedPrintf(viewer," %12.4e",idx[3*n+i]);
620: #endif
621: }
622: PetscViewerASCIISynchronizedPrintf(viewer,"\n");
623: }
624: PetscViewerFlush(viewer);
625: #if defined(PETSC_USE_SOCKET_VIEWER)
626: } else if (issocket) {
627: PetscMPIInt size,rank,*sizes,Ntotal,*displs,NN = (PetscMPIInt)N;
628: PetscScalar *array;
630: MPI_Comm_rank(comm,&rank);
631: MPI_Comm_size(comm,&size);
633: if (size > 1) {
634: if (rank) {
635: MPI_Gather(&NN,1,MPI_INT,0,0,MPI_INT,0,comm);
636: MPI_Gatherv(idx,NN,MPIU_SCALAR,0,0,0,MPIU_SCALAR,0,comm);
637: } else {
638: PetscMalloc(size*sizeof(PetscMPIInt),&sizes);
639: MPI_Gather(&NN,1,MPI_INT,sizes,1,MPI_INT,0,comm);
640: Ntotal = sizes[0];
641: PetscMalloc(size*sizeof(PetscMPIInt),&displs);
642: displs[0] = 0;
643: for (i=1; i<size; i++) {
644: Ntotal += sizes[i];
645: displs[i] = displs[i-1] + sizes[i-1];
646: }
647: PetscMalloc(Ntotal*sizeof(PetscScalar),&array);
648: MPI_Gatherv(idx,NN,MPIU_SCALAR,array,sizes,displs,MPIU_SCALAR,0,comm);
649: PetscViewerSocketPutScalar(viewer,Ntotal,1,array);
650: PetscFree(sizes);
651: PetscFree(displs);
652: PetscFree(array);
653: }
654: } else {
655: PetscViewerSocketPutScalar(viewer,N,1,idx);
656: }
657: #endif
658: } else {
659: const char *tname;
660: PetscObjectGetName((PetscObject)viewer,&tname);
661: SETERRQ1(PETSC_ERR_SUP,"Cannot handle that PetscViewer of type %s",tname);
662: }
663: return(0);
664: }