def matmul_(a0, a1): if not (a0.Size == a1.Size and (a0.IsMatrix or a0.IsVector) \ and (a1.IsMatrix or a1.IsVector)): raise Exception("matmul(): unsupported operand shape!") if a0.IsVector and a1.IsVector: return _ek.dot(a0, a1) elif a0.IsMatrix and a1.IsVector: ar = a0[0] * a1[0] for i in range(1, a1.Size): ar = _ek.fmadd(a0[i], a1[i], ar) return ar elif a0.IsVector and a1.IsMatrix: ar = a1.Value() for i in range(a1.Size): ar[i] = _ek.dot(a0, a1[i]) return ar else: # matrix @ matrix ar, sr = _check2(a0, a1) for j in range(a0.Size): accum = a0[0] * _ek.full(a0.Value, a1[0, j]) for i in range(1, a0.Size): accum = _ek.fmadd(a0[i], _ek.full(a0.Value, a1[i, j]), accum) ar[j] = accum return ar
def test05_allclose(): m = ek.full(M, 1) assert ek.allclose(m, ek.full(M, 1)) m[1, 0] = 0 assert not ek.allclose(m, ek.full(M, 1)) m = ek.identity(M) assert ek.allclose(m, 1) m[1, 0] = 1 assert not ek.allclose(m, 1)
def test08_divmod(cname): t = get_class(cname) index = ek.arange(t, 10000000) index[index < len(index) // 2] = -index index *= 256203161 for i in range(1, 100): assert index // i == index // ek.full(t, i, 1, eval=True) assert index % i == index % ek.full(t, i, 1, eval=True) if t.IsSigned: for i in range(1, 100): assert index // -i == index // ek.full(t, -i, 1, eval=True) assert index % -i == index % ek.full(t, -i, 1, eval=True)
def test19_make_opaque(): Float = get_class('enoki.llvm.Float') Array3f = get_class('enoki.llvm.Array3f') a = Float(4.4) b = ek.full(Float, 3.3, 10) c = Array3f(2.2, 5.5, 6.6) assert a.is_literal_() assert not a.is_evaluated_() assert b.is_literal_() assert not b.is_evaluated_() for i in range(len(c)): assert c[i].is_literal_() assert not c[i].is_evaluated_() ek.make_opaque(a, b, c) assert not a.is_literal_() assert a.is_evaluated_() assert not b.is_literal_() assert b.is_evaluated_() for i in range(len(c)): assert not c[i].is_literal_() assert c[i].is_evaluated_()
def test15_test_avx512_approx(): Float = get_class('enoki.llvm.Float') x = ek.linspace(Float, 0, 10, 1000) o = ek.full(Float, 1, 1000) assert ek.allclose(ek.rsqrt(x), o / ek.sqrt(x), rtol=2e-7, atol=0) assert ek.allclose(ek.rcp(x), o / x, rtol=2e-7, atol=0)
def test07_loop_nest(pkg, variant): p = get_class(pkg) def collatz(value: p.Int): counter = p.Int(0) loop = p.Loop(value, counter) while (loop.cond(ek.neq(value, 1))): is_even = ek.eq(value & 1, 0) value.assign(ek.select(is_even, value // 2, 3 * value + 1)) counter += 1 return counter i = p.Int(1) buf = ek.full(p.Int, 1000, 16) ek.eval(buf) if variant == 0: loop_1 = p.Loop(i) while loop_1.cond(i <= 10): ek.scatter(buf, collatz(p.Int(i)), i - 1) i += 1 else: for i in range(1, 11): ek.scatter(buf, collatz(p.Int(i)), i - 1) i += 1 assert buf == p.Int(0, 1, 7, 2, 5, 8, 16, 3, 19, 6, 1000, 1000, 1000, 1000, 1000, 1000)
def fallof(self, cosTheta): # delta = (cosTheta - self.cosTotalWidth)/(self.cosFallOffStart - self.cosTotalWidth) delta = (self.cutOffAngle - ek.acos(cosTheta)) * self.m_invTransitionWidth delta = ek.select(cosTheta > self.cosFallOffStart, ek.full(type(delta), 1), delta) delta = ek.select(cosTheta < self.cosTotalWidth, ek.zero(type(delta)), delta) return delta
def test25_pow(m): x = ek.linspace(m.Float, 1, 10, 10) y = ek.full(m.Float, 2.0, 10) ek.enable_grad(x, y) z = x**y ek.backward(z) assert ek.allclose(ek.grad(x), ek.detach(x) * 2) assert ek.allclose( ek.grad(y), m.Float(0., 2.77259, 9.88751, 22.1807, 40.2359, 64.5033, 95.3496, 133.084, 177.975, 230.259))
def full_(cls, value, size, eval): result = cls() if cls.Size == Dynamic: result.init_(size) for i in range(size): result.set_entry_(i, value) else: if _ek.array_depth_v(value) != cls.Depth - 1: value = _ek.full(cls.Value, value, size, eval) for i in range(cls.Size): result.set_entry_(i, value) return result
params = traverse(scene) # Make a backup copy param_res = params['my_envmap.resolution'] param_ref = Float(params['my_envmap.data']) # Discard all parameters except for one we want to differentiate params.keep(['my_envmap.data']) # Render a reference image (no derivatives used yet) image_ref = render(scene, spp=16) crop_size = scene.sensors()[0].film().crop_size() write_bitmap('out_ref.png', image_ref, crop_size) # Change to a uniform white lighting environment params['my_envmap.data'] = ek.full(Float, 1.0, len(param_ref)) params.update() # Construct an Adam optimizer that will adjust the parameters 'params' opt = Adam(params, lr=.02) time_a = time.time() iterations = 100 for it in range(iterations): # Perform a differentiable rendering of the scene image = render(scene, optimizer=opt, unbiased=True, spp=1) write_bitmap('out_%03i.png' % it, image, crop_size) write_bitmap('envmap_%03i.png' % it, params['my_envmap.data'], (param_res[0], param_res[1]))
def test03_roundtrip(): pytest.importorskip("numpy") m = M(*range(1, 17)) + ek.full(M, ek.arange(ek.packet.Float)) m2 = M(m.numpy()) assert m == m2
# Find differentiable scene parameters params = traverse(scene) print(params) opt_param_name = 'textured_lightsource.emitter.radiance.data' # Make a backup copy param_res = params['textured_lightsource.emitter.radiance.resolution'] param_ref = Float(params[opt_param_name]) # Discord all parameters except for one we want to differentiate params.keep([opt_param_name]) # texture_bitmap = Bitmap('img/checker.jpg').convert(Bitmap.PixelFormat.RGB, Struct.Type.Float32, srgb_gamma=False) # texture_float = Float(texture_bitmap) # params['textured_lightsource.emitter.radiance.data'] = texture_bitmap params['textured_lightsource.emitter.radiance.data'] = ek.full( Float, 0.0, len(param_ref)) opt = Adam(params, lr=render_config['learning_rate']) time_a = time.time() outpath = os.path.join('outputs/invert_infloasion/', outimg_dir) os.makedirs(outpath, exist_ok=True) out_config(outpath, render_config) # Write out config file losses = np.array([]) film = scene.sensors()[0].film() crop_size = film.crop_size() iterations = render_config['num_iteration']
# Create another scene for optimizing geometry parameters del scene scene = make_scene(path_reparam_str, spp_opt, width, height) vertex_pos_key = 'grid_mesh.vertex_positions_buf' params = traverse(scene) params.keep([vertex_pos_key]) print('Parameter map after filtering: ', params) vertex_positions_buf = params[vertex_pos_key] vertex_positions = ravel(vertex_positions_buf) vertex_count = ek.slices(vertex_positions) if task == 'plain2bumpy': disp_tex_data_init = ek.full(Float, 0.0, vertex_count) disp_tex_data_ref = disp_tex_diffuser_1 displacements = ek.full(Float, 0.0, vertex_count) if task == 'bumpy2plain': disp_tex_data_init = disp_tex_diffuser_1 disp_tex_data_ref = ek.full(Float, 0.0, vertex_count) displacements = disp_tex_diffuser_1 * amp if task == 'bumpy2bumpy': disp_tex_data_init = disp_tex_diffuser_2 disp_tex_data_ref = disp_tex_diffuser_1 displacements = disp_tex_diffuser_2 * amp params_opt = {"displacements": displacements} if task == 'bumpy2bumpy':