Ramón Casero Cañas on Thu, 23 Jan 2003 18:18:48 +0100 (MET) |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
PARI hangs with initialize / freeall / initialize |
For my program the inversion takes very little, and it needs memory, so at the beginning of the function there's a pari stack initialization, and before returning, the stack is freed. But two consecutive calls to the function hang the Linux terminal where the program runs. A CTRL-C says *** user interrupt. but it doesn't release the terminal, and the CPU load remain 100%. A kill command must be executed from another terminal in order to stop the program. The test program is compiled and linked with g++ 2.95.4: --------------------------------------------------------------------- /* File m_modulo2.cpp */ #include <iostream> // for std::cout #include <exception> #include <typeinfo> // #include <fstream> // for ifstream typedef enum{FALSE, TRUE} mybool; #define exor(a, b) ((mybool)(a != b)) extern "C" { // #include "include/gamatrix.h" /* mybool inverse_mat_mod2(mybool **_a, unsigned _size); */ mybool inverse_mat_mod2(mybool **_a, unsigned _size, mybool _CHECK); /* print_c_boolmatrix: print a C boolean matrix */ void print_c_boolmatrix(mybool **_a, unsigned _m, unsigned _n); } /* main */ /* argv[] (IN): file names array --- return n: n files were succesfully read, n > 0 return 0: none of the files could be read return -1: unexpected error --- read steiner problem from files */ int main(int argc, char *argv[]) { try { unsigned m, n; std::cout << "Hola mundo" << std::endl; // boost::array<BoolMatrix::index, 2> shape = {{ 5, 8 }}; // BoolMatrix *A; // boost::array<BoolMatrix::index, 2> dims = {{20, 15}}; // A.reshape(dims); // print_multi_array(A); const unsigned a_size = 32; const bool a_const[a_size][a_size] = { {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 1}, {1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}, {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0}, {0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1}, {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1}, {0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1}, {1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0}, {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0}, {0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1}, {0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1}, {0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0}, {0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}, {0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0}, {0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0}, {1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0}, {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0}, {1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1}, {0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0}, {0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1}, {0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0}, {1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0} }; mybool **a; a = new (mybool *)[a_size]; for (m = 0; m < a_size; ++m) { a[m] = new mybool[a_size]; for (n = 0; n < a_size; ++n) { a[m][n] = (mybool)a_const[m][n]; } } // print_c_boolmatrix(a, a_size, a_size); if (inverse_mat_mod2(a, a_size, TRUE)) { std::cout << "right inversion" << std::endl; // print_c_boolmatrix(a, a_size, a_size); } else { std::cout << "wrong inversion" << std::endl; return 0; } if (inverse_mat_mod2(a, a_size, TRUE)) { std::cout << "right inversion" << std::endl; // print_c_boolmatrix(a, a_size, a_size); } else { std::cout << "wrong inversion" << std::endl; return 0; } return 1; } catch (char *s) { std::cout << "exception! " << s << std::endl; return 0; } catch (std::exception& e) { std::cout << "exception! " << e.what() << std::endl; } catch (...) { std::cout << "unexpected exception!" << std::endl; return -1; } } --------------------------------------------------------------------------- The functions file is compiled with gcc 2.95.4 --------------------------------------------------------------------- /* File gamatrix.cpp */ /* Thanks to Karim Belabas and Bill Allombert for his help with this code */ // #include <iostream> // for std::cout #include "include/gamatrix.h" #include <pari/pari.h> // #include "/usr/src/pari-2.2.4.alpha/src/basemath/base3.c" // GEN u_FpM_inv(GEN a, ulong p); void freeall(void); // thanks, Karim void pari_sig_init(void (*f)(int)); // thanks, Karim // extern "C" { // void pari_sig_init(void (*f)(int)); // } /* inverse_mat_mod2: overwrites a matrix modulo 2 with its inverse; * input is a mybool matrix, but internally, PARI library types are * used */ /* return true if it has inverse and false if not or cannot be computed */ /* mybool inverse_mat_mod2(mybool **_a, unsigned _size) { */ /* return inverse_mat_mod2(_a, _size, true); */ /* } */ mybool inverse_mat_mod2(mybool **_a, unsigned _size, mybool _CHECK) { GEN a; // temp matrix by columns unsigned i, j; // counter unsigned sizepari = _size + 1; GEN z; // auxiliary element of the matrix GEN v; // auxiliary element of the matrix long paristacksize = 500000; long total_size = sizepari * sizepari + _size * _size * 9; // thanks, Karim GEN determinant; GEN ainv; printf("inverse_mat_mod2: getting into pari function\n"); // std::cout << "getting into pari function" << std::cout; paristacksize = sizeof(long) * total_size * 10; // thanks again pari_init(paristacksize, 2); // init PARI stack printf("inverse_mat_mod2: stack initialized\n"); // std::cout << "inverse_mat_mod2: stack initialized" << std::cout; /* allocate memory for the temp matrix * note: remember that PARI matrices of mxn need (m+1)x(n+1), and * that elements go a[1], a[2], ..., while a[0] is for type * information */ printf("inverse_mat_mod2: size = %d\n", _size); // std::cout << "inverse_mat_mod2: size = " << _size << std::endl; a = cgetg(sizepari, t_MAT); // `a' has _size columns for (i = 1; i <= _size; ++i) { // allocate `a' columns of _size elements a[i] = lgetg(sizepari, t_COL); } for (i = 1; i <= _size; ++i) { // allocate space for elements v = (GEN)a[i]; for (j = 1; j <= _size; ++j) { v[j] = lgetg(3, t_INTMOD); z = (GEN)v[j]; z[1] = lstoi(2); // modulo 2 if (_a[j-1][i-1]) z[2] = un; else z[2] = zero;//lstoi(0); } } printf("inverse_mat_mod2: assigment done\n"); // std::cout << "inverse_mat_mod2: assigment done" << std::endl; /* compute determinant to check invertibility */ determinant = det(a); printf("Hi\n"); if (determinant == gzero) { printf("determinant is zero\n"); printf("By\n"); freeall(); printf("By\n"); pari_sig_init(SIG_DFL); printf("By\n"); return FALSE; } /* invert matrix */ ainv = ginv(a); printf("inverse_mat_mod2: matrix inverted\n"); // std::cout << "inverse_mat_mod2: matrix inverted" << std::endl; /* check whether the inverse is valid */ if (_CHECK) { GEN a_ainv; a_ainv = gmul(a, ainv); for (i = 1; i <= _size; ++i) { v = (GEN)a_ainv[i]; for (j = 1; j <= _size; ++j) { z = (GEN)v[j]; if ((i == j) != itos((GEN)z[2])) { freeall(); pari_sig_init(SIG_DFL); return FALSE; } } } } /* for no _CHECK or valid inversion, overwrite input array with inverse matrix */ for (i = 1; i <= _size; ++i) { v = (GEN)ainv[i]; for (j = 1; j <= _size; ++j) { z = (GEN)v[j]; _a[j-1][i-1] = (mybool)itos((GEN)z[2]); } } /* free PARI's memory (thanks Karim) */ freeall(); pari_sig_init(SIG_DFL); return TRUE; } /* print_c_myboolmatrix: print a C myboolean matrix */ void print_c_boolmatrix(mybool **_a, unsigned _m, unsigned _n) { unsigned m, n; printf("{\n"); for (m = 0; m < _m; ++m) { printf("{"); for (n = 0; n < _n; ++n) { printf("%d ", _a[m][n]); if (n == _n - 1) { printf("}\n"); } else { printf(" "); } } } printf("}\n"); return; } /* XOR function */ /* mybool exor(mybool a, mybool b) { return (mybool)(a != b); } */ ---------------------------------------------------------------------- And the included headers file just have ------------------------------------------------------------------- #ifndef MODULO2_H #define MODULO2_H typedef enum{FALSE, TRUE} mybool; /* inverse_mat_mod2: overwrites a matrix modulo 2 with its inverse; * input is a bool matrix, but internally, PARI library types are * used */ /* mybool inverse_mat_mod2(mybool **_a, unsigned _size); */ mybool inverse_mat_mod2(mybool **_a, unsigned _size, mybool _CHECK); /* print_c_boolmatrix: print a C boolean matrix */ void print_c_boolmatrix(mybool **_a, unsigned _m, unsigned _n); /* logic XOR function */ /* mybool exor(mybool a, mybool b); */ #define exor(a, b) ((mybool)(a != b)) #endif -------------------------------------------------------------------- regards, Ramón. -- +++ GMX - Mail, Messaging & more http://www.gmx.net +++ NEU: Mit GMX ins Internet. Rund um die Uhr für 1 ct/ Min. surfen!