IRC channel logs
2025-07-08.log
back to list of logs
<omentic>hi all -- embarassingly, i'm kind of getting really owned by the module system right now. how do i use a module from another file in the same directory as my new module? <rlb>Hmm, should just need (use-modules (some module)) as long as the parent directory of some is in the load path. <omentic>can you elaborate on that "as long as"? <omentic>i'm running "guile myfile.scm" to run the program. does that not add the current directory to the load path? <rlb>It'll need to be in the %load-path, often set via GUILE_LOAD_PATH, if it's not in one of the "standard" directories. <rlb>No -- and you probably wouldn't want it to by default since that's the "." in path style of security risk. <rlb>"." in PATH (I mean, shell-wise) <rlb> GUILE_LOAD_PATH="$(pwd)" guile ... <rlb>might work for you for now <rlb>There's also a related -L if you'd prefer an argument. <rlb>guile -L "$(pwd)" I think <rlb>I'm not sure -- I've often used GUILE_LOAD_PATH, but that's mostly from scripts, and it's possible they might take affect at slightly different times, but I suspect either's likely fine in your case. <rlb>(and easy to change later if you want to) <rlb>You can also mess with %load-path from your scheme code. <omentic>ok, interesting. do ppl use some standard build tool when they have larger projects? <rlb>I don't know, in general -- I think one common option is just to rely on guix, and of course for people already involved with guix, but I don't have a lot of experience there myself yet. <omentic>also -- GUILE_LOAD_PATH does work, but it only seems to work when i have (define-module (filename)) in the file i want to import. can i have anything other than (filename) there? <omentic>hmm, i'll poke around and look for how to use that, thx <rlb>You'll want it to match the location of the module. <rlb>i.e. (define-module (foo bar) ...) for a module in foo/bar.scm in the load path. <omentic>ah, i see. ok, maybe i should do -L .. then to do a bit of namespacing <rlb>Also these days personally recommend always #:select(ing) your imports instead of importing everything via "no #:select". <rlb>It's a bit more work up front, and more "noise", but I find it very nice to make it totally obvious where all the bindings came from, and also to not be susceptible to collisions if the module adds new exports later. <ArneBab>wingo: nice! Thank you for the update! <omentic>i'm curious, any reason guile has define-syntax-parameter and syntax-parametrize but no syntax-parameter-value? <ttz>Is syntax-case suitable to produce a specialized inner-product procedure on one of its two input vectors, with a fully unrolled loop? <ttz>I have tried a few things but macros are still hard for me... <dodoyada>probably, yes, but a concrete example would go a long way <ttz>I would like a macro (specialize-inner-product v) to return a procedure (lambda (v*) (+ (* 4 (vector-ref v* 0)) (* 1 (vector-ref v* 1)) ...)) given v is (vector 4 1 ...). <ttz>with an extra check on v*'s length (unless (= 34 (vector-length v*)) (error "unequal argument lengths")) given (vector-length v) is 34. <ttz>The value of v would only be available at run-time. <dodoyada>I'm not familiar with inner-product but this looks very map/reduce-y to me. Does it need to be a macro? <ieure>Yeah, this is also what I'm wondering, I'd probably write a function that returns a lambda that uses reduce or maybe a transducer to do the work. <ttz>I need it to be specialized on one of the two arguments, with loop fully unrolled <ieure>Doesn't feel like a situation where a macro adds anything. <mwette>ttz: for it to be a macro your expanded vector would have to be a literal <ttz>Is there a way to unroll a loop which depth is only available at run-time ? <ttz>for information, I have already implemented an inner-product procedure that way: (define (inner-product v w) (vector-fold (λ (a x y) (+ a (* x y))) 0 v w)) <identity>is there really a need for the unrolling though? <ttz>that's the hot-spot of my program, and I really would like to make some performance improvement <ttz>unrolling would remove length check at each iteration <ttz>and specializing the vector reference on the known argument <ttz>otherwise I am rather pleased by Guile's performance, this inner-product procedure runs in 50us for vectors of dimensions 384 on my PC :) <mwette>oops maybe not; it does not work ; need to fix <ttz>mmh you think simply expressing it in a currying fashion allows the optimizer to perform the work? <mwette>this one doesn't look like it's generating fast code <mwette>you could generate a sexp for the code and feed that to compile, I guess <ttz>no it didn't, it's twice as slow as my original procedure :/ <mwette>I assume you don't know the one vector when you call the specializer. That is, you don't have a literal vector. Is that right? <ttz>yes, that's why I wanted to use syntax-case: to generate sexps <ttz>I have bunch of IP to compute for different vectors, and many of them with the same first argument <ttz>but that argument is determined at run-time <ttz>So to generate sexps, should I simply do it "by hand"? <dthompson>I have done hand-written matrix multiplication for small 4x4 and 3x3 transformation matrices, but for larger things I'd use a syntax-case macro to generate the code <mwette>But he does not know the coef's at compile time. <mwette>I was approching to generate '(+ (* 1 y[0]) (* 2 y[1]) ...) <ttz>So now I can generate a procedure that takes the second vector and computes the IP withtout loop <ttz>cool, similar code :) <ttz>so can I call compile ? <ttz>which module do I need to import ? <mwette>`compile' is included in booted guile; no use-module needed <mwette>`compile' takes args for things like optimization level etc. <mwette>I wonder if multiple binary + would be faster than + w/ > 2 args <mwette>i.e., (+ (* 1 y[0]) (+ (* 2 y[1]) (+ 3 y[2]))) <ttz>Good idea, it may seem like it from a quick timing <ttz>but the dominant factor here is * <ttz>I don't seem to have compile available inside my module... <ttz><stdin>:70:5: warning: possibly unbound variable `compile' <mwette>hmm. it's in mine; maybe (use-module (system base compile)) <mwette>Also, if you're using floats maybe (unless (inexact? (vector-ref y 0)) (error "optimized for floats")) as the first line will help; <= to give compiler a hint that this is float only <ttz>thanks, I will try adding this hint <ttz>after some tries, it seems that the manually unrolled procedure is faster for small dimensions (e.g. 13) but slower for big ones (e.g. 234) <mwette>OK. Then I can't guess what the growth may be from. <ttz>The number of instructions to perform in case of a high dimension is huge (~6000). Maybe the overhead of loading them to memory start to matter at that scale? <ttz>I think I remember Knuth talking about something like that, but I cannot find it back... <daviid>for larger matrix multilication, providing you agree to only work with float32, you might consider using guile-cv, or aiscm <ttz>yes something like that would be my guess <ttz>thanks daviid I will have a look at it