Show HN: Vector - A High-Level Programming Language for GPU Computing
zhehaomao.com
zhehaomao.com
Please do not underestimate the critical nature and endless annoyance associated with naming things after common concepts (or worse yet, single characters)
The suffix is just meant to be unambiguous. Those familiar with the target language will understand what language the library is written for.
But yeah, we aren't particularly concerned about the name, since we don't really plan on continuing development.
This is high level — http://hackage.haskell.org/package/accelerate
You think C is bad? Those are far worse.
This is at least a great step in the right direction. It's not "low level" as you describe just because it's C.
I read a lot of GPGPU papers at the university, and I could never understand the older ones, that described algorithms by mapping everything to graphics elements, and computed the solutions as a side-effect of rendering something.
Next to that, undestanding an algorithm implemented in CUDA is a breeze.
CUDA and OpenCL demand a depth of understanding of both C, and how your code is executed on many core processors. but i wouldn't call either of them terrible.
i would however, very much like to see a widespread higher level API for doing compute on GPUs, if only to encourage people to understand the lower level details.
The reason it is that it operates on concepts that are not abstract but are of register machines. A high completely abstracts underlying architecture so the code can be executed in any possible environment by means of translation, be it a $10MM Cray or a cellular automaton or a mechanical computer. In essence, a high level language provides an abstract notation for computation.
C, however, is not abstract at all. Variables? How those will map to a dataflow computation? Pointers? Would not work beyond register CPUs (e.g. it is very cumbersome to translate C programs to Javascript as a result and usually leads to a memory array emulation). Fixed-width types? Volatile pointers? Returns from the middle of a procedure? Gotos? Come on, how those are even going to run on a non-conventional architecture?
C also does not completely define the language semantics leaving certain operations implementation-specific or undefined. It also (before C11) didn't define any memory model, thus making it impossible to even describe an algorithm that depends on specific properties of memory accesses in a way that will be portable across different register machines. C algorithms are close to impossible to translate to be run on memory-less computation devices as the whole concept of C is based around having local memory and a stack space with certain properties (unless one wants to emulate a register machine, see JavaScript remark above).
In certain areas it lead to some ugly solutions like Cuda where the language looks like C but semantics is completely different and GPUs are the closest thing to he original C target as you can get.
The mapping between C and assembly is very nontrivial, and is definitely not one-to-one.
at the time of the creation, the general consensus was that C was too high level, that it abstracted away the actual workings of the code.
we've been introduced to high level languages that have made us re-evaluate what it means to be low or high level. but make no mistake, C is.. at least medium-level..!
The thing that struck me most about vector was the radically different for loops (compared to C). I'm assuming you're purposefully crippling them to make parallelisation easier? Or is there another reason?
EDIT: One other thing - the website fails to scroll nicely on a mac (in chrome). I had to manually use the scroll bars instead of being able to 2 finger swipe...
Also, I can't believe I forgot to mention this in the post, but both for and pfor can sweep multiple iterators, so
for (i in 0:10, j in 0:5) {
}
Is equivalent to for (i = 0; i < 10; i++) {
for (j = 0; j < 5; j++) {
}
}* http://notonlyluck.com/2013/07/23/reasons-to-join-a-startup-...
* http://notonlyluck.com/2013/07/24/more-thoughts-on-reasons-t...
for(i=0,j=0;i<10;j=(j+1)%5, j==0?i++:){
}
Not that you ever would of course, but it does demonstrate the power of for loops in C.[1] https://github.com/pflanze/mandelbrot.git
(BTW, also in the PDF, page 35, you write "computes the number of iterations til convergence for that point", that should be "divergence", right?)
PS. I'm quite impressed by what you achieved in the given time frame.
$ vagrant up
/home/chrishaskell/src/vector/Vagrantfile:7:in `<top (required)>': undefined method `configure' for Vagrant:Module (NoMethodError)
from /usr/lib/ruby/vendor_ruby/vagrant/config/loader.rb:115:in `load'
from /usr/lib/ruby/vendor_ruby/vagrant/config/loader.rb:115:in `block in procs_for_source'
from /usr/lib/ruby/vendor_ruby/vagrant/config.rb:41:in `block in capture_configures'
from <internal:prelude>:10:in `synchronize'
from /usr/lib/ruby/vendor_ruby/vagrant/config.rb:36:in `capture_configures'
from /usr/lib/ruby/vendor_ruby/vagrant/config/loader.rb:114:in `procs_for_source'
from /usr/lib/ruby/vendor_ruby/vagrant/config/loader.rb:51:in `block in set'
from /usr/lib/ruby/vendor_ruby/vagrant/config/loader.rb:45:in `each'
from /usr/lib/ruby/vendor_ruby/vagrant/config/loader.rb:45:in `set'
from /usr/lib/ruby/vendor_ruby/vagrant/environment.rb:377:in `block in load_config!'
from /usr/lib/ruby/vendor_ruby/vagrant/environment.rb:392:in `call'
from /usr/lib/ruby/vendor_ruby/vagrant/environment.rb:392:in `load_config!'
from /usr/lib/ruby/vendor_ruby/vagrant/environment.rb:327:in `load!'
from /usr/bin/vagrant:40:in `<main>'
If you post the generated C code then I'll give the timings and try to compare what it's doing differently.The CPU I'm using (Intel(R) Core(TM)2 Duo CPU T9300 @ 2.50GHz) was released in July 2006 [1]. The GPU you're using was released on 15 June 2007 [2]. My CPU code calculates the 1246x998 pixel image of the zoomed out view (real=-2..2, imag=-1.6..1.6, maxdepth=200) in 0.07 seconds, if your GPU code does about the same in 0.61 sec, then that's about 8 times slower than the slightly older CPU can do with hand optimized C code. That wouldn't be such a pretty result yet :)
[1] http://en.wikipedia.org/wiki/Intel_Core_2 [2] http://en.wikipedia.org/wiki/GeForce_8_Series
https://github.com/vectorlang/vector/blob/master/rtlib/vecto...
Basically, the VectorArray class contains both the host array pointer and the device array pointer. There are also two boolean flags, h_dirty and d_dirty. When you modify array elements on the host, h_dirty is set to one. Then, when you run a kernel, the data is copied to the device if h_dirty is set, h_dirty is cleared, and d_dirty is set. When you try to read an array element again on the CPU, the data is copied from device to host if d_dirty is set, and d_dirty is then cleared.
* Automatic memory management - Been in ArrayFire since 2008
* Their pfor statement - See ArrayFire's GFOR, http://www.accelereyes.com/arrayfire/c/page_gfor.htm
* High-order functions - Been in ArrayFire since 2009
It's always interesting to watch other people reinvent the wheel. It takes a lot of talent though. If the people behind this want an awesome opportunity to join with our team (where we live this stuff every day and have developed a great culture and customer focus), give me a holler. Find me at http://notonlyluck.com