9

I have an application using the Yeppp! SIMD library. The application is written in C#. It runs perfectly on Windows x86-32 and x86-64. However, when I run the application on a Raspberry Pi with Mono I get the following exception (not sure if it's an ARM issue, a Mono issue, or something else). I've tried running as root just to check, also same exception. I noticed the "UnixLibraryLoader" part of the stack trace so I made sure the Yeppp DLL (Yeppp.CLR.Bundle.dll) is in the same directory as the executable, which it is. Is this a problem with my code, the way I compiled it, or a problem with the library?

    Stacktrace:

  at <unknown> <0xffffffff>
  at (wrapper managed-to-native) Yeppp.UnixLibraryLoader.dlopen (string,int) <0xffffffff>
  at Yeppp.UnixLibraryLoader.Yeppp.INativeLibraryLoader.LoadLibrary (string) <0x0002f>
  at Yeppp.NativeLibrary..ctor (string,Yeppp.INativeLibraryLoader) <0x0006b>
  at Yeppp.Loader.LoadNativeLibrary () <0x000db>
  at Yeppp.Library.Init () <0x00027>
  at <Module>..cctor () <0x0000b>
  at (wrapper runtime-invoke) object.runtime_invoke_void (object,intptr,intptr,intptr) <0xffffffff>
  at <unknown> <0xffffffff>
  at SimdSpeedTest.Program.DisplayCpuFeatures () <0x00033>
  at SimdSpeedTest.Program.Main (string[]) <0x000c7>
  at (wrapper runtime-invoke) <Module>.runtime_invoke_void_object (object,intptr,intptr,intptr) <0xffffffff>

Native stacktrace:


Debug info from gdb:

