Archive for November, 2015

SSE illegal instruction run-time error in Eigen

Monday, November 30th, 2015

While debugging the other day we ran into a runtime error:


`
0x0000000000655679 in _mm_set_epi32 (__q0=0, __q1=0, __q2=0, __q3=0)
    at /usr/lib/gcc/x86_64-linux-gnu/4.9/include/emmintrin.h:595
595       return __extension__ (__m128i)(__v4si){ __q0, __q1, __q2, __q3 };
(gdb) bt
#0  0x0000000000655679 in _mm_set_epi32 (__q0=0, __q1=0, __q2=0, __q3=0)
    at /usr/lib/gcc/x86_64-linux-gnu/4.9/include/emmintrin.h:595
#1  _mm_set1_epi32 (__A=0) at /usr/lib/gcc/x86_64-linux-gnu/4.9/include/emmintrin.h:635
#2  Eigen::internal::pset1(Eigen::internal::unpacket_traits::type const&) (from=@0x7fffffffd61c: 0) at /usr/local/include/eigen3/Eigen/src/Core/arch/SSE/PacketMath.h:115
#3  0x00000000006a88ee in Eigen::internal::scalar_constant_op::packetOp (this=0x7fffffffd61c)
    at /usr/local/include/eigen3/Eigen/src/Core/Functors.h:522
#4  0x00000000006a0ea4 in Eigen::CwiseNullaryOp, Eigen::Matrix >::packet<0> (this=0x7fffffffd610, index=0)
    at /usr/local/include/eigen3/Eigen/src/Core/CwiseNullaryOp.h:88
#5  0x0000000000698582 in Eigen::DenseCoeffsBase, 1>::copyPacket, Eigen::Matrix >, 1, 0> (
    this=0x7fffffffd6a0, index=0, other=...) at /usr/local/include/eigen3/Eigen/src/Core/DenseCoeffsBase.h:537
#6  0x000000000068f403 in Eigen::internal::assign_impl, Eigen::CwiseNullaryOp, Eigen::Matrix >, 3, 0, 0>::run (dst=..., 
    src=...) at /usr/local/include/eigen3/Eigen/src/Core/Assign.h:410
#7  0x000000000068416e in Eigen::DenseBase >::lazyAssign, Eigen::Matrix > > (this=0x7fffffffd6a0, 
    other=...) at /usr/local/include/eigen3/Eigen/src/Core/Assign.h:499
#8  0x000000000067980d in Eigen::PlainObjectBase >::lazyAssign, Eigen::Matrix > > (
    this=0x7fffffffd6a0, other=...) at /usr/local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:414
#9  0x000000000066c1f8 in Eigen::internal::assign_selector, Eigen::CwiseNullaryOp, Eigen::Matrix >, false, false>::run (
    dst=..., other=...) at /usr/local/include/eigen3/Eigen/src/Core/Assign.h:520
#10 0x00000000006619b3 in Eigen::PlainObjectBase >::_set_noalias, Eigen::Matrix > > (
---Type  to continue, or q  to quit---
    this=0x7fffffffd6a0, other=...) at /usr/local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:621
#11 0x000000000069e5b7 in Eigen::PlainObjectBase >::_set_selector, Eigen::Matrix > > (
    this=0x7fffffffd6a0, other=...) at /usr/local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:606
#12 0x000000000069590c in Eigen::PlainObjectBase >::_set, Eigen::Matrix > > (this=0x7fffffffd6a0, 
    other=...) at /usr/local/include/eigen3/Eigen/src/Core/PlainObjectBase.h:598
#13 0x000000000068bc41 in Eigen::Matrix::operator=, Eigen::Matrix > > (this=0x7fffffffd6a0, other=...)
`

We were getting an “illegal instruction” trap. Finally we tracked down the issue to be that we’d compiled using the -msse4.2 flag on a machine that did not support SSE 4.2. In retrospect we should have suspected this from the header in which the error occurred (emmintrin.h). We had accidentally cross-compiled and then tried to run a bogus binary. To fix this issue we deleted the flag and replaced it with -march=native.

GLSL shaders using normal as vertex positions

Saturday, November 14th, 2015

Every few months I need to relearn how properly set up a GLSL shader with a vertex array object. This time I was running into a strange bug where my normals were being used as vertex positions. I had a simple pass-through vertex shader looking something like:

