[julia-users] Re: Strange performance problem for array scaling
I can't really help you debug the IR code, but I can at least say I'm seeing a similar thing. It starts to slow down around just after 0.5, and doesn't get back to where it was at 0.5 until 0.87. Can you compare the IR code when two different values are used, to see what's different? When I tried looking at the difference between 0.50 and 0.51, the biggest thing that popped out to me was that the numbers after !dbg were different. Even 0.50001 is a lot slower: julia for eΓ in 0.5:0.1:0.50015 println(eΓ) gc() @time ψs = propagate(P, ψ0, ψs, eΓ) end 0.5 elapsed time: 0.065609581 seconds (16 bytes allocated) 0.50001 elapsed time: 0.875806461 seconds (16 bytes allocated) julia versioninfo() Julia Version 0.3.9 Commit 31efe69 (2015-05-30 11:24 UTC) Platform Info: System: Darwin (x86_64-apple-darwin13.4.0) CPU: Intel(R) Core(TM)2 Duo CPU T8300 @ 2.40GHz WORD_SIZE: 64 BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Penryn) LAPACK: libopenblas LIBM: libopenlibm LLVM: libLLVM-3.3 On Sunday, July 12, 2015 at 6:45:53 PM UTC-5, Yichao Yu wrote: On Sun, Jul 12, 2015 at 7:40 PM, Yichao Yu yyc...@gmail.com javascript: wrote: P.S. Given how strange this problem is for me, I would appreciate if anyone can confirm either this is a real issue or I'm somehow being crazy or stupid. One additional strange property of this issue is that I used to have much costy operations in the (outer) loop (the one that iterate over nsteps with i) like Fourier transformations. However, when the scaling factor is taking the bad value, it slows everything down (i.e. the Fourier transformation is also slower by ~10x). On Sun, Jul 12, 2015 at 7:30 PM, Yichao Yu yyc...@gmail.com javascript: wrote: Hi, I've just seen a very strange (for me) performance difference for exactly the same code on slightly different input with no explicit branches. The code is available here[1]. The most relavant part is the following function. (All other part of the code are for initialization and bench mark). This is a simplified version of my similation that compute the next array column in the array based on the previous one. The strange part is that the performance of this function can differ by 10x depend on the value of the scaling factor (`eΓ`, the only use of which is marked in the code below) even though I don't see any branches that depends on that value in the relavant code. (unless the cpu is 10x less efficient for certain input values) function propagate(P, ψ0, ψs, eΓ) @inbounds for i in 1:P.nele ψs[1, i, 1] = ψ0[1, i] ψs[2, i, 1] = ψ0[2, i] end T12 = im * sin(P.Ω) T11 = cos(P.Ω) @inbounds for i in 2:(P.nstep + 1) for j in 1:P.nele ψ_e = ψs[1, j, i - 1] ψ_g = ψs[2, j, i - 1] * eΓ # Scaling factor ψs[2, j, i] = T11 * ψ_e + T12 * ψ_g ψs[1, j, i] = T11 * ψ_g + T12 * ψ_e end end ψs end The output of the full script is attached and it can be clearly seen that for scaling factor 0.6-0.8, the performance is 5-10 times slower than others. The assembly[2] and llvm[3] code of this function is also in the same repo. I see the same behavior on both 0.3 and 0.4 and with LLVM 3.3 and LLVM 3.6 on two different x86_64 machine (my laptop and a linode VPS) (the only platform I've tried that doesn't show similar behavior is running julia 0.4 on qemu-arm... although the performance between different values also differ by ~30% which is bigger than noise) This also seems to depend on the initial value. Has anyone seen similar problems before? Outputs: 325.821 milliseconds (25383 allocations: 1159 KB) 307.826 milliseconds (4 allocations: 144 bytes) 0.0 19.227 milliseconds (2 allocations: 48 bytes) 0.1 17.291 milliseconds (2 allocations: 48 bytes) 0.2 17.404 milliseconds (2 allocations: 48 bytes) 0.3 19.231 milliseconds (2 allocations: 48 bytes) 0.4 20.278 milliseconds (2 allocations: 48 bytes) 0.5 23.692 milliseconds (2 allocations: 48 bytes) 0.6 328.107 milliseconds (2 allocations: 48 bytes) 0.7 312.425 milliseconds (2 allocations: 48 bytes) 0.8 201.494 milliseconds (2 allocations: 48 bytes) 0.9 16.314 milliseconds (2 allocations: 48 bytes) 1.0 16.264 milliseconds (2 allocations: 48 bytes) [1] https://github.com/yuyichao/explore/blob/e4be0151df33571c1c22f54fe044c929ca821c46/julia/array_prop/array_prop.jl [2] https://github.com/yuyichao/explore/blob/e4be0151df33571c1c22f54fe044c929ca821c46/julia/array_prop/propagate.S [2] https://github.com/yuyichao/explore/blob/e4be0151df33571c1c22f54fe044c929ca821c46/julia/array_prop/propagate.ll
Re: [julia-users] Re: is it possible to return an array (or any other variable) name as a symbol?
Awesome, thanks! On Friday, July 3, 2015 at 10:05:52 PM UTC-5, Yichao Yu wrote: On Fri, Jul 3, 2015 at 11:04 PM, Yichao Yu yyc...@gmail.com javascript: wrote: On Fri, Jul 3, 2015 at 8:37 PM, Kevin Owens kevin@gmail.com javascript: wrote: Yes, you're right, that won't work. I got to thinking about this from this part of the DataFrames documentation: http://dataframesjl.readthedocs.org/en/latest/getting_started.html#the-dataframe-type df = DataFrame(A = 1:4, B = [M, F, F, M]) and this code df = DataFrame() df[:A] = 1:8 df[:B] = [M, F, F, M, F, M, M, F] df If I already had arrays A and B (or an arbitrary number of them) it would be nice to be able to do df = DataFrame(A, B) and then df would have column names :A and :B. And that's exactly what I guessed what you wanted (because I've done sth similar in python sometime ago :P) The right way to do this is to specify the name of the variable because a variable is always bound to a single object while a object can be bound to multiple varialbles. The way I did it in python was using eval. However, in Julia, the eval function is working in the global (module) scope (otherwise the compiler cannot reason anything about local variables) so you cannot use it to get the value of a variable. One way to do this in julia is using macros What you want is basically to write sth like: ``` some magic(A, B) ``` to achieve the effect of ``` DataFrame(A=A, B=B) ``` Well, this is a simple code transformation. (untested code below) Not untested anymore ``` julia macro dataframe(args...) :(DataFrame($([Expr(:kw, arg, arg) for arg in args]...))) end julia macroexpand(:(@dataframe(A, B))) :(DataFrame(A=A,B=B)) julia Meta.show_sexpr(macroexpand(:(@dataframe(A, B (:call, :DataFrame, (:kw, :A, :A), (:kw, :B, :B)) julia Meta.show_sexpr(:(DataFrame(A=A, B=B))) (:call, :DataFrame, (:kw, :A, :A), (:kw, :B, :B)) ``` ``` macro dataframe(args...) :(DataFrame($([Expr(:kw, arg, arg) for arg in args]...))) end ``` If you would like to figure out how to write a macro, the general procedure is to see the input and output AST with `Meta.show_sexpr` (which is better than `show` for this because some symbols are parsed differently in different context) and then write a program to do the transformation. On Friday, July 3, 2015 at 7:24:55 PM UTC-5, Yichao Yu wrote: On Fri, Jul 3, 2015 at 8:21 PM, Kevin Owens kevin@gmail.com wrote: Gah, nevermind: function as_symbol(x) :(print(x)).args[2] end This is almost certainly not what you want unless you just want a function that returns `:x`, in which case, you would be better off to just return that. Can you elaborate on what exactly you would like to do? Depending on what you really want, there are different ways to implement. (using print() so that it works regardless of the type) On Friday, July 3, 2015 at 7:16:38 PM UTC-5, Kevin Owens wrote: Say you have an array x = rand(5) or just any variable y = abc How would I write a function that I would call like foo(x) and would return the symbol :x?
Re: [julia-users] Re: is it possible to return an array (or any other variable) name as a symbol?
Yes, you're right, that won't work. I got to thinking about this from this part of the DataFrames documentation: http://dataframesjl.readthedocs.org/en/latest/getting_started.html#the-dataframe-type df = DataFrame(A = 1:4, B = [M, F, F, M]) and this code df = DataFrame() df[:A] = 1:8 df[:B] = [M, F, F, M, F, M, M, F] df If I already had arrays A and B (or an arbitrary number of them) it would be nice to be able to do df = DataFrame(A, B) and then df would have column names :A and :B. On Friday, July 3, 2015 at 7:24:55 PM UTC-5, Yichao Yu wrote: On Fri, Jul 3, 2015 at 8:21 PM, Kevin Owens kevin@gmail.com javascript: wrote: Gah, nevermind: function as_symbol(x) :(print(x)).args[2] end This is almost certainly not what you want unless you just want a function that returns `:x`, in which case, you would be better off to just return that. Can you elaborate on what exactly you would like to do? Depending on what you really want, there are different ways to implement. (using print() so that it works regardless of the type) On Friday, July 3, 2015 at 7:16:38 PM UTC-5, Kevin Owens wrote: Say you have an array x = rand(5) or just any variable y = abc How would I write a function that I would call like foo(x) and would return the symbol :x?
[julia-users] is it possible to return an array (or any other variable) name as a symbol?
Say you have an array x = rand(5) or just any variable y = abc How would I write a function that I would call like foo(x) and would return the symbol :x?
[julia-users] Re: is it possible to return an array (or any other variable) name as a symbol?
Gah, nevermind: function as_symbol(x) :(print(x)).args[2] end (using print() so that it works regardless of the type) On Friday, July 3, 2015 at 7:16:38 PM UTC-5, Kevin Owens wrote: Say you have an array x = rand(5) or just any variable y = abc How would I write a function that I would call like foo(x) and would return the symbol :x?
[julia-users] is there a better way to partially evaluate an expression?
My question is basically: what is the best way to say here's what I've got, solve it as much as you can so it will be fast when I get the rest? The kind of problem I'm trying to solve is we have this fancy model ... hey, wouldn't it be cool to look at how it changes if we vary X? I'd love to try that, but it takes a day to run each time. Say there's a piece of code that has many inputs and takes a long time to run. Some inputs may be known ahead of time and others only on an ad-hoc basis. Or, given a set of inputs, you may want to vary other arbitrary inputs, but you don't know what values to test yet. Sometimes you have all of the inputs and can run all of the code at once, and sometimes you want to pre-compile/lazy/cache to finish later. Maybe saving the object in HDF5. The documentation show how to use expression interpolation but the drawbacks are that you have to edit code for each combination of inputs that are known, and the code won't run interactively once you've edited it. You could invent a new syntax or do find/replace, but that can be risky. Here's an example of what I'd like to do: versioninfo() const n = 4 ex1 = :(x .* exp(y .* z)) y = rand(n) z = rand(n) data = [:y=y,:z=z] function plug_in!(expr,data) for i in 1:length(expr.args) if isa(expr.args[i],Expr) expr2 = plug_in!(expr.args[i],data) expr.args[i] = try eval(expr.args[i]) catch expr.args[i] end elseif isa(expr.args[i],Symbol) for k in keys(data) if expr.args[i] == k expr.args[i] = data[k] end end else expr.args[i] = try eval(expr.args[i]) catch expr.args[i] end end end return expr end plug_in!(ex1,data) x = rand(n) eval(ex1) It's not completely arbitrary in that there's a question of how to organize the initial ex1 to be able to pre-process as much as possible, but that's a separate issue. So, if y was unknown and x and z were known it would be more optimal to re-factor ex1, but that could be another function called within plug_in!. Also, I know there are needless assignments, and there are probably other things that could be optimized in the function, but I just wanted to give a working example. So, has someone smarter than me already figured this out? Is this already in a package somewhere? Is there a much more elegant way to do it? 99% of my motivation for asking this is to learn more about Julia. Thanks, Kevin
[julia-users] unicode character as type name leads to unexpected behavior
Maybe I just didn't read the documentation well enough, but when I try to use a unicode character as a name for a type it leads to unexpected behavior. I'm using Julia through Emacs and and ESS if that makes any difference. Here's the output from versioninfo() julia versioninfo() Julia Version 0.3.9 Commit 31efe69 (2015-05-30 11:24 UTC) Platform Info: System: Linux (x86_64-unknown-linux-gnu) CPU: Intel(R) Atom(TM) CPU N570 @ 1.66GHz WORD_SIZE: 64 BLAS: libopenblas (DYNAMIC_ARCH NO_AFFINITY Atom) LAPACK: libopenblas LIBM: libm LLVM: libLLVM-3.3 and starting with a clean session in the REPL I see this happening: _ _ _ _(_)_ | A fresh approach to technical computing (_) | (_) (_)| Documentation: http://docs.julialang.org _ _ _| |_ __ _ | Type help() for help. | | | | | | |/ _' | | | | |_| | | | (_| | | Version 0.3.9 (2015-05-30 11:24 UTC) _/ |\__'_|_|_|\__'_| | |__/ | x86_64-unknown-linux-gnu WARNING: Terminal not fully functional julia julia type delta +x +m end julia type δ +x +m end julia tmp1 = delta(.05,Inf) delta(0.05,Inf) julia tmp2 = δ(.05,Inf) (0.05,Inf) julia typeof(tmp1) delta (constructor with 1 method) julia typeof(tmp2) (Float64,Float64) julia abstract Something julia type α : Something +x +m end ERROR: syntax: invalid type signature I would have expected that using a unicode character would have the same behavior. If I put an inner constructer method in the definition of δ I get an error julia type δ +x +m +δ(x,m) = new(x,m) end ERROR: new not defined and as the error with α shows, you can't make it a subtype.
[julia-users] Re: A few notes and questions on building 0.3.8-pre on ARM or Jetson-tk1
No, it gets an error because there is a build option with gcc and g++ of -m32 (32 being the word length). Now that I see this, I remember this being an issue when I installed 0.4* about a month ago. (Sorry if this would be more appropriate in the julia-dev list.) Here's the output from running testall: $ make testall gcc: error: unrecognized command line option ‘-m32’ C Compiler (gcc -m32) is something wrong. 1 at ./c_check line 144. make[3]: *** [config.h] Error 1 Makefile.system:148: Makefile.conf: No such file or directory Makefile.system:860: Makefile.: No such file or directory make[3]: *** No rule to make target `Makefile.'. Stop. *** Clean the OpenBLAS build with 'make -C deps clean-openblas'. Rebuild with 'make OPENBLAS_USE_THREAD=0 if OpenBLAS had trouble linking libpthread.so, and with 'make OPENBLAS_TARGET_ARCH=NEHALEM' if there were errors building SandyBridge support. Both these options can also be used simultaneously. *** make[2]: *** [openblas-v0.2.13/libopenblas.so] Error 1 make[1]: *** [julia-release] Error 2 make: *** [release] Error 2 Which makes me think I have a different version of gcc or g++. I tried to figure out what version I have: [14:14:07 tegra-ubuntu] ~/julia3/julia $ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/4.8/lto-wrapper Target: arm-linux-gnueabihf Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.8.2-19ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-armhf/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-armhf --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-armhf --with-arch-directory=arm --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --enable-multilib --disable-sjlj-exceptions --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb --disable-werror --enable-checking=release --build=arm-linux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf Thread model: posix gcc version 4.8.2 (Ubuntu/Linaro 4.8.2-19ubuntu1) [14:14:09 tegra-ubuntu] ~/julia3/julia $ g++ -v Using built-in specs. COLLECT_GCC=g++ COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-linux-gnueabihf/4.8/lto-wrapper Target: arm-linux-gnueabihf Configured with: ../src/configure -v --with-pkgversion='Ubuntu/Linaro 4.8.2-19ubuntu1' --with-bugurl=file:///usr/share/doc/gcc-4.8/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.8 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.8 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-libmudflap --disable-libitm --disable-libquadmath --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.8-armhf/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.8-armhf --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.8-armhf --with-arch-directory=arm --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --enable-multilib --disable-sjlj-exceptions --with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb --disable-werror --enable-checking=release --build=arm-linux-gnueabihf --host=arm-linux-gnueabihf --target=arm-linux-gnueabihf Thread model: posix gcc version 4.8.2 (Ubuntu/Linaro 4.8.2-19ubuntu1) The README file in the master branch says gcc =4.7 is required. On Sunday, March 29, 2015 at 12:18:13 PM UTC-5, Viral Shah wrote: 0.3 does not have the ARM related patches in Julia. I doubt it will work on 0.3 even if you get it compiled. Even on 0.4, we have some ways to pass all tests before trying to use packages. Do you see success for `make testall`? -viral On Sunday, March 29, 2015 at 7:11:37 PM UTC+2, Kevin Owens wrote: I already have 0.4-something installed on my Jetson-tk1, but with DataFrames not working for that version, I decided to install the stable build. Here are some notes for how to do it: 1. ARM.inc doesn't exist in 0.3 2. Make.inc needs to be edited around line 440 and this needs
[julia-users] Re: constructor with named arguments
Is there any way to do it without setting default values? Or, is there a type you can give to default values so that if you try to use them it will throw an error? I'm thinking like with R and the NA value. Do keyword arguments have to have default values? It's not clear in the 0.3 documentation on functions that it's the case. On Sunday, November 2, 2014 12:47:26 PM UTC-6, Jack Minardi wrote: You need to give default values for each keyword argument: type Foo bar baz Foo(;bar=10, baz=1) = new(bar, baz) end On Sunday, November 2, 2014 1:05:37 PM UTC-5, Kevin Owens wrote: I'm using Julia 0.3 something. If I make a composite type with many fields I may forget the order, but remember their names. I'd like to use a constructor where I can use name the arguments. Say I have the composite type type Foo bar baz end How can I make a constructor that lets me do this myfoo = Foo(baz=1, bar=2) I expected this would work type Foo bar baz Foo(;bar, baz) = new(bar, baz) end But when I run it I get ErrorException(syntax: invalid keyword argument bar) I also tried julia function Foo(;bar, baz) Foo(bar, baz) end ErrorException(syntax: invalid keyword argument bar)