[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
[New Thread 0xb5b7b430 (LWP 2272)]
0xb6eabaac in waitpid () from /lib/arm-linux-gnueabihf/libpthread.so.0
  Id   Target Id         Frame
  2    Thread 0xb5b7b430 (LWP 2272) "mono" 0xb6ea9770 in sem_wait@@GLIBC_2.4 () from /lib/arm-linux-gnueabihf/libpthread.so.0
* 1    Thread 0xb6f80000 (LWP 2271) "mono" 0xb6eabaac in waitpid () from /lib/arm-linux-gnueabihf/libpthread.so.0

Thread 2 (Thread 0xb5b7b430 (LWP 2272)):
#0  0xb6ea9770 in sem_wait@@GLIBC_2.4 () from /lib/arm-linux-gnueabihf/libpthread.so.0
#1  0x001fff10 in mono_sem_wait (sem=0x2f523c, alertable=1) at mono-semaphore.c:119
#2  0x0017db28 in finalizer_thread (unused=<optimized out>) at gc.c:1073
#3  0x001625b4 in start_wrapper_internal (data=0xb0d8c8) at threads.c:643
#4  start_wrapper (data=0xb0d8c8) at threads.c:688
#5  0x001f5c30 in thread_start_routine (args=0xac86c0) at wthreads.c:294
#6  0x00204268 in inner_start_thread (arg=0xac86b4) at mono-threads-posix.c:49
#7  0xb6ea2c00 in start_thread () from /lib/arm-linux-gnueabihf/libpthread.so.0
#8  0xb6e0f728 in ?? () from /lib/arm-linux-gnueabihf/libc.so.6
#9  0xb6e0f728 in ?? () from /lib/arm-linux-gnueabihf/libc.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

Thread 1 (Thread 0xb6f80000 (LWP 2271)):
#0  0xb6eabaac in waitpid () from /lib/arm-linux-gnueabihf/libpthread.so.0
#1  0x000b2148 in mono_handle_native_sigsegv (signal=<optimized out>, ctx=<optimized out>) at mini-exceptions.c:2299
#2  0x00027af8 in mono_sigsegv_signal_handler (_dummy=11, info=0xbe9280e0, context=0xbe928160) at mini.c:6777
#3  <signal handler called>
#4  0xb6f6d754 in ?? () from /lib/ld-linux-armhf.so.3
#5  0xbe9284a0 in ?? ()
Cannot access memory at address 0x3000
#6  0xbe9284a0 in ?? ()
Cannot access memory at address 0x3000
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
user9993
  • 5,833
  • 11
  • 56
  • 117
  • Cool that you're using Yeppp! ! – Z boson Jun 10 '15 at 06:57
  • Yeah I've been experimenting with it for a while now. I really like how it's avaliable for multiple languages and operating systems. Can't wait to then try combining it with parallel/async/concurrent/multi threaded code etc. for even more performance. – user9993 Jun 10 '15 at 07:56
  • I i'm staring with Raspberry-pi now. I have been using intel intrinsics for SIMD but I want my code on ARM now so I need NEON. Yeppp! seems like a good choice so I'll probably give it a try soon. I can't help you but the author of Yeppp! is on SO and may answer your question. – Z boson Jun 10 '15 at 08:00
  • Sounds good! Yeah he answered one of my questions about it before, I'm hoping perhaps he might answer this one :) – user9993 Jun 10 '15 at 08:01
  • Have you considered contacting the developer (http://www.yeppp.info/contact.html)? – Z boson Jun 12 '15 at 09:14
  • What is your hardware (which version of raspberry) and what OS are you running on (e.g. Raspbian)? If the Yeppp! DLL was compiled for ARM version 7 instead of ARM version 6 and you're not using a raspberry pi2 then it won't work. – Z boson Jun 17 '15 at 11:39
  • I'm using Raspberry Pi 1 Model B. How do I compile for that one? – user9993 Jun 17 '15 at 11:40
  • Well if you built the Yeppp library yourself I would guess it's okay. It's only a problem if you use a prebuilt binary compiled for ARM version 7 or if Yeppp requires ARM version 7. – Z boson Jun 17 '15 at 11:41
  • I didn't compile it I just grabbed the exe and the Yeppp CLR DLL and copied to the Pi – user9993 Jun 17 '15 at 11:43
  • BTW, I don't know Mono, but Linux/Raspian does not use DLLs (.dll), it uses shared libraries (.so files). – Z boson Jun 17 '15 at 11:43
  • okay, well then what hardware was the Yeppp CLR DLL made for? – Z boson Jun 17 '15 at 11:44
  • If it was made for ARM version 7 it won't work on Rasperry Pi 1 Model B. – Z boson Jun 17 '15 at 11:44
  • .NET/Mono executables and libraries are made for the runtime not a specific machine architecture so they work on anything that .NET/Mono run on so in theory this should all work. – user9993 Jun 17 '15 at 11:45
  • The whole point of Yeppp! is SIMD. For ARM that's Neon. The Raspberry PI 1 Model B does not have Neon. So Yeppp! would be useless on it. – Z boson Jun 17 '15 at 11:51
  • Oh wait what? Does it not have any SIMD capabilities at all? I thought it had Neon? – user9993 Jun 17 '15 at 11:52
  • I just looked at the Yeppp! files `binareis/linux/armhf/libyeppp.so` and `binareis/linux/armel/libyeppp.so` and both are made for ARM7 (use `readelf -A`. I don't know how to read the DLL file `binareis/linux/clr-2.0/libyeppp.so` but I assume it's built for ARM7 since only ARM7 has Neon. – Z boson Jun 17 '15 at 11:54
  • No, only Raspberry PI 2 has Neon. – Z boson Jun 17 '15 at 11:54
  • according to the website "Yeppp! detects all publicly announced ARM instruction sets, including ARMv6, ARMv7, VFPv3, VFPv4, NEON, NEONv2, half-precision extensions, and hardware division extension. Some extensions can be detected even if Linux kernel is not aware of them. Yeppp! compute kernels are optimized for ARM Vector Floating-Point (VFP) and NEON instruction sets." – Z boson Jun 17 '15 at 11:57
  • So I guess Yeppp! will take advantage of VFP with ARMv6 even if you don't have Neon so probably your problem is something else. – Z boson Jun 17 '15 at 11:58
  • But maybe the clr-2.0/libyeppp.so file is not built for ARMv6? – Z boson Jun 17 '15 at 12:00
  • This is strange. The readme says it should support arm-linux-softeabi-v5t but `readelf -A binareis/linux/armel/libyeppp.so` clearly shows it's built for v7`. If you try e.g. `readelf -A /bin/ls` in Raspian it shows that `ls` is built for v6. – Z boson Jun 17 '15 at 12:05
  • It's a real puzzler. Been scratching my head about it for a while now. – user9993 Jun 17 '15 at 12:05
  • Have you tried the preview release of Yeppp! (Yepppp! 1.0.1)? https://www.nuget.org/packages/Yeppp.CLR.Bundle/ It says "Cross-platform Yeppp! CLR DLL for .Net/Mono." I get the feeling that you need the preview release (compare at http://www.yeppp.info/downloads.html). – Z boson Jun 17 '15 at 12:44
  • That's actually where I got the file, from NuGet. – user9993 Jun 17 '15 at 14:35
  • In that case, maybe you have discovered one reason it's called a preview release. – Z boson Jun 18 '15 at 07:38
  • In regards to `readelf -A` I'm not sure it's reliable in this case. The library file`e.g. libyeppp.so` must be using a CPU dispatcher and include several object files for different instructions sets. I'm not sure what `readelf -A` does in this case. – Z boson Jun 18 '15 at 08:43

3 Answers3

3

I would guess Mono on the ARMV6 Hard-float architecture of RasPi, probably is having trouble in handling the intentional SIGILL issued by the feature detection code in Yepp (https://bitbucket.org/MDukhan/yeppp/src/40148ba4cdd00b03dfa880f6b7cecce83979c9d3/library/sources/library/Probe.arm.asm?at=default) and may be collapsing.

Detection depends on SIGILL handling just make the unsupported instructions being skipped. Other possibility is that the lib is not correctly retrieved from the resource (or the wrong one is retrieved as the Yeppp.Loader.LoadNativeLibrary guesses which native lib to use for the architecture it is running on) and when passing the execution to it things crash.

I second that you should contact the developer as I could not find any reference in the site, and on the source files I perused that indicate that RasPi and it's oldish version of ARM is supported.

PS.: I assumed you are using Raspbian that uses HardFloat, and a recent version of Mono (which initially was using the incompatible SoftFloat).

Monoman
  • 721
  • 10
  • 12
  • 1
    Yeppp! on its homepage says explicitly that it does support ARMv6 "Yeppp! detects all publicly announced ARM instruction sets, including ARMv6, ARMv7, VFPv3, VFPv4, NEON, NEONv2, half-precision extensions, and hardware division extension. Some extensions can be detected even if Linux kernel is not aware of them. Yeppp! compute kernels are optimized for ARM Vector Floating-Point (VFP) and NEON instruction sets." – Z boson Jun 19 '15 at 08:05
  • Thanks @Zboson for the clarification. :) – Monoman Jun 19 '15 at 15:22
  • Your assumptions turn out to be closer to the correct answer from the developer than mine. – Z boson Jul 03 '15 at 09:48
2

Now that the bounty is over let me put my comments into an answer here.

You're using a preview release so it's maybe not surprising that it's not working as your expect.


The Raspberry Pi 1 does not have NEON but does VFP2. The VFP instructions are not SIMD instructions despite the misleading acronym of Vector Floating Point (see arm-cortex-a8-whats-the-difference-between-vfp-and-neon and VFP SIMD Instructions, howto?).

VFPv2 was introduced with the ARMv5TE, ARMv5TEJ and ARMv6 architectures. So even though the source code for Yeppp! does not reference ARMV6 explicitly that does not necessarily mean it does not support VFPv2 since it does reference ARMV5T.

What would be the advantage of using Yeppp! with the Raspberry Pi 1 then since VFP instructions are not SIMD instructions? My guess is that GCC does not implement these well and so it may be advantageous to do it explicitly with Yeppp!.


I'm not sure what the peak flops of he Raspberry PI 1 is. However, benchmarks have measured

  • 0.041 DP GFLOPS
  • 0.192 SP GFLOPS

The cortex A7 cores, which which has NEON and VFP3, of the Raspberry Pi 2 can do:

  • 0.5 DP FLOPs/cycle: scalar VMLA.F64 every four cycles.
  • 1.0 DP FLOPs/cycle: scalar VADD.F64 every cycle.
  • 2.0 SP FLOPs/cycle: scalar VMLA.F32 every cycle.
  • 2.0 SP FLOPs/cycle: 2-wide VMLA.F32 every other cycle.

The Raspberry Pi 2 has four cores so the PEAK flops is 4* FLOPs/cycle/core.

Note that the peak FLOPS of Neon with the Cortex-A7 is the same as the peak FLOPS of VFP. The Cortex-A7 is 100% binary instruction set compatible with the Cortex-A15 which is why it's use in the ARM big.LITTLE design. So Neon is implemented in the Cortex-A7 only to be compatible.

I don't know about Integer operations per cycle yet.

However, there is another SIMD option for the Raspberry PI 1 and 2. You can use Integer SIMD instructions on the VideoCore IV (see also NEON instruction set support SIMD). You could implement fixed point with this. This could potentially give you a lot more performance than NEON anyway.

Z boson
  • 32,619
  • 11
  • 123
  • 226
2

Yeppp! supports two Linux ARM platforms:

  • ARMv5TE + soft-float ABI (arm-linux-gnueabi)
  • ARMv7-A + hard-float ABI (arm-linux-gnueabihf)

Most Linux distributions for Raspberry Pi use unusual ARMv6 + hard-float ABI. Yeppp!'s ARMv7-A + hard+float version uses Thumb-2 instructions, which are not supported by Raspberry Pi. That is why you get SIGILL when trying to use it.

I can suggest two workarounds:

  • Use Raspberry Pi with soft-float Linux distribution
  • Use Raspberry Pi 2, which supports ARMv7-A (and thus Thumb-2)
Marat Dukhan
  • 11,993
  • 4
  • 27
  • 41