Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@
/Manifest.toml
/docs/Manifest.toml
/docs/build/
/language_wrappers/Manifest.toml
/language_wrappers/bindinginfo_libNMFMerge.log
1 change: 0 additions & 1 deletion .vscode/settings.json

This file was deleted.

55 changes: 55 additions & 0 deletions language_wrappers/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# This Makefile template requires the following variables to be set
# in the environment or on the command-line:
# JULIA: path to julia[.exe] executable
# BIN: binary build directory

ifndef JULIA
$(error "Please pass JULIA=[path of target julia binary], or set as environment variable!")
endif
ifndef BIN
$(error "Please pass BIN=[path of build directory], or set as environment variable!")
endif

#=============================================================================
# location of test source
SRCDIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST))))
PKGDIR := $(abspath $(dir $(SRCDIR)))
JULIAHOME := $(abspath $(JULIA)/../..)
# BUILDSCRIPT := $(BIN)/../share/julia/juliac-buildscript.jl
# include $(JULIAHOME)/Make.inc

# FIXME
SHLIB_EXT := so

# get the executable suffix, if any
EXE := $(suffix $(abspath $(JULIA)))

# get compiler and linker flags. (see: `contrib/julia-config.jl`)
JULIA_CONFIG := $(JULIA) -e 'include(joinpath(Sys.BINDIR, Base.DATAROOTDIR, "julia", "julia-config.jl"))' --
JULIA_LIBDIR := $(shell $(JULIA) -e 'println(joinpath(Sys.BINDIR, "..", "lib"))' --)
CPPFLAGS_ADD :=
CFLAGS_ADD = $(shell $(JULIA_CONFIG) --cflags)
LDFLAGS_ADD = -lm $(shell $(JULIA_CONFIG) --ldflags --ldlibs) -ljulia-internal

# get the JuliaC build script
JULIAC_BUILDSCRIPT := $(shell $(JULIA) -e 'print(joinpath(Sys.BINDIR, Base.DATAROOTDIR, "julia", "juliac", "juliac-buildscript.jl"))')

#=============================================================================

release: libNMFMerge-o.a

$(BIN)/libNMFMerge-o.a: $(PKGDIR)/language_wrappers/lib.jl $(JULIAC_BUILDSCRIPT)
$(JULIA) -t 1 -J $(JULIA_LIBDIR)/julia/sys.$(SHLIB_EXT) --startup-file=no --history-file=no --project=$(PKGDIR)/language_wrappers/ --output-o $@ --output-incremental=no --strip-ir --strip-metadata --experimental --trim $(JULIAC_BUILDSCRIPT) $< --output-lib true $(BIN)/bindinginfo_libNMFMerge.log

# check: $(BIN)/libNMFMerge$(EXE)
# $(JULIA) --depwarn=error $(SRCDIR)/trimming.jl $<

clean:
-rm -f $(BIN)/libNMFMerge-o.a $(BIN)/bindinginfo_libNMFMerge.log

.PHONY: release clean

# Makefile debugging trick:
# call print-VARIABLE to see the runtime value of any variable
print-%:
@echo '$*=$($*)'
5 changes: 5 additions & 0 deletions language_wrappers/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[deps]
NMFMerge = "9cc52eda-dfaf-4e21-aae3-9f26bed153a3"

[sources]
NMFMerge = {path = ".."}
29 changes: 29 additions & 0 deletions language_wrappers/lib.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module NMFMergeLib

using NMFMerge

struct ReturnValue
niters::Int32
converged::Bool
objvalue::Float64
end

struct CMatrix{T} <: AbstractMatrix{T}
data::Ptr{T}
rows::Int32
cols::Int32
end

Base.@ccallable function nmfmerge_inplace(Wout::CMatrix{Float64}, Hout::CMatrix{Float64}, X::CMatrix{Float64}, ncomponents::Int32, tol::Float64, maxiter::Int32)::ReturnValue
Wout.rows == X.rows || throw(ArgumentError("Wout and X must have the same number of rows"))
Hout.cols == X.cols || throw(ArgumentError("Hout and X must have the same number of columns"))
W, H, X = unsafe_wrap(Array, Wout.data, (Wout.rows, Wout.cols)),
unsafe_wrap(Array, Hout.data, (Hout.rows, Hout.cols)),
unsafe_wrap(Array, X.data, (X.rows, X.cols))
result = nmfmerge(X, ncomponents; tol_final=tol, maxiter)
W .= result.W
H .= result.H
return ReturnValue(result.niters, result.converged, result.objvalue)
end

end