www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Catching Acces Violation/Segmentation Fault

reply Silverling <este_aqui_ hotmail.com.remove.underscores> writes:
I am programming a Matrix class to be used like a primitive type (overloaded
operators, identity, transpose, the whole shebang) and one of the constructors
_may_ cause an Access Violation (or Segmentation Fault, if you prefer the old
Linux SIGSEG) if the class's user is foolish. Is there a way to catch this
errors?

Secondly, would this class be of any use to anyone? I'll gladly distribute it
all around (OpenSourced, of course). It is 'templatized'. I'm unsure if Phobos
or Tango would want such class if I submited it.
May 09 2007
next sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Silverling wrote:
 I am programming a Matrix class to be used like a primitive type (overloaded
operators, identity, transpose, the whole shebang) and one of the constructors
_may_ cause an Access Violation (or Segmentation Fault, if you prefer the old
Linux SIGSEG) if the class's user is foolish. Is there a way to catch this
errors?
 
 Secondly, would this class be of any use to anyone? I'll gladly distribute it
all around (OpenSourced, of course). It is 'templatized'. I'm unsure if Phobos
or Tango would want such class if I submited it.

What are the specifics of your class? Is it an arbitrary MxN sized matrix? Will it use vendor-provided accelerated BLAS libraries where available? Is it parameterized on element type? Storage format? Can it handle different storage schemes (e.g. sparse formats like CSC, CSR, banded, symmetric). If it's got all that, then I'm definitely interested. A port of something like Boost::ublas would be great. (http://www.boost.org/libs/numeric/ublas/doc/index.htm). I've started on a multidimensional array class that can be used as a matrix if desired. It's based loosely on NumPy's multidimensional arrays. http://www.dsource.org/projects/multiarray.html . It's hooked up to BLAS and LAPACK for some basic operations like multiplication, linear system solving, and least squares problems. Doesn't do sparse at all though. Oskar Linde also posted a multidim array struct a while back. Same basic philosophy, but using a struct instead of a class. I'm probably going to switch over to using a struct eventually too, once D gets const ref. --bb
May 09 2007
parent reply Silverling <este_aqui_ hotmail.com.remove.underscores> writes:
 Is it an arbitrary MxN sized matrix?

 Will it use vendor-provided accelerated BLAS libraries where available?

 Is it parameterized on element type?

 Storage format?

 Can it handle different storage schemes (e.g. sparse formats like CSC, CSR,
banded, symmetric).

Implementing such schemes would only need to override the opIndex and opIndexAssign. The current implementation still accesses the matrix's data directly, but that can be easily changed (which I will, due to your idea). I've started this module because I wanted to learn operator overloading on D. I'm having a small issue on overloading the opMul. I templatized it but I need a specialization to multipliy by a matrix. DMD is not accepting void opMul(T:Matrix)(T mult) meanwhile I've shifted my attention towards inverse matrix, determinant and equation system solving. Later on I'll use it for Hamming coding (to port a script of mine from MatLab), where I'll test the matrix's behavior with type 'bool', although for memory purposes, it'll use bit arrays or (a lot of) masking. I'll send the source if you'd like to take a peek.
May 09 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Silverling wrote:
 Is it an arbitrary MxN sized matrix?


 Will it use vendor-provided accelerated BLAS libraries where available?


BLAS is good if you're going to be working with big matrices. But for a 4x4 view mat, there's not much point.
 Is it parameterized on element type?


Yeh, that's what I mean. "parameterized on type" == The type of the elements is a template parameter.
 Storage format?


Got it. You may be better off with Type[row*col]. Type[row][col] is an array of col pointers to 1D arrays of rows, rather than densely packed memory.
 
 Can it handle different storage schemes (e.g. sparse formats like CSC, CSR,
banded, symmetric).


For 3D linear algebra (or 4D homogeneous linalg) there's helix. http://www.dsource.org/projects/helix It's pretty decent -- even includes a polar decomposition routine. It didn't have 2D classes, which I missed, so I added those to my own copy. There've been a few other folks to implement 3D linalg stuff in D as well. Don't have any links for those though. Anyway, for 3D stuff I think using a generic MxN matrix class is overkill.
 and vectorial calculus.
 Implementing such schemes would only need to override the opIndex and
opIndexAssign. 
 The current implementation still accesses the matrix's data directly,
 but that can be easily changed (which I will, due to your idea).

But if you have different storage schemes you want to be able to do things like sparse_mat * dense_vec, or dense_mat + upper_triangular_mat. It's a multiple dispatch problem so it requires some thinking. The approach I've seen is to
 I've started this module because I wanted to learn operator overloading on D.
I'm having a small issue on overloading the opMul. I templatized it but I need
a specialization to multipliy by a matrix. DMD is not accepting
 void opMul(T:Matrix)(T mult)

My understanding is that if you use specialization in D it disables IFTI (the thing that allows to to call a template function without specifying parameters). So to use that you'd need to call it explicitly as A.opMul!(typeof(B))(B). Not so nice. The workaround is generally to use some static ifs or static asserts inside the template instead. void opMul(T)(T mult) { static assert(is(T:Matrix), "Mult only works for things derived from Matrix"); } --bb
May 09 2007
next sibling parent Bill Baxter <dnewsgroup billbaxter.com> writes:
Bill Baxter wrote:

 But if you have different storage schemes you want to be able to do 
 things like sparse_mat * dense_vec,  or dense_mat + 
 upper_triangular_mat.   It's a multiple dispatch problem so it requires 
 some thinking.  The approach I've seen is to

Oops forgot to compelete that thought. Take a look at things like Boost::ublas or MTL (Matrix Template Library) if you want some ideas how to deal with different storage mechanisms. --bb
May 09 2007
prev sibling parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Bill Baxter wrote:
 Silverling wrote:
 Bill Baxter wrote:
 Storage format?


Got it. You may be better off with Type[row*col]. Type[row][col] is an array of col pointers to 1D arrays of rows, rather than densely packed memory.

No, it's definitely densely packed memory. Static arrays always put their elements directly where you put the array itself, "inline". Only dynamic (Type[]) and associative (Type[Type2]) arrays use "hidden" pointers.
May 09 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Frits van Bommel wrote:
 Bill Baxter wrote:
 Silverling wrote:

 Storage format?


Got it. You may be better off with Type[row*col]. Type[row][col] is an array of col pointers to 1D arrays of rows, rather than densely packed memory.

No, it's definitely densely packed memory. Static arrays always put their elements directly where you put the array itself, "inline". Only dynamic (Type[]) and associative (Type[Type2]) arrays use "hidden" pointers.

Ok, but he said it was going to be resizeable. Does that change your answer? --bb
May 09 2007
parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
Bill Baxter wrote:
 Frits van Bommel wrote:
 Bill Baxter wrote:
 Silverling wrote:

 Storage format?


Got it. You may be better off with Type[row*col]. Type[row][col] is an array of col pointers to 1D arrays of rows, rather than densely packed memory.

No, it's definitely densely packed memory. Static arrays always put their elements directly where you put the array itself, "inline". Only dynamic (Type[]) and associative (Type[Type2]) arrays use "hidden" pointers.

Ok, but he said it was going to be resizeable. Does that change your answer?

Hmm... Right. I don't see how he could do that for non-square matrices without allocating a new matrix; if general resizing is implemented, he must've used a different storage format (not Type[row*col] either, but Type[] with length (row*col) would work). Maybe he was just inaccurate with in his answer...
May 10 2007
parent Silverling <este_aqui_ hotmail.com.remove.underscores> writes:
Frits van Bommel Wrote:

 Bill Baxter wrote:
 Frits van Bommel wrote:
 Bill Baxter wrote:
 Silverling wrote:

 Storage format?


Got it. You may be better off with Type[row*col]. Type[row][col] is an array of col pointers to 1D arrays of rows, rather than densely packed memory.

No, it's definitely densely packed memory. Static arrays always put their elements directly where you put the array itself, "inline". Only dynamic (Type[]) and associative (Type[Type2]) arrays use "hidden" pointers.

Ok, but he said it was going to be resizeable. Does that change your answer?

Hmm... Right. I don't see how he could do that for non-square matrices without allocating a new matrix; if general resizing is implemented, he must've used a different storage format (not Type[row*col] either, but Type[] with length (row*col) would work). Maybe he was just inaccurate with in his answer...

With resizeable arrays, I init a new array like this Type[][] data=new Type[][](rows, cols); Since array resizings only occur in multiplications and transposes of matrices of non-square matrices, I believe it to be doable.
May 10 2007
prev sibling next sibling parent reply BCS <ao pathlink.com> writes:
Reply to silverling,

 I am programming a Matrix class to be used like a primitive type
 (overloaded operators, identity, transpose, the whole shebang) and one
 of the constructors _may_ cause an Access Violation (or Segmentation
 Fault, if you prefer the old Linux SIGSEG) if the class's user is
 foolish. Is there a way to catch this errors?

Put this in somewhere at global scope and all seg-v's will throw an Error by passing signal a different function you can make it do other things. // stubs for access to unix signal handeling alias void function(int) sighandler_t; extern (C) sighandler_t signal(int signum, sighandler_t handler); const int SIGHUP = 1; // Term Hangup detected on controlling terminal or death of controlling process const int SIGINT = 2; // Interrupt from keyboard const int SIGQUIT = 3; // Quit from keyboard const int SIGILL = 4; // Illegal Instruction const int SIGABRT = 6; // Abort signal from abort(3) const int SIGFPE = 8; // Floating point exception const int SIGKILL = 9; // Kill signal const int SIGSEGV = 11; // Invalid memory reference const int SIGPIPE = 13; // Broken pipe: write to pipe with no readers const int SIGALRM = 14; // Timer signal from alarm(2) const int SIGTERM = 15; // Termination signal static this() { // trap seg-v and report as error (not sure this is working) signal(SIGSEGV,function void(int i){throw new Error("SEGV");}); }
May 09 2007
next sibling parent reply Silverling <este_aqui_ hotmail.com.remove.underscores> writes:
BCS Wrote:

 Reply to silverling,
 
 I am programming a Matrix class to be used like a primitive type
 (overloaded operators, identity, transpose, the whole shebang) and one
 of the constructors _may_ cause an Access Violation (or Segmentation
 Fault, if you prefer the old Linux SIGSEG) if the class's user is
 foolish. Is there a way to catch this errors?

Put this in somewhere at global scope and all seg-v's will throw an Error by passing signal a different function you can make it do other things. // stubs for access to unix signal handeling alias void function(int) sighandler_t; extern (C) sighandler_t signal(int signum, sighandler_t handler); const int SIGHUP = 1; // Term Hangup detected on controlling terminal or death of controlling process const int SIGINT = 2; // Interrupt from keyboard const int SIGQUIT = 3; // Quit from keyboard const int SIGILL = 4; // Illegal Instruction const int SIGABRT = 6; // Abort signal from abort(3) const int SIGFPE = 8; // Floating point exception const int SIGKILL = 9; // Kill signal const int SIGSEGV = 11; // Invalid memory reference const int SIGPIPE = 13; // Broken pipe: write to pipe with no readers const int SIGALRM = 14; // Timer signal from alarm(2) const int SIGTERM = 15; // Termination signal static this() { // trap seg-v and report as error (not sure this is working) signal(SIGSEGV,function void(int i){throw new Error("SEGV");}); }

This is great! Thanks! Now I only need to throw an exception. Unfortunatly, it will only work on linux :( meaning the module is not portable.
May 09 2007
parent BCS <ao pathlink.com> writes:
Reply to silverling,

 BCS Wrote:
 
 Reply to silverling,
 
 I am programming a Matrix class to be used like a primitive type
 (overloaded operators, identity, transpose, the whole shebang) and
 one of the constructors _may_ cause an Access Violation (or
 Segmentation Fault, if you prefer the old Linux SIGSEG) if the
 class's user is foolish. Is there a way to catch this errors?
 


Unfortunatly, it will only work on linux :( meaning the module is not portable.

so just tell the win32 user to not be foolish <g>
May 09 2007
prev sibling parent reply Sean Kelly <sean f4.ca> writes:
Is it legal to throw an exception from a signal handler?  This
seems risky (though appealing).


Sean
May 09 2007
parent BCS <BCS pathlink.com> writes:
Sean Kelly wrote:
 Is it legal to throw an exception from a signal handler?  This
 seems risky (though appealing).
 
 
 Sean

It seems to work, OTOH I never catch it so it might be causing problems that I'm not noticing. Really the only reason I have it is so that my DIY stack trace works on seg-vs // at the top of *every* function scope(failure) writef("backtrace "__FILE__~itoa!(__LINE__)~\n);
May 10 2007
prev sibling parent "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Silverling" <este_aqui_ hotmail.com.remove.underscores> wrote in message 
news:f1sqc4$2jsj$1 digitalmars.com...
I am programming a Matrix class to be used like a primitive type 
(overloaded operators, identity, transpose, the whole shebang) and one of 
the constructors _may_ cause an Access Violation (or Segmentation Fault, if 
you prefer the old Linux SIGSEG) if the class's user is foolish. Is there a 
way to catch this errors?

void main() { try *cast(byte*)null = 0; catch(Exception e) writefln("I caught : ", e); } I hope this works on Linux too. I'm not sure if it will.
May 10 2007