1*ed170139SJacob Faibussowitsch static const char help[] = "Test PetscFunctionList.\n"; 2*ed170139SJacob Faibussowitsch 3*ed170139SJacob Faibussowitsch #include <petscsys.h> 4*ed170139SJacob Faibussowitsch #include <petscviewer.h> 5*ed170139SJacob Faibussowitsch 6*ed170139SJacob Faibussowitsch #define PETSC_DEFINE_FUNCTION_AND_STR(name) \ 7*ed170139SJacob Faibussowitsch static void name() \ 8*ed170139SJacob Faibussowitsch { \ 9*ed170139SJacob Faibussowitsch puts("called " PetscStringize(name) "()"); \ 10*ed170139SJacob Faibussowitsch } \ 11*ed170139SJacob Faibussowitsch static const char name##_str[] = PetscStringize(name) 12*ed170139SJacob Faibussowitsch 13*ed170139SJacob Faibussowitsch PETSC_DEFINE_FUNCTION_AND_STR(foo); 14*ed170139SJacob Faibussowitsch PETSC_DEFINE_FUNCTION_AND_STR(bar); 15*ed170139SJacob Faibussowitsch PETSC_DEFINE_FUNCTION_AND_STR(baz); 16*ed170139SJacob Faibussowitsch PETSC_DEFINE_FUNCTION_AND_STR(bop); 17*ed170139SJacob Faibussowitsch PETSC_DEFINE_FUNCTION_AND_STR(qux); 18*ed170139SJacob Faibussowitsch PETSC_DEFINE_FUNCTION_AND_STR(quux); 19*ed170139SJacob Faibussowitsch PETSC_DEFINE_FUNCTION_AND_STR(blip); 20*ed170139SJacob Faibussowitsch PETSC_DEFINE_FUNCTION_AND_STR(blap); 21*ed170139SJacob Faibussowitsch PETSC_DEFINE_FUNCTION_AND_STR(blop); 22*ed170139SJacob Faibussowitsch PETSC_DEFINE_FUNCTION_AND_STR(graulty); 23*ed170139SJacob Faibussowitsch PETSC_DEFINE_FUNCTION_AND_STR(quix); 24*ed170139SJacob Faibussowitsch 25*ed170139SJacob Faibussowitsch static const char *const all_names[] = {foo_str, bar_str, baz_str, bop_str, qux_str, quux_str, blip_str, blap_str, blop_str, graulty_str, quix_str}; 26*ed170139SJacob Faibussowitsch static void (*const all_funcs[])(void) = {foo, bar, baz, bop, qux, quux, blip, blap, blop, graulty, quix}; 27*ed170139SJacob Faibussowitsch static const size_t num_names = PETSC_STATIC_ARRAY_LENGTH(all_names); 28*ed170139SJacob Faibussowitsch static const size_t num_funcs = PETSC_STATIC_ARRAY_LENGTH(all_funcs); 29*ed170139SJacob Faibussowitsch 30*ed170139SJacob Faibussowitsch static PetscErrorCode TestPetscFunctionListCreate(PetscViewer viewer, PetscFunctionList *fl, PetscFunctionList *fl_dup) 31*ed170139SJacob Faibussowitsch { 32*ed170139SJacob Faibussowitsch PetscFunctionBegin; 33*ed170139SJacob Faibussowitsch // add the function 34*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListAdd(fl, foo_str, foo)); 35*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListView(*fl, NULL)); 36*ed170139SJacob Faibussowitsch // remove it 37*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListAdd(fl, foo_str, NULL)); 38*ed170139SJacob Faibussowitsch PetscCheck(*fl, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Emptying PetscFunctionList has destroyed it!"); 39*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListView(*fl, NULL)); 40*ed170139SJacob Faibussowitsch // should not do anything 41*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListClear(*fl)); 42*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListView(*fl, viewer)); 43*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListDuplicate(*fl, fl_dup)); 44*ed170139SJacob Faibussowitsch PetscCheck(*fl_dup, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Duplicating empty function list has not allocated a new one"); 45*ed170139SJacob Faibussowitsch // still empty 46*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListView(*fl, viewer)); 47*ed170139SJacob Faibussowitsch // also empty 48*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListView(*fl_dup, viewer)); 49*ed170139SJacob Faibussowitsch PetscFunctionReturn(0); 50*ed170139SJacob Faibussowitsch } 51*ed170139SJacob Faibussowitsch 52*ed170139SJacob Faibussowitsch static PetscErrorCode TestPetscFunctionListFind(PetscViewer viewer, PetscFunctionList fl, PetscFunctionList fl_dup, size_t *fl_size, size_t *fl_dup_size) 53*ed170139SJacob Faibussowitsch { 54*ed170139SJacob Faibussowitsch PetscFunctionBegin; 55*ed170139SJacob Faibussowitsch // add a bunch of functions, and ensure they are all there 56*ed170139SJacob Faibussowitsch for (size_t i = 0; i < num_funcs; ++i) { 57*ed170139SJacob Faibussowitsch PetscVoidFunction func; 58*ed170139SJacob Faibussowitsch 59*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&fl, all_names[i], all_funcs[i])); 60*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListFind(fl, all_names[i], &func)); 61*ed170139SJacob Faibussowitsch PetscCheck(func == all_funcs[i], PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscFunctionListFind() failed to find %s() immediately after inserting it! returned %p != expected %p", all_names[i], (void *)(PETSC_UINTPTR_T)func, (void *)(PETSC_UINTPTR_T)(all_funcs[i])); 62*ed170139SJacob Faibussowitsch // make sure the pointer is good 63*ed170139SJacob Faibussowitsch func(); 64*ed170139SJacob Faibussowitsch } 65*ed170139SJacob Faibussowitsch 66*ed170139SJacob Faibussowitsch // ensure that none of them are missing 67*ed170139SJacob Faibussowitsch for (size_t i = 0; i < num_funcs; ++i) { 68*ed170139SJacob Faibussowitsch PetscVoidFunction func; 69*ed170139SJacob Faibussowitsch 70*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListFind(fl, all_names[i], &func)); 71*ed170139SJacob Faibussowitsch PetscCheck(func == all_funcs[i], PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscFunctionListFind() failed to find %s() after inserting all functions! returned %p != expected %p", all_names[i], (void *)(PETSC_UINTPTR_T)func, (void *)(PETSC_UINTPTR_T)(all_funcs[i])); 72*ed170139SJacob Faibussowitsch // make sure the pointer is good 73*ed170139SJacob Faibussowitsch func(); 74*ed170139SJacob Faibussowitsch } 75*ed170139SJacob Faibussowitsch 76*ed170139SJacob Faibussowitsch // appends to fl_dup 77*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListDuplicate(fl, &fl_dup)); 78*ed170139SJacob Faibussowitsch 79*ed170139SJacob Faibussowitsch // ensure that none of them are missing 80*ed170139SJacob Faibussowitsch for (size_t i = 0; i < num_funcs; ++i) { 81*ed170139SJacob Faibussowitsch PetscVoidFunction fl_func, fl_dup_func; 82*ed170139SJacob Faibussowitsch 83*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListFind(fl, all_names[i], &fl_func)); 84*ed170139SJacob Faibussowitsch PetscCheck(fl_func == all_funcs[i], PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscFunctionListFind() failed to find %s() after inserting all functions! returned %p != expected %p", all_names[i], (void *)(PETSC_UINTPTR_T)fl_func, (void *)(PETSC_UINTPTR_T)(all_funcs[i])); 85*ed170139SJacob Faibussowitsch // make sure the pointer is good 86*ed170139SJacob Faibussowitsch fl_func(); 87*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListFind(fl_dup, all_names[i], &fl_dup_func)); 88*ed170139SJacob Faibussowitsch PetscCheck(fl_dup_func == fl_func, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscFunctionListFind() returned different results for %s() for duplicated function list. returned %p != expected %p", all_names[i], (void *)(PETSC_UINTPTR_T)fl_dup_func, (void *)(PETSC_UINTPTR_T)fl_func); 89*ed170139SJacob Faibussowitsch fl_dup_func(); 90*ed170139SJacob Faibussowitsch } 91*ed170139SJacob Faibussowitsch 92*ed170139SJacob Faibussowitsch // same as in fl 93*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListView(fl_dup, viewer)); 94*ed170139SJacob Faibussowitsch // clearing fl should have no effect on fl_dup 95*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListClear(fl)); 96*ed170139SJacob Faibussowitsch // ensure that none of them are missing 97*ed170139SJacob Faibussowitsch for (size_t i = 0; i < num_funcs; ++i) { 98*ed170139SJacob Faibussowitsch PetscVoidFunction fl_dup_func; 99*ed170139SJacob Faibussowitsch 100*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListFind(fl_dup, all_names[i], &fl_dup_func)); 101*ed170139SJacob Faibussowitsch PetscCheck(fl_dup_func == all_funcs[i], PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscFunctionListFind() failed to find %s() in duplicated function list after clearing original list! returned %p != expected %p", all_names[i], (void *)(PETSC_UINTPTR_T)fl_dup_func, (void *)(PETSC_UINTPTR_T)(all_funcs[i])); 102*ed170139SJacob Faibussowitsch fl_dup_func(); 103*ed170139SJacob Faibussowitsch } 104*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListView(fl_dup, viewer)); 105*ed170139SJacob Faibussowitsch *fl_size = 0; 106*ed170139SJacob Faibussowitsch *fl_dup_size = num_funcs; 107*ed170139SJacob Faibussowitsch PetscFunctionReturn(0); 108*ed170139SJacob Faibussowitsch } 109*ed170139SJacob Faibussowitsch 110*ed170139SJacob Faibussowitsch static PetscErrorCode TestPetscFunctionListGet(PetscViewer viewer, PetscFunctionList fl, PetscFunctionList fl_dup, size_t expected_fl_size, size_t expected_fl_dup_size) 111*ed170139SJacob Faibussowitsch { 112*ed170139SJacob Faibussowitsch const char **array; 113*ed170139SJacob Faibussowitsch int n; 114*ed170139SJacob Faibussowitsch #define PetscCheckArrayPointer(expected_non_null, array) \ 115*ed170139SJacob Faibussowitsch PetscCheck((expected_non_null) ? (array) != NULL : (array) == NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscFunctionListGet() returned invalid array (%p) for cleared function list, expected %s", (void *)(array), (expected_non_null) ? "non-null" : "null") 116*ed170139SJacob Faibussowitsch 117*ed170139SJacob Faibussowitsch PetscFunctionBegin; 118*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListGet(fl, &array, &n)); 119*ed170139SJacob Faibussowitsch PetscCheck((size_t)n == expected_fl_size, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscFunctionListGet() returned unexpected size %d, expected %zu", n, expected_fl_size); 120*ed170139SJacob Faibussowitsch PetscCheckArrayPointer(expected_fl_size, array); 121*ed170139SJacob Faibussowitsch 122*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListGet(fl_dup, &array, &n)); 123*ed170139SJacob Faibussowitsch PetscCheck((size_t)n == expected_fl_dup_size, PETSC_COMM_SELF, PETSC_ERR_PLIB, "PetscFunctionListGet() returned unexpected size %d, expected %zu", n, expected_fl_dup_size); 124*ed170139SJacob Faibussowitsch PetscCheckArrayPointer(expected_fl_dup_size, array); 125*ed170139SJacob Faibussowitsch for (int i = 0; i < n; ++i) PetscCall(PetscViewerASCIIPrintf(viewer, "%d: %s\n", i + 1, array[i])); 126*ed170139SJacob Faibussowitsch PetscCall(PetscFree(array)); 127*ed170139SJacob Faibussowitsch // ensure that free-ing the array is OK 128*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListView(fl_dup, viewer)); 129*ed170139SJacob Faibussowitsch PetscFunctionReturn(0); 130*ed170139SJacob Faibussowitsch #undef PetscCheckArrayPointer 131*ed170139SJacob Faibussowitsch } 132*ed170139SJacob Faibussowitsch 133*ed170139SJacob Faibussowitsch int main(int argc, char *argv[]) 134*ed170139SJacob Faibussowitsch { 135*ed170139SJacob Faibussowitsch PetscViewer viewer; 136*ed170139SJacob Faibussowitsch PetscFunctionList fl = NULL, fl_dup = NULL; 137*ed170139SJacob Faibussowitsch size_t fl_size, fl_dup_size; 138*ed170139SJacob Faibussowitsch 139*ed170139SJacob Faibussowitsch PetscFunctionBeginUser; 140*ed170139SJacob Faibussowitsch PetscCall(PetscInitialize(&argc, &argv, NULL, help)); 141*ed170139SJacob Faibussowitsch PetscCheck(num_names == num_funcs, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Number of functions %zu != number of function names %zu", num_funcs, num_names); 142*ed170139SJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(PETSC_COMM_WORLD, &viewer)); 143*ed170139SJacob Faibussowitsch 144*ed170139SJacob Faibussowitsch PetscCall(TestPetscFunctionListCreate(viewer, &fl, &fl_dup)); 145*ed170139SJacob Faibussowitsch PetscCall(TestPetscFunctionListFind(viewer, fl, fl_dup, &fl_size, &fl_dup_size)); 146*ed170139SJacob Faibussowitsch PetscCall(TestPetscFunctionListGet(viewer, fl, fl_dup, fl_size, fl_dup_size)); 147*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListPrintTypes(PETSC_COMM_WORLD, PETSC_STDOUT, "my_prefix_", "-petsc_function_type", "Description", "PetscFunctionList", fl_dup, "foo", "bar")); 148*ed170139SJacob Faibussowitsch 149*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListDestroy(&fl)); 150*ed170139SJacob Faibussowitsch PetscCheck(fl == NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Failed to destroy PetscFunctionList, pointer (%p) is non-null", (void *)fl); 151*ed170139SJacob Faibussowitsch PetscCall(PetscFunctionListDestroy(&fl_dup)); 152*ed170139SJacob Faibussowitsch PetscCheck(fl_dup == NULL, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Failed to destroy PetscFunctionList, pointer (%p) is non-null", (void *)fl_dup); 153*ed170139SJacob Faibussowitsch PetscCall(PetscFinalize()); 154*ed170139SJacob Faibussowitsch return 0; 155*ed170139SJacob Faibussowitsch } 156*ed170139SJacob Faibussowitsch 157*ed170139SJacob Faibussowitsch /*TEST 158*ed170139SJacob Faibussowitsch 159*ed170139SJacob Faibussowitsch test: 160*ed170139SJacob Faibussowitsch 161*ed170139SJacob Faibussowitsch TEST*/ 162