Materialist ramble, and not the philosophical kind.
I like being minimalist. I’m not one of those count-everything-you-own types, inventorying every fork and spoon and plate I own, but by and large the only things of note that I [want to] own which I don’t carry around in my backpack all day are my bed and a beanbag. I really need to sell the four computers I haven’t turned on in months. My old desktop has been eclipsed in everything but gpu by my laptop – I don’t really game anymore, and amazon can give me cuda when I need it. And my old 6 drive zfs raidz2 array’s contents now fit on a single external hooked up to my diehard netbook server, with the important stuff backed up elsewhere. I suppose I’ll always have a desk with a keyboard, mouse, giant monitor, and godly headphone rig, but it’s now just external accessories for my laptop. I’ve said it before, but being able to sit down practically anywhere – in a bar, on a beach, in the park – with my full workstation and broadband is incredibly awesome. My dad said it, but he was into it before laptops were powerful enough for me. My brother said it, but that was in Jacksonville where pretty much the only interesting place to hang out is exactly one hookah lounge. Here and now however I’ve finally seen that light, and it’s bright.
A backpack with the most badass laptop available, a trusty android tablet, a rockbox ipod 4g, the most badass earbuds and usb dac/amp available, the most badass android phone available, and, like, a mouse and stuff. Really all I want. I know many people this age for countless generations have gone through this ‘phase’, but times really are different. With the laptop alone I have every book movie song and line of code ever or yet written. The collective knowledge of mankind and all that. I have unfettered access to as much computing resources as I need via the proverbial cloud. I have games, should I want them. This has never, in the history of the known universe, happened before. Used to be to get information you had to ask people in person, or write them letters, or consult books of your own or of a library’s, and to do research you had to be at a university or lab and have all kinds of crazy, heavy, expensive equipment at your fingertips. I don’t expect people used to the way things have always been, or as my inner singularist would phrase it people used to linear growth, to understand this, but physical objects and even physical location are now just conveniences, not requirements. What an age.
As much as I’ve loved my 240sx I really can’t wait to sell it. It’s been a brilliant machine and has served me unspeakably well, but I think that phase of my life has ended. The only [US] cities I can see myself living in now are SF and NYC which have real public transpo, and Boulder, and it wouldn’t fare well at all in the snow.
I suppose I have exactly three tiers of material want:
1) My attainable, realistic backpack.
2) A goddam decked out camper van. I’ve always dreamt of taking a year and hitting up every good festival in the country, and camping out in the middle of nowhere with my whole house, and [secondarily] seeing the many interesting cities on the continent. I’m almost embarrassed to admit how much I’ve thought this out. This is mid-term attainable, but I’m not sure I’ll come into that kind of cash before I’m too old to enjoy it. Meh, it’s a distant blip on the radar.
3) A goddam airship. Hey, everyone needs goals.
Seeing only those the theme seems to be more of nomadism than of minimalism, but the second two are largely pipe dreams, rewards for something I’ve yet to accomplish. By far most importantly I’m a being of information, and a friggin laptop and broadband is all I need for complete self-realization. Granted my projects folder is a graveyard of hundreds of cloned git repos and pdfs and stuff, but speaking purely physically.
Getting a job in the city. Not just ‘some job’, like I didn’t just move to ‘some city’. A perfect fit, all boxes checked. I’m still in that phase of initial disbelief, really – I’ll believe it when I start there. Literally dream come true. But this means I don’t need to drive, and I can move to the mecca of mission, a hazy stagger from ritual, the park, noisebridge, and sweet, sweet music venues. Block parties and community, not a sterile commercial barrens (ALLIES IN XR). A cheaper, smaller, simpler apartment away from the highway and even more overpriced boutique soma. I don’t need or want all this space – all I need is a room. To fit my bed and beanbag. I see people constructing, lusting for, and living in such giant homes elsewhere and I honsetly wonder what they need all that stuff and space for. I can see the appeal of having land of your own, trees and lakes and wildlife, a homestead, but it’s not me. And, of course, I’m just some dude, not a family. Different strokes I guess, and this is mine. Giggity.
It’s somewhat chicken and egg: do I love deletion and simplification because I am at my core a coder, a constructor, a purity seeker, an unapologetic but not soulless reductionist, or vice versa? A ponderance, but by no means an evaluatory crisis. Almost like asking which side of an arch was built first.
page break
Man, actors and state machines. I had written off the ‘master’ part of my project as small earlier, but now it needs to exist, and it’s become less and less so. I guess that’s part of the game – when you try to keep each component simple the shifted duties have to wind up somewhere. Mister master has wound up getting stuck with all the managerial arbitration I don’t want to pollute the machine gun sim nodes or fanciful mdl nodes with. It’s obviously for the best, now I have no ugly distributed spider web of machinery living on different machines, it’s all under one monolithic, GIL’d, garbage collected roof, all queryable and trackable without worrying about the word network, but damn sure it’s still no hello world.
I’ve been trying to do it erlang style, and I think I’ve settled on at least a vague silhouette of what I want it to be. The best actor offerings I know of are erlang and akka, and potentially mozart/oz, but I’m going to be keeping it all python and si-pi-pi. Pythons actor libs seem to be relatively lacking, all going off on poorly fitting directions or having not been updated since 2004 (candygram). Thankfully I’ve found pykka. gevent driven. I’m pretty set on using twisted to handle the ugly socket bits on the py side, and delightfully it can be run with a gevent reactor – hooray harmony. So I’m currently mulling over the interplay of actors, machines, and twisted handlers. Sim and mdl nodes are to remain as stupid as possible – sync and async command handlers with as little state as can be. I don’t want them being machines. They handle commands which can be issued, queried, and cancelled. Concessions must be made, for example the sim nodes must loop until they’re told to stop to avoid comically inefficent master round trips and mass joins, but for the most part they wear helmets. So as for the master, where everything lives: are all actors machines? Are all connections actors? Are all commands messages? Are all messages transitions? Are all simple, linear sequences of transitions their own machines? And vice versa to each of these. What’s in my head at the moment is an all powerful sim machine created on connection which creates and kills child machines as necessary, where each machine is a pykka actor. On the sim side commands need to have ID’s to be queryable and cancellable, but I don’t think all commands require an actor or a machine. I don’t have an example of this at the moment, however. I thought I did. It really looks heavyweight, but none of this happens per frame – master control commands are all rare, catastrophic events like loading cells and spinning up nodes and whatnot. However it may turn out it’s an interesting thought experiment. I’m consciously trying to force myself to be somewhat large about this side, to contrast my obsession with bits on the sim. Don’t be afraid of allocation, let’s see what happens.
On the bits front though I’ve been trying to implement an absolutely minimal lockless stack for the sim page allocator (free list). I think I’m going to be using TBB again – the atomics are (ALMOST) bulletproof, I’d need to write a threadpool / workqueue thing to handle async commands anyway, and wow is its TLS and thread local mem allocator gorgeous. As for the ALMOST: hey intel how about lock cmpxchg16b? TBB simply can’t currently emit that. Apple’s assembler certainly can’t (it won’t even do avx, cause not all macs have avx and mother apple won’t let you compile things that might not run on everymac). I tried asm(“.byte 0xFE 0xAC”) or whatever it is but it didn’t work and I gave up. I don’t need it, I was just curious really.
Oh yeah, lockless stack. concurrent_queue (this is just a freelist so it doesn’t matter if it’s a queue or stack and there’s no tbb::conc_stack) is hilariously heavyweight for something as trivial but inner-loopy as page allocation here. It yields. Even tbb::spin_mutex yields. You can probably configure it to not, but it’s still too much. Furthermore to use it (conc_queue) for a page freelist they’d necessarily heap alloc nodes because TBB doesn’t support intrusive datastructures. Weeeeak. So I’ve banned TBB, with the exception of atomics, from the holy inner loop, and thus need to write the six lines of code needed for a lockless intrusive stack. Using a ‘hands off’ sentinel of -1 it (pop) works out to this (noinlined):
00000001000016e0 <__Z9test6_popR11AtomicList6>:
1000016e0: push rbp
1000016e1: mov rbp,rsp
1000016e4: nop WORD PTR [rax+rax*1+0x0]
1000016ea: nop WORD PTR [rax+rax*1+0x0]
1000016f0: mov rax,0xffffffffffffffff
1000016f7: lock xchg QWORD PTR [rdi],rax
1000016fb: cmp rax,0xffffffffffffffff
1000016ff: je 1000016f0 <__Z9test6_popR11AtomicList6+0x10>
100001701: mov rcx,QWORD PTR [rax]
100001704: mov QWORD PTR [rdi],rcx
100001707: pop rbp
100001708: ret
(stealth edit: pasted wrong thing)
As stores don’t get reordered with respect to other stores a fence instruction isn’t necessary (but TBB can do that too – __TBB_full_memory_fence(); – I think it’s undocumented, and I can’t figure out how to get lfence or sfence and not just mfence, but hey it’s something). I am a little bummed about the mov, xchg, cmp, je loopage – with cmpxchg you can just do cmpxchg and jnz back directly to it, but wow does it not really matter. And for completeness:
00000001000016b0 <__Z10test6_pushR11AtomicList6PNS_4NodeE>:
1000016b0: push rbp
1000016b1: mov rbp,rsp
1000016b4: nop WORD PTR [rax+rax*1+0x0]
1000016ba: nop WORD PTR [rax+rax*1+0x0]
1000016c0: mov rax,0xffffffffffffffff
1000016c7: lock xchg QWORD PTR [rdi],rax
1000016cb: cmp rax,0xffffffffffffffff
1000016cf: je 1000016c0 <__Z10test6_pushR11AtomicList6PNS_4NodeE+0x10>
1000016d1: mov QWORD PTR [rsi],rax
1000016d4: mov QWORD PTR [rdi],rsi
1000016d7: pop rbp
1000016d8: ret
you gotta love ‘nop’ taking arguments, lols. I know it’s more efficient, it’s just funny. And there will be a much fatter sad path in here when head == NULL in which case it needs to allocate a new slab and thread the next pointers and shit, but that’s all init time really, once enough pages come to life it won’t happen. Overall I’m okay with this.
So now I’m also wondering how to do the machine guns – the num-of-cores threads that furiously run through every cell running a sim stage till there are none – most direct approach is queue n affinity-locked tasks with a completion task that depends on them every stage every frame. It’s allocy, but what like 5 stages * 4 cores allocs per frame? Wow I shouldn’t care about that. At this point it feels like I’m building a life size eiffel tower out of toothpicks. Hey everyone needs a hobby.
page break
And the sweet sweet mdl. So with the current draft the structure of the net before neurons must fit snugly in everyone’s mem without a peep – that means every mdl node instance, of which there are num-of-cores per mdl box, knows where every little neocortical column is, and has a duplicate copy of that jazz in its mem (barring fork COW magic). I think this is doable. I’m seeing:
1) Gen till neurons
2) Map neuron generation to workers, either spatially or just buck wild randomly, dumping them all to flat files
3) Reduce all them flat files into an octree of neuron positions
4) Map synapse generation to workers, as above, dumping them all flat files
5) Reduce all that garbage into a humungous octree of synapse positions
Basically. There’s still a ton of question marks:
* Chopping them up into cells?
* Neurons and synapses have STATE, they grow and die and branch and shit, a simple octree alone isn’t sufficient
* Sharded octrees / state db’s? How you gonna handle edges?
* There’s also neurites, neural projections that spawn synapses but aren’t neurons themselves – kinda need them
* Will all syns really be ignorant of eachother? All neurites? All neurons? Or will it be stepped or something, jittering and tweaking the phases until some condition is met?
* Oh yeah the whole DSL is still in bits in pieces, I haven’t even decided the best way to generate radially distributed points yet (deceptively difficult to do cleanly, especially when I want density to vary arbitrarily by distance from the center).
But progress. Definitely heavily inspired by my data creator, in fact started as a straight python port of it. Brevity brought to you by __subclasses__().
^L
Oh, and finally on the spikerouter protocol. I have decreed that sims shall have three network.. things..: a udp spike listener, a tcp spike router update listener, and a tcp master command connection. udp spike sink will be dead simple, just taking (for now) bigass chunks of fired neuronid’s (really exportidxs, long story) of stuff that fired (for now, really a bit more complex than that but that’s the gist). Master conn is obvious conn. The spike router update listener is the recently materialized one – it’s sim <-> sim (well sim entity <-> sim entity), and connections are one time use. A sim connects to another when it needs to tell it that it wants to change the neurons it imports from it. It’s a linear transaction of ‘hi this is what I want from you’, ‘ok this is what I want from you’, ‘ok bye’. No fully connected disgusting network of persistent sim <-> sim connections, no statefulness to speak of, just a brief exchange, two ships passing in the night. tcp takes care of everything getting there, and in this case it’s important. For the actual udp spike exchanges I intend them to eventually be lossy, but more to the point they shouldn’t need to be acking all over the place when it happens so much. I am happy with this. Hopefully boost::asio will play nice with tbb, because I don’t want to write an async socket server, nor do I want yet another dep. boost, tbb, and sqlite are plenty for the sim. The python projects however, particularly the stats nodes, kitchen sink that shit. pip whorin it up. pandas you say? I don’t know what it is but I’ll take three.
I like how this post started out all poetic and ended up a grotesque, incomprehensible, vulgar, poorly capitalized mess. I feel like a perl coder.