Compiling Scavenger From Source to add OpenCL Support

Now that I have Scavenger up and running on the ODROID-XU4, it’s time to do a little optimization to see how much I can really get out of it.

For this I’m going to use 1.6.0 from the releases page. Download Source code(tar.gz). The development team has some really great information on all of the configuration options on the github wiki, so make sure to check that out if you’re going to try this on your own device.

Installing Rust

First and foremost, I needed to make sure I had Rust installed in order to compile. In the terminal run the command:

rustc --version

This shows that I already had Rust installed and it was version 1.28.0. I also wanted to make sure I had the latest version, so the next command would be:

rustup update
rustup: command not found

Uh-oh! What’s going on here?

Apparently the first time I installed Rust, I didn’t follow their recommended procedure of using rustup. To FIX that problem, first I had to uninstall the current version of Rust, so that I could re-install the recommended way. Information on installing & uninstalling Rust can be found here.

My First Attempt

To install via rustup:

curl -sSf | sh
rustc already installed

Another problem: it looks like you have an existing installation of Rust. So I uninstalled the previous version.

su root

And again:

curl -sSf | sh
Rustup installation

Choose Proceed with installation (default)

This worked as intended and installed all of the files needed.

Rustup success

Rustup success

At the end of the installation it tells you that you can immediately register the command to your PATH by entering the following:

source $HOME/.cargo/env

I did NOT do that, but closed and re-opened the terminal instead. After that, to make sure it was all installed correctly, type:

rustc --version

This gave me rustc command not found! It must not have added to my PATH, right? I manually added it in by opening up the /home/odroid/.bashrc file and added export PATH=$HOME/.cargo/bin:$PATH to the end of the file.

source ~/.bashrc

The above command makes the change in .bashrc immediately available. So now, I tried again.. and again rustc command not found! What’s going on here?? Next I checked out the /.cargo/ folder and lo and behold.. no /bin folder. That’s not right.

The Problem

As it turns out, back when I uninstalled the previous version, I swapped over to the root user and installed as root. That made Rust unavailable to my odroid user. OOPS. If YOU do this, uninstall that version and try again.

sudo /root/.cargo/bin/rustup self uninstall

The Correct Way

As the odroid user:

cd /home/odroid
curl -sSf | sh
source $HOME/.cargo/env

Now check that it’s installed correctly.

rustc --version

I now show that Rust is installed again, the same as before.. but now it’s installed for the correct user!

Compiling From Source

Now I copied the 1.6.0 source over to a “scavenger-src” folder and started the compiler. (I did this via Ubuntu to avoid command line stuff)

cd /home/odroid/scavenger-src
cargo build --release --features=opencl,neon,simd
Build twice error

That’s apparently not correct, since it gives an error that the build function can’t be used twice. Looking at the config file, it looks like you can’t have neon and simd as options at the same time, so I removed simd.

cargo build --release --features=opencl,neon

That went through 192 of 193 compilations before it finally failed.

Feature not available

#![feature] may not be used on the stable release channel

This is because the stdsimd library is not labeled as “stable” and so it can’t be used in the “stable” version of Rust. The fix? Use the nightly release of Rust. See this link for more information.

rustup install nightly
rustup default nightly

Make sure it’s working correctly:

rustc --version
Installing rust nightly

Shows: rustc 1.32.0-nightly. All set!

Scavenger compiled

Compiling again with cargo build –release –features=opencl,neon finally made it 100% through the build. I now have a working NEON & OpenCL Scavenger!! Right?? Wrong :(.


Unfortunately, it looks like OpenCL is indeed compiled in, but there’s an error

error executing function clSetKernelArg("find_min") - status code CL_INVALID_ARG_SIZE


error: panicked at 'attempt to multiply with overflow', src/

This is above my pay grade, but I hopped on Discord to see if anyone else had these errors and/or a solution. Lucky for me JohnnyDeluxe was on and he has his own ODROID to test with. He started taking a look at the problem right away. Nice!

In the Meantime

My Ubuntu version was a bit behind, so I decided to upgrade to Ubuntu 18.04. Hardkernel has an image for it on their site but I decided to do it through the Software Updater under System > Administration > Software Updater. This took a while to complete, and actually failed according to the updater, but restarting showed that I was indeed running 18.04 now, so I’m calling that part a success!

I tried Scavenger again after this and it still gave me that same error. Wah wah waaaah.

The Next Morning

Johnny was able to find the problem!! It turns out that one of the variables needed to be cast to type u64. I downloaded his new version 1.6.4 and tried it out. Compiling with the following:

cargo build --release --features=opencl,neon

YES! It’s working! ** cue heavenly noise

Scavenger working

I set my config.yaml settings:

gpu_platform: 0
gpu_device: 0
gpu_worker_thread_count: 4
gpu_nonces_per_cache: 262144
gpu_mem_mapping: false

The ODROID-XU4 actually has a Mali-T628 MP6 chip, which shows as two separate devices. The first with 4 cores and the second has 2 cores. Since I’m using device 0, I’ve entered 4 for the gpu_worker_thread_count.

And it’s off to the races!

Final Tests – (For Now)

232MiB/s I/O
196MiB/s CPU (NEON)
299MiB/s XPU (NEON + OpenCL)

4 CPU w/ NEON – I initially left this at 4 (the default) instead of adjusting to my system.. oops!
Average 51s rounds @ 112MiB/s (over 10 rounds)

8 CPU core w/ NEON
Average 34s rounds @ 164MiB/s (over 10 rounds)

8 CPU core w/ NEON & OpenCL
Average 31s rounds @ 182MiB/s

These tests show that with OpenCL, it’s now the I/O that is the slower of the two and reading is more of a problem than computing. OpenCL seems to add a decent boost and knocks a few more seconds off of total round time. Now it will be about optimizing the settings to try and get closer to the 232MiB/s bottleneck. I may be able to do that by boosting the hdd_reader_thread_count.. but that’ll have to wait. My kids are in full spaz-out mode so it’s probably time to give them some attention!!

Until next time!


Leave a Reply

Your email address will not be published. Required fields are marked *