siddharth-maddali/HierarchicalSmooth

Data preparation for the C++ version

xiaotingz opened this issue · 16 comments

Hi Sid,

Again, thanks for putting upt the C++ version.

I compiled it as instructed and got HierarchicalSmoothFrontEnd.mexmaci64. But Matlab crashes when I try to use HierarchicalSmoothFrontEnd function.

I have checked the function input order and it seems to be HierarchicalSmoothFrontEnd(tri, xdat, fl, ntype) but that didn't work, neither did the order HierarchicalSmoothFrontEnd(tri, xdat, fl, ntype). Also thought about data type and tried to convert tri, fl and ntype intro int32 but the program also crashed. Maybe it's a data shape issue but I'm not that familiar with C++ data.

Can you put up an example about using the C++ file with one of the examples?

Thanks!

Hi @xiaotingz,
sorry for the late reply; did you try checking the dimensions of the arrays that you're inputting? tri should be nx3, xdat should be 3xn, fl should be nx2, ntype should be nx1. These types are defined in Types.h. If these dimensions are not satisfied, the Matlab will likely crash.

I've not included proper type checking in the HierarchicalSMoothFrontEnd.cpp wrapper, it just assumes you're assigning the dimensions correctly to the C++ object.

@mward22 By smoothing grains, do you mean smoothing features internal to the grain, like orientations? No, this is not implemented in HierarchicalSMooth. It's only a boundary smoothing technique...for now. I believe DREAM.3D already has other feature smoothing capabilities.

I could use some help in developing a wrapper for DREAM.3D, it's been on the agenda but I've not found the time to do it.

@mward22 I'm not familiar with Neper, but you should be able to get HSmooth do what you're describing. As long as you label the different interfaces of your single grain with different facelabels, and clearly label the nodetypes, it's possible.

Glad you're using HSmooth, please do cite the paper in your work!
https://www.sciencedirect.com/science/article/pii/S0927025616303913

@xiaotingz If you can confirm that Matlab is no longer crashing, I can close this issue.
Thanks!

Closing due to inactivity.

Sorry for this late follow up.. I'll set up an email notification for the github updates.

The input dimension seems to be right but the program still crahses. I was using the suggested examples in the pasted my commands below. Can you check if it will work on your computer? In case it's something like a MATLAB version problem.

xdat = load( '../../examples/ex0/SharedVertexList.txt' );
xdat = xdat';
tri = int32(1 + load( '../../examples/ex0/SharedTriList.txt' ));
fl = int32(load( '../../examples/ex0/FaceLabels.txt' ));
f = find( any( fl==-1 | fl==0, 2 ) );
fl( f, : ) = [];
tri( f, : ) = [];
ntype = int32(load( '../../examples/ex0/NodeType.txt' ));
HierarchicalSmoothFrontEnd(tri, xdat, fl, ntype)

For the last line of cammond, I wasn't really sure so I tried HierarchicalSmoothFrontEnd(xdat, tri, fl, ntype) but didn't work.

Thanks for the help.

Hi @xiaotingz
I reproduced the Matlab crash that you're talking about, and managed to fix it on my machine. The problem lies deep within Matlab itself: when you boot Matlab, it dynamically links to a default version of the C++ standard library that ships with it. However, a different version of this library was likely used when you compiled HierarchicalSmooth using the Makefile, outside Matlab. This incompatibility is seen only during runtime.

The following guide for Linux and Mac should help you out (Sorry, but I have no idea how to do this on Windows):

  1. Compile HierarchicalSMooth with the Makefile, outside Matlab in the command line (make clean && make).
  2. Run the CreateMatlabMex.m script as usual, within Matlab.
  3. Type this in the Matlab command line:
    !ldd <mexfile> | grep libstdc++
    where <mexfile> is the Matlab executable that CreateMatlabMex.m generates. For me, it was HierarchicalSmoothFrontEnd.mexa64. Don't forget the ! at the beginning of the command.

When you do this, you should see something like:
libstdc++.so.6 => /usr/local/MATLAB/R2017b/sys/os/glnxa64/libstdc++.so.6 (0x00007f57a2f34000)

This is the location of the libstdc++ library that Matlab uses by default. As you can see, it's in the Matlab directory. This is what you need to change. You need to trick Matlab into using the more updated one that your operating system uses.

The way I did this was to change the LD_PRELOAD environment variable to point to the updated libstdc++. First, I located the updated library from the command line, outside Matlab:
ldd libhsmooth.so | grep libstdc++
which gave me:
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f3648617000)

Then I added this alias to my ~/.bash_aliases file:
alias matlab='LD_PRELOAD=/usr/lib/x86_64-linux-gnu/libstdc++.so.6 /usr/local/bin/matlab'

Everytime you want matlab to link to the new libstdc++, you should now start it from the command line by typing matlab &. There are smarter ways of doing this, but I'm too lazy to google them. Now, from within Matlab, go back and run CreateMatlabMex.m again. Try !ldd <mexfile> | grep libstdc++, and confirm that Matlab sees the new libstdc++ instead of the default one. This should prevent the crash next time. You might get a warning that some nodes were not smoothed, but you can ignore it.

Let me know if this works.

Thanks for the response!

I tried the solution and got stucked at the third step. I'm using mac, which doesn't support ldd command but there is an equivalent one otool -L.

I tried !otool -L HierarchicalSmoothFrontEnd.mexmaci64 | grep libstdc++ but it didn't show anything. Then I tried !otool -L HierarchicalSmoothFrontEnd.mexmaci64 /bin/ls, which gave the following info:

HierarchicalSmoothFrontEnd.mexmaci64:
	/System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa (compatibility version 1.0.0, current version 20.0.0)
	@rpath/libmx.dylib (compatibility version 0.0.0, current version 0.0.0)
	/usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1)
/bin/ls:
	/usr/lib/libutil.dylib (compatibility version 1.0.0, current version 1.0.0)
	/usr/lib/libncurses.5.4.dylib (compatibility version 5.4.0, current version 5.4.0)
	/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0)

Seems like there is no libstdc++.

Hmm ok...This fix works perfectly well on my Linux box. Looks like Matlab on Mac is beyond my hacking abilities. I was hoping that the Unix similarity would make the fix identical in both cases. Apparently the std C++ library version used in Mac is called libc++.1.dylib.

Try runnng !otool -L HierarchicalSmoothFrontEnd.mexmaci64 | grep libc++ from Matlab as well as otool -L HierarchicalSmoothFrontEnd.mexmaci64 | grep libc++ from the Unix shell (without the !), outside Matlab. Do they show the same version of libc++? Then, try otool -L libhsmooth.so in the Unix shell, to see that even libhsmooth links to the same version.

Yes they are the same version. But it seems like something was different about /usr/lib/libSystem.B.dylib though. Inside matlab is current version 1197.1.1 and out side is current version 1213.0.0 Was that the same on your computer?

Interesting. I don't know what that library is. But clearly Matlab is using an older version. I'm not sure how to get Matlab to point to the newer version in Mac, or if this is even the real problem for Matlab crashing. Maybe you can open an issue with Mathworks and ask them. I'm sure they'll be happy to help.

I notice you're casting tri, fl and ntype as int32. This might be another reason for your crash. Try without this casting and see if it works. The conversion is already taking place inside HierarchicalSmoothFrontEnd.cpp, and you doing the cast outside again might be causing additional problems.

I started without applying int32 so that shouldn't be the problem.

Haha~ I'll try google it and maybe ask a friend with a Linux computer for help. Thanks for the kind answers!