#version 330 core
in vec3 position;
in vec3 normal;
out vec3 frag_normal;
void main()
{                                      
  gl_Position = position;
  frag_normal = normal;
}

And on the CPU side I was setting up my vertex attributes with:

glVertexAttribPointer(0,3, ... );
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER,position_buffer_object);
glVertexAttribPointer(1,3, ... );
glEnableVertexAttribArray(1);
glBindBuffer(GL_ARRAY_BUFFER,normal_buffer_object);

My folly was assuming that because I’d declared position and normal in that order in the vertex shader that they’d be bound to attribute ids 0 and 1 respectively. Not so! After some head-slamming I thought to query these ids using:

glGetAttribLocation(program_id,"position");
glGetAttribLocation(program_id,"normal");

And found that for whatever reason position was bound to 0 and normal was bound to 1. Of course I then tried hacks to get these to reverse order, or I could hard code the different order. But there appears to be two correct options for fixing this problem:

The obvious one is to use glGetAttribLocation when creating the vertex array object:

glVertexAttribPointer(glGetAttribLocation(program_id,"position"),3, ... );
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER,position_buffer_object);
...

I was a little bothered that this solution requires that I know which shader is going to be in use at the time of creating the vertex array object.

The opposite solution is to assume a certain layout on the CPU-side when writing the shader:

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;

Now I can be sure that using ids 0 and 1 will correctly bind to position and normal respectively.

Determine how much space is used by .git/.svn/.hg in a directory

Thursday, November 12th, 2015

Here’s a nasty little bash one-liner to determine how much space is being “wasted” but .svn/ or .git/ or .hg/ repos in your current directory:

du -k | sed -nE 's/^([0-9]*).*\.(svn|git|hg)$/\1/p' | awk '{s+=$1*1024} END {print s}' | awk '{ sum=$1 ; hum[1024**3]="Gb";hum[1024**2]="Mb";hum[1024]="Kb"; for (x=1024**3; x>=1024; x/=1024){ if (sum>=x) { printf "%.2f %s\n",sum/x,hum[x];break } }}'

Remove prince annotation from pdf

Tuesday, November 10th, 2015

Here’s a little perl script to remove the prince watermark note from a pdf:

perl -p -e '!$x && s:/Annots \[[0-9]+ 0 R [0-9]+ 0 R ?([^\]]+)\]:/Annots [\1]: && ($x=1)' input.pdf > output.pdf

Update:

So, unfortunately the simple perl hack will “damage” the pdf. It seems that most viewers will ignore this, but I was alerted that a popular ipad reader “GoodReader” produces an ominous “This file is damaged” warning (though it then renders OK).

I couldn’t quite reverse engineer why, but here’s a temporary albeit heavy-handed fix. After running the perl script, also repair the pdf with ghostscript:

gs -o output.pdf  -sDEVICE=pdfwrite -dPDFSETTINGS=/prepress input.pdf

Note that output.pdf cannot be the same as input.pdf or it quietly creates an empty pdf instead.

Update:

Even better you can directly remove the specific Annotation from prince:

perl -i -p -e 's:/(Rect \[572\.0000 716\.0000 597\.0000 741\.0000\]|Contents \(This document was created with Prince, a great way of getting web content onto paper.\))::' input-and-output.pdf

Update:

Or even even better better:

  perl -i -pe 'BEGIN{undef $/;} s:/Rect.*?Contents \(This document was created with Prince, a great way of getting web content onto paper.\)::smg' input-and-output.pdf

Conservative voxelization in gptoolbox

Tuesday, November 3rd, 2015

A while ago I implemented a function to voxelize a given triangle mesh in matlab as part of gptoolbox. Rather than use 3D-Bresenham-style rasterization, I needed a conservative voxelization: where every point (not just vertex) on the mesh is contained inside the voxelization. In other words, output all voxels that intersect the triangle mesh.

Here’s a little snippet to produce the following meshes:

for k = [10 20 40 80]
  [W,BC,DV,Q] = voxelize(V,F,k,'Pad',1);
  [DV,I] = remove_unreferenced(DV,Q);
  Q = I(Q);
  d = render_in_cage(V,F,DV,Q,'ColorIntersections',false);
  d.tc.LineWidth = 2;
end

big alien model voxelized
big alien model voxelized
big alien model voxelized
big alien model voxelized