# Binary CUDA dependency

**URL:** <https://discourse.julialang.org/t/binary-cuda-dependency/6226>\
**Category:** GPU\
**Created:** [October 3, 2017, 7:20pm UTC](https://discourse.julialang.org/t/binary-cuda-dependency/6226 "2017-10-03T19:20:03Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![una-dinosauria](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/una-dinosauria/32/2077_2.png) [@una-dinosauria](https://discourse.julialang.org/u/una-dinosauria)\
**Post date:** [October 3, 2017, 7:20pm UTC](https://discourse.julialang.org/t/binary-cuda-dependency/6226/1 "2017-10-03T19:20:03Z")

</div>

I’m in the process of building a Julia package which uses some custom CUDA kernels that I wrote a few years ago.

I want to provide these CUDA binaries with the package, and have them compiled using [BinDeps.jl](https://github.com/JuliaLang/BinDeps.jl). I’m following a recipe that worked for some of my C++, but somehow BinDeps does not seem to be happy with my CUDA code.

Here is my build.jl file:

```julia
using BinDeps

@BinDeps.setup

deps = [
  cudautils = library_dependency("cudautils")
]

prefix=joinpath(BinDeps.depsdir(cudautils))
linscan_aqdbuilddir = joinpath(BinDeps.depsdir(cudautils),"builds")

# === CUDA code ===
provides(BuildProcess,
    (@build_steps begin
        CreateDirectory(linscan_aqdbuilddir)
        @build_steps begin
            ChangeDirectory(linscan_aqdbuilddir)
            FileRule(joinpath(prefix,"builds","cudautils.ptx"),@build_steps begin
                `nvcc -ptx ../src/cudautils.cu -o cudautils.ptx -arch=compute_35`
            end)
        end
    end),cudautils, os = :Linux, installed_libpath=joinpath(prefix,"builds"))

@BinDeps.install Dict([(:cudautils, :cudautils)])

```

However, when I build I always get this message:

```julia
LoadError: Provider BinDeps.BuildProcess failed to satisfy dependency cudautils

```

It is not clear to me why this process works for C++ code that produces `.so` files, but not for CUDA code that produces `.ptx` files. Any help is appreciated.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [October 3, 2017, 10:11pm UTC](https://discourse.julialang.org/t/binary-cuda-dependency/6226/2 "2017-10-03T22:11:11Z")

</div>

I think BinDeps assumes your library ends with `Libdl.dlext` (which is probably `.so`). But it looks like you can add an alias with the `.ptx` extension:

```julia
library_dependency("cudautils", aliases=["cudautils.ptx"])

```

(assuming that the `.ptx` is still just a shared library. I don’t actually know anything about building CUDA libraries).

---

<div class="post-metadata">

**Author:** ![jekbradbury](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jekbradbury/32/953_2.png) [@jekbradbury](https://discourse.julialang.org/u/jekbradbury)\
**Post date:** [October 3, 2017, 10:31pm UTC](https://discourse.julialang.org/t/binary-cuda-dependency/6226/3 "2017-10-03T22:31:03Z")

</div>

PTX files are not binaries (they’re assembly); nvcc can produce binaries if you don’t pass the ptx flag. How are you planning to link in/make use of the ptx files?

---

<div class="post-metadata">

**Author:** ![una-dinosauria](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/una-dinosauria/32/2077_2.png) [@una-dinosauria](https://discourse.julialang.org/u/una-dinosauria)\
**Post date:** [October 3, 2017, 10:35pm UTC](https://discourse.julialang.org/t/binary-cuda-dependency/6226/4 "2017-10-03T22:35:37Z")

</div>

Correct, they are some sort of cuda mid-level representation.

I am linking to the `.ptx` files using [CUDAdrv.jl](https://github.com/JuliaGPU/CUDAdrv.jl)’s `CuModuleFile` (e.g. something like [this example](https://github.com/JuliaGPU/CUDAdrv.jl/blob/3cbf6a74e48ad5026b606721a573c7ac5b9f9d97/examples/vadd.jl#L9)).

```julia
using CUDAdrv
using Base.Test

using Compat

dev = CuDevice(0)
ctx = CuContext(dev)

md = CuModuleFile(joinpath(@ __DIR__ , "vadd.ptx"))
vadd = CuFunction(md, "kernel_vadd")

dims = (3,4)
a = round.(rand(Float32, dims) * 100)
b = round.(rand(Float32, dims) * 100)

d_a = CuArray(a)
d_b = CuArray(b)
d_c = similar(d_a)

len = prod(dims)
cudacall(vadd, len, 1, Tuple{Ptr{Cfloat},Ptr{Cfloat},Ptr{Cfloat}}, d_a, d_b, d_c)
c = Array(d_c)
@test a+b ≈ c

destroy!(ctx)

```

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [October 3, 2017, 11:07pm UTC](https://discourse.julialang.org/t/binary-cuda-dependency/6226/5 "2017-10-03T23:07:52Z")

</div>

Oh, in that case I’m definitely wrong, so please ignore the noise 🙂

---

<div class="post-metadata">

**Author:** ![jekbradbury](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jekbradbury/32/953_2.png) [@jekbradbury](https://discourse.julialang.org/u/jekbradbury)\
**Post date:** [October 4, 2017, 12:23am UTC](https://discourse.julialang.org/t/binary-cuda-dependency/6226/6 "2017-10-04T00:23:16Z")

</div>

I think that means you might be right, since the problem appears to be simply that BinDeps can’t tell the requirement is satisfied because the extension is unexpected?

---

<div class="post-metadata">

**Author:** ![una-dinosauria](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/una-dinosauria/32/2077_2.png) [@una-dinosauria](https://discourse.julialang.org/u/una-dinosauria)\
**Post date:** [October 4, 2017, 12:30am UTC](https://discourse.julialang.org/t/binary-cuda-dependency/6226/7 "2017-10-04T00:30:59Z")

</div>

That might be correct. I tried changing the extension to `.so` to see if I could “fool” BinDeps, but it didn’t work.

But you are right, at the heart of my confusion is the fact that I cannot seem to find what criteria are necessary for BinDeps to mark a dependency as “satisfied”, and the documentation and error outputs are not super helpful in that sense.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [October 4, 2017, 3:14am UTC](https://discourse.julialang.org/t/binary-cuda-dependency/6226/8 "2017-10-04T03:14:21Z")

</div>

Yeah, I agree that the documentation is sparse. The library is tested here: [https://github.com/JuliaLang/BinDeps.jl/blob/master/src/dependencies.jl#L652](https://github.com/JuliaLang/BinDeps.jl/blob/master/src/dependencies.jl#L652) so it needs to be openable with dlopen()

---

<div class="post-metadata">

**Author:** ![maleadt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maleadt/32/10097_2.png) [@maleadt](https://discourse.julialang.org/u/maleadt)\
**Post date:** [October 4, 2017, 7:06am UTC](https://discourse.julialang.org/t/binary-cuda-dependency/6226/9 "2017-10-04T07:06:02Z")

</div>

Some alternatives: you could use `libnvrtc` to compile CUDA C to PTX, but we don’t have that wrapped yet.  
Or commit compiled PTX code, just make sure to target an old-enough PTX ISA.

Fixing Bindeps seems preferable though. Do note that `nvcc` isn’t necessarily on the PATH though, that’s (among other things) why we have [CUDAapi.jl](https://github.com/JuliaGPU/CUDAapi.jl/blob/29049524084d11335c82c6f13f25d06d962fd041/src/discovery.jl#L91).
