### Configure Install Directories Source: https://github.com/mitsuba-renderer/drjit/blob/master/CMakeLists.txt Sets installation directories for Dr.Jit when building with SKBUILD. ```cmake if (SKBUILD) set(CMAKE_INSTALL_DATAROOTDIR drjit) set(CMAKE_INSTALL_INCLUDEDIR ${CMAKE_INSTALL_DATAROOTDIR}/include) endif() ``` -------------------------------- ### Install Dr.Jit Core Components Source: https://github.com/mitsuba-renderer/drjit/blob/master/CMakeLists.txt Installs the core Dr.Jit library targets and header files. This includes the main library, extra components, and nanothread. ```cmake if (DRJIT_MASTER_PROJECT) install(DIRECTORY include/drjit DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(TARGETS drjit-core EXPORT drjitTargets DESTINATION drjit) install(TARGETS drjit-extra EXPORT drjitTargets DESTINATION drjit) install(TARGETS nanothread EXPORT drjitTargets DESTINATION drjit) if (DRJIT_ENABLE_PYTHON) install(TARGETS drjit-python DESTINATION drjit) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/drjit/config.py ${CMAKE_CURRENT_BINARY_DIR}/drjit/__init__.pyi ${CMAKE_CURRENT_BINARY_DIR}/drjit/__init__.py ${CMAKE_CURRENT_BINARY_DIR}/drjit/ast.pyi ${CMAKE_CURRENT_BINARY_DIR}/drjit/ast.py ${CMAKE_CURRENT_BINARY_DIR}/drjit/dda.py ${CMAKE_CURRENT_BINARY_DIR}/drjit/detail.pyi ${CMAKE_CURRENT_BINARY_DIR}/drjit/detail.py ${CMAKE_CURRENT_BINARY_DIR}/drjit/hashgrid.pyi ${CMAKE_CURRENT_BINARY_DIR}/drjit/hashgrid.py ${CMAKE_CURRENT_BINARY_DIR}/drjit/interop.pyi ${CMAKE_CURRENT_BINARY_DIR}/drjit/interop.py ${CMAKE_CURRENT_BINARY_DIR}/drjit/nn.pyi ${CMAKE_CURRENT_BINARY_DIR}/drjit/nn.py ${CMAKE_CURRENT_BINARY_DIR}/drjit/opt.py ${CMAKE_CURRENT_BINARY_DIR}/drjit/random.pyi ${CMAKE_CURRENT_BINARY_DIR}/drjit/random.py ${CMAKE_CURRENT_BINARY_DIR}/drjit/py.typed DESTINATION drjit ) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/drjit/scalar/__init__.pyi ${CMAKE_CURRENT_BINARY_DIR}/drjit/scalar/__init__.py DESTINATION drjit/scalar ) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/drjit/llvm/py.typed ${CMAKE_CURRENT_BINARY_DIR}/drjit/llvm/__init__.pyi ${CMAKE_CURRENT_BINARY_DIR}/drjit/llvm/__init__.py ${CMAKE_CURRENT_BINARY_DIR}/drjit/llvm/ad.pyi ${CMAKE_CURRENT_BINARY_DIR}/drjit/llvm/ad.py DESTINATION drjit/llvm ) if (DRJIT_ENABLE_CUDA) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/drjit/cuda/py.typed ${CMAKE_CURRENT_BINARY_DIR}/drjit/cuda/__init__.pyi ${CMAKE_CURRENT_BINARY_DIR}/drjit/cuda/__init__.py ${CMAKE_CURRENT_BINARY_DIR}/drjit/cuda/ad.pyi ${CMAKE_CURRENT_BINARY_DIR}/drjit/cuda/ad.py DESTINATION drjit/cuda ) endif() if (DRJIT_ENABLE_METAL) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/drjit/metal/py.typed ${CMAKE_CURRENT_BINARY_DIR}/drjit/metal/__init__.pyi ${CMAKE_CURRENT_BINARY_DIR}/drjit/metal/__init__.py ${CMAKE_CURRENT_BINARY_DIR}/drjit/metal/ad.pyi ${CMAKE_CURRENT_BINARY_DIR}/drjit/metal/ad.py DESTINATION drjit/metal ) endif() install(FILES ${CMAKE_CURRENT_BINARY_DIR}/drjit/auto/py.typed ${CMAKE_CURRENT_BINARY_DIR}/drjit/auto/__init__.pyi ${CMAKE_CURRENT_BINARY_DIR}/drjit/auto/__init__.py ${CMAKE_CURRENT_BINARY_DIR}/drjit/auto/ad.pyi ${CMAKE_CURRENT_BINARY_DIR}/drjit/auto/ad.py DESTINATION drjit/auto ) endif() if (DRJIT_ENABLE_JIT) install(DIRECTORY ext/drjit-core/include/drjit-core DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(DIRECTORY ext/drjit-core/ext/nanothread/include/nanothread DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) endif() install(TARGETS drjit EXPORT drjitTargets) set(DRJIT_CMAKECONFIG_INSTALL_DIR "${CMAKE_INSTALL_DATAROOTDIR}/cmake/drjit") configure_package_config_file( resources/drjitConfig.cmake.in drjitConfig.cmake INSTALL_DESTINATION ${DRJIT_CMAKECONFIG_INSTALL_DIR}) write_basic_package_version_file( drjitConfigVersion.cmake VERSION ${DRJIT_VERSION} COMPATIBILITY AnyNewerVersion ARCH_INDEPENDENT) install( EXPORT drjitTargets DESTINATION ${DRJIT_CMAKECONFIG_INSTALL_DIR}) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/drjitConfigVersion.cmake ${CMAKE_CURRENT_BINARY_DIR}/drjitConfig.cmake DESTINATION ${DRJIT_CMAKECONFIG_INSTALL_DIR}) endif() ``` -------------------------------- ### Install LLVM on Linux Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/what.rst Instructions for installing LLVM on Debian/Ubuntu-based Linux distributions using the apt package manager. This is necessary for the LLVM backend. ```bash $ sudo apt install llvm ``` -------------------------------- ### Install LLVM on macOS Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/what.rst Instructions for installing LLVM on macOS using Homebrew. This is a prerequisite for using the LLVM backend on this platform. ```bash $ brew install llvm ``` -------------------------------- ### CoopVec Initialization Example Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/coop_vec.rst Shows the construction of a `nn.CoopVec` with specific values, including scalars and arrays. ```python from drjit import Float16, Array2f from drjit.nn import CoopVec vec = CoopVec( Float16(1), 3.0, Array2f(4, 5) ) ``` -------------------------------- ### Basic Frozen Function Example Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/freeze.rst Demonstrates a simple frozen function that performs an addition. This example is supported and shows basic usage. ```python @dr.freeze def frozen(l): return l[0] + 1 # This constructs a list with a reference cycle. l = [Float(1)] l.append(l) # Passing an object with a simple reference cycle is supported. frozen(l) ``` -------------------------------- ### MLP Training Example with Adam and GradScaler Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/nn.rst A complete example demonstrating the declaration and optimization of a multilayer perceptron for image fitting. It utilizes `Adam` for optimization and `GradScaler` for adaptive mixed-precision training, showing the full workflow from data loading to optimization steps. ```python from tqdm.auto import tqdm import imageio.v3 as iio import drjit as dr import drjit.nn as nn from drjit.opt import Adam, GradScaler from drjit.auto.ad import Texture2f, TensorXf, TensorXf16, Float16, Float32, Array2f, Array3f # Load a test image and construct a texture object ref = TensorXf(iio.imread("https://d38rqfq1h7iukm.cloudfront.net/media/uploads/wjakob/2024/06/wave-128.png") / 256) tex = Texture2f(ref) # Establish the network structure. Networks with an encoding # layer do not need biases, which simplifies the architecture. net = nn.Sequential( nn.TriEncode(16, 0.2), nn.Cast(Float16), nn.Linear(-1, -1, bias=False), nn.LeakyReLU(), nn.Linear(-1, -1, bias=False), nn.LeakyReLU(), nn.Linear(-1, -1, bias=False), nn.LeakyReLU(), nn.Linear(-1, 3, bias=False), nn.Exp() ) # Instantiate a random number generator to initialize the network weights rng = dr.rng(seed=0) # Instantiate the network for a specific backend + input size net = net.alloc( dtype=TensorXf16, size=2, rng=rng ) # Convert to training-optimal layout net = nn.pack(net, layout='training') print(net) # The optimizer discovers the parameter via the module's mapping # interface and keeps its own single-precision copy of the packed buffer. opt = Adam(lr=1e-3) opt.update(net) # This is an adaptive mixed-precision (AMP) optimization, where a half # precision computation runs within a larger single-precision program. # Gradient scaling is required to make this numerically well-behaved. scaler = GradScaler() res = 256 for i in tqdm(range(40000)): # Push the latest optimizer state back into the network (Float32 -> Float16). net.update(opt) # Generate jittered positions on [0, 1]^2 t = dr.arange(Float32, res) p = (Array2f(dr.meshgrid(t, t)) + rng.random(Array2f, (2, res * res))) / res # Evaluate neural net + L2 loss img = Array3f(net(nn.CoopVec(p))) loss = dr.squared_norm(tex.eval(p) - img) # Mixed-precision training: take suitably scaled steps dr.backward(scaler.scale(loss)) scaler.step(opt) # Done optimizing, now let's plot the result t = dr.linspace(Float32, 0, 1, res) p = Array2f(dr.meshgrid(t, t)) img = Array3f(net(nn.CoopVec(p))) ``` -------------------------------- ### Inclusive prefix reduction example Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Example of an inclusive prefix reduction using dr.ReduceOp.Add. The output is [a[0], a[0] + a[1], ...]. ```python dr.block_prefix_reduce(value, block_size, op=dr.ReduceOp.Add, exclusive=False) ``` -------------------------------- ### Dr.Jit Step Function Example Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Computes a step function by comparing two arguments. This is equivalent to a conditional selection based on the comparison. ```python dr.select( arg0 < arg1, 0, # if arg0 < arg1 1, # if arg1 >= arg1 ) ``` -------------------------------- ### Neural Network Module Example Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/changelog.rst Illustrates the basic import of the neural network module from Dr.Jit, which provides abstractions for constructing and evaluating neural networks. ```python import drjit.nn as nn from drjit.cuda.ad import TensorXf16, Float16 ``` -------------------------------- ### Optimizer Setup and Parameter Update Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/nn.rst Sets up an Adam optimizer and updates the network parameters. It also demonstrates how to add separate encoding parameters to the optimizer's update list. ```python # Optimize a single-precision copy of the parameters. The optimizer picks # up ``mlp.weights`` from ``net`` through the mapping interface and we # add the encoding parameters alongside. opt = Adam(lr=1e-3) opt.update(net) opt['enc.params'] = Float32(enc.params) ``` -------------------------------- ### Install Dr.Jit Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/what.rst Installs the latest version of Dr.Jit for Python. Ensure libatomic is installed on your system. ```bash python -m pip install --upgrade drjit ``` -------------------------------- ### Dr.Jit Type Promotion Example Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/misc.rst Demonstrates how Dr.Jit's type promotion rules determine the resulting type when performing operations between different Dr.Jit array types, such as maximum. ```python a: Array3u = ... b: Array3f = ... c: WhatIsThis = dr.maximum(a, b) ``` -------------------------------- ### Reverse inclusive prefix reduction example Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Example of a reverse inclusive prefix reduction using dr.ReduceOp.Add. The reduction is done from the end of each block. ```python dr.block_prefix_reduce(value, block_size, op=dr.ReduceOp.Add, exclusive=False, reverse=True) ``` -------------------------------- ### Fused Kernel Compilation Example in Dr.Jit Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/types.rst Illustrates the conceptual C code behind a fused kernel compilation in Dr.Jit, highlighting how temporaries are kept in registers for optimization. ```cpp // Loop parallelized using SIMD + multicore parallelism for (size_t i = 0; i < N; ++i) { float v0 = x[i]; float v1 = v0*v0; float v2 = sqrtf(v1); y[i] = v2; } ``` -------------------------------- ### Example of drjit.switch with scalar index Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Demonstrates the basic usage of drjit.switch with a scalar index to select a function from a list of targets. ```python from drjit.llvm import UInt32 res = dr.switch( index=UInt32(0, 0, 1, 1), # <-- selects the function targets=[ # <-- arbitrary list of callables lambda x: x, lambda x: x*10 ], UInt32(1, 2, 3, 4) # <-- argument passed to function ) # res now contains [0, 10, 20, 30] ``` -------------------------------- ### Forward Gradient Propagation Example Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Demonstrates a typical chain of operations for forward propagating gradients from a variable 'a' to 'b'. This can be written more compactly using dr.forward(a). ```python a = dr.llvm.ad.Float(1.0) dr.enable_grad(a) b = f(a) # some computation involving 'a' # The below three operations can also be written more compactly as dr.forward(a) dr.set_gradient(a, 1.0) dr.enqueue(dr.ADMode.Forward, a) dr.traverse(dr.ADMode.Forward) grad = dr.grad(b) ``` -------------------------------- ### GLInterop Example: Buffer Upload Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Demonstrates how to use GLInterop to upload data from a Dr.Jit tensor to an OpenGL buffer via CUDA. Ensures the resource is mapped before upload and unmapped afterwards. ```python interop = dr.cuda.GLInterop.from_buffer(gl_buffer_id) interop.map().upload(drjit_tensor).unmap() ``` -------------------------------- ### Construct Dr.Jit Array from NumPy Array Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Example of initializing a Dr.Jit array from a NumPy array. ```python Array3f(np.array([1, 2, 3])) ``` -------------------------------- ### Efficient Dispatch with drjit.dispatch() Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst This example demonstrates an alternative implementation using drjit.dispatch() to achieve a more efficient vectorized call compared to separate calls. ```python def my_func(self, arg1, arg2): return (self.func_1(arg1), self.func_2(arg2)) result_1, result_2 = dr.dispatch(inst, my_func, arg1, arg2) ``` -------------------------------- ### Example of Function Call with Instance Array Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Illustrates a function call on an instance array, which can generate numerous functions. This is relevant when considering JitFlag.MergeFunctions. ```python arr.f(inputs...) ``` -------------------------------- ### Configure Dr.Jit Include Directories Source: https://github.com/mitsuba-renderer/drjit/blob/master/CMakeLists.txt Specifies the include directories for the Dr.Jit interface library, including build and install paths. ```cmake target_include_directories(drjit INTERFACE $ $ $ $ $ ) ``` -------------------------------- ### CoopVec Arithmetic Example (sin) Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/coop_vec.rst Illustrates performing an operation not directly supported by `CoopVec` arithmetic by unpacking, applying the operation, and repacking. This may impact performance. ```python import drjit as dr from drjit.nn import CoopVec # Assume x is a CoopVec # y = nn.CoopVec(dr.sin(v) for v in x) ``` -------------------------------- ### GLInterop Example: Texture Upload Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Demonstrates how to use GLInterop to upload data from a Dr.Jit tensor to an OpenGL texture via CUDA. Ensures the resource is mapped before upload and unmapped afterwards. ```python interop = dr.cuda.GLInterop.from_texture(gl_texture_id) interop.map().upload(drjit_tensor).unmap() ``` -------------------------------- ### Constant Propagation Example Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/optim.rst Dr.Jit performs arithmetic involving literal constant arrays immediately, preventing these operations from becoming part of the generated device code. ```pycon >>> a = Int(4) + Int(5) >>> a.state dr.VarState.Literal ``` -------------------------------- ### Random Number Generation API Example Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/changelog.rst Illustrates the usage of the new random number generation API by creating a generator and calling methods to produce random numbers. ```python import drjit as dr # Example usage (specific methods not shown in source) rng = dr.rng(seed=0) random_value = rng.random() normal_value = rng.normal() ``` -------------------------------- ### CUDA Green Context Example Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Demonstrates creating and using a CUDA green context to isolate a specified number of streaming multiprocessors (SMs) for computations. Shows how to access context information and the remaining available SMs. ```python from drjit.cuda import green_context # Simple usage - isolate 16 SMs for computation with green_context(16): # Kernels launched here use only 16 SMs result = some_computation() # Access context information with green_context(16) as ctx: print(f"Requested: {ctx.requested_sm_count} SMs") print(f"Actual: {ctx.sm_count} SMs") # Use remaining_ctx for concurrent computation other_ctx = ctx.remaining_ctx if other_ctx is not None: # Launch work on remaining SMs pass ``` -------------------------------- ### Basic Parallel Loop in Dr.Jit Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/what.rst Illustrates a simple parallel loop for array element-wise computation. This is a foundational example of Dr.Jit's acceleration capabilities. ```python a = dr.zeros(1000000) for i in range(1000000): a[i] = i * (1.0 / 999999.0) ``` -------------------------------- ### Include Dr.Jit Array and Matrix Types Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/cpp.rst Include necessary headers for Dr.Jit's array and matrix types. This example demonstrates basic usage of Array3f and Matrix3f for vector operations. ```cpp #include namespace dr = drjit; using Array3f = dr::Array; using Matrix3f = dr::Matrix; int main(int, char**) { Array3f x(1, 2, 3), y(1, 0, 1); Array3f z = dr::normalize(dr::cross(x, y)) * .5f; printf("Result = %s\n", dr::string(z).c_str()); } ``` -------------------------------- ### Example Usage of compress and gather Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Demonstrates how to use `drjit.compress` to obtain indices from an active mask, and then use `drjit.gather` to extract corresponding elements from other arrays. This pattern is useful for reducing a stream to a subset of active entries. ```python # Input: an active mask and several arrays data_1, data_2, ... dr.schedule(active, data_1, data_2, ...) indices = dr.compress(active) data_1 = dr.gather(type(data_1), data_1, indices) data_2 = dr.gather(type(data_2), data_2, indices) # ... ``` -------------------------------- ### Construct Dr.Jit Array from Components Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Shows how to initialize a Dr.Jit array by providing its individual components. ```python Array3f(1, 2, 3) ``` -------------------------------- ### Neural Network Initialization and Packing Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/nn.rst Initializes a neural network with specified precision and dimensions, then converts it to a training-optimal layout. Prints the packed network structure. ```python net = net.alloc(TensorXf16, 2, rng=rng) # Convert to training-optimal layout. net = nn.pack(net, layout='training') print(net) ``` -------------------------------- ### Dr.Jit Scatter Exchange (scatter_exch) Example Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Illustrates the use of drjit.scatter_exch for atomically exchanging values and using the returned old values. Reusing the 'old' index in subsequent kernels without evaluation causes exceptions. ```python old = dr.scatter_exch(target=buffer, value=new_val, index=idx, active=active) dr.scatter( target=data_compact_1, value=data_1, index=old, # Using the returned old values as indices active=active ) dr.eval(data_compact_1) # Run Kernel #1 dr.scatter( target=data_compact_2, value=data_2, index=old, # <-- oops, reusing 'old' in another kernel. active=active # This raises an exception. ) ``` -------------------------------- ### Exclusive prefix reduction example Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Example of an exclusive prefix reduction using dr.ReduceOp.Add. The output is [0, a[0], a[0] + a[1], ...]. ```python dr.block_prefix_reduce(value, block_size, op=dr.ReduceOp.Add, exclusive=True) ``` -------------------------------- ### Type Variable Example in Dr.Jit Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/reference.rst Illustrates how type variables (T, ArrayT, MaskT) are used in function signatures to indicate how types propagate through function calls. For example, a function returning a pair of the input type. ```python def f(arg: T, /) -> tuple[T, T]: ... ``` -------------------------------- ### Dr.Jit Local Value Numbering Example Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst This example illustrates local value numbering, a form of common subexpression elimination. It demonstrates that performing the same arithmetic operation twice on non-literal arrays results in both operations referencing the same Dr.Jit variable. ```python from drjit.llvm import Int # Create two non-literal arrays stored in device memory a, b = Int(1, 2, 3), Int(4, 5, 6) # Perform the same arithmetic operation twice c1 = a + b c2 = a + b # Verify that c1 and c2 reference the same Dr.Jit variable assert c1.index == c2.index ``` -------------------------------- ### Dr.Jit Metaprogramming with User Input Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/what.rst Demonstrates metaprogramming in Dr.Jit where Python code, including user input, influences the generated device program. This allows for runtime specialization of programs. ```python a = np.linspace(0, x, 1000000, dtype=np.float32) print('Enter exponent: ', end='') i = int(input()) print(np.mean(np.sin(a**i))) ``` -------------------------------- ### Event_handle Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Get the raw backend-specific event handle as a 64-bit integer. ```APIDOC ## Event_handle ### Description Get the raw backend-specific event handle as a 64-bit integer. ### Returns - **int**: The raw event handle as an integer. ``` -------------------------------- ### Bind Dr.Jit Instance Arrays in C++ Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/cpp.rst Demonstrates how to create nanobind bindings for Dr.Jit instance arrays, enabling dispatch of function calls to the underlying C++ methods. Requires the 'drjit/python.h' header. ```cpp #include using FooPtr = dr::CUDADiffArray; dr::ArrayBinding b; auto base_ptr = dr::bind_array_t(b, m, "FooPtr") .def("f", [](FooPtr &self, Float a) { return self->f(a); }); ``` -------------------------------- ### Tensor Creation and Initialization Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/types.rst Shows how to create tensors using drjit.zeros and by initializing from a flat list with a specified shape. Tensors represent n-dimensional arrays with dynamic shapes. ```pycon >>> from drjit.llvm import TensorXf >>> drjit.zeros(TensorXf, shape=(1, 2, 3, 4)) [[[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]]] ``` ```pycon >>> t = TensorXf([1,2,3,4,5,6], shape=(3, 2)) >>> print(t) [[1, 2], [3, 4], [5, 6]] ``` -------------------------------- ### Quaternion Broadcasting Example Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/types.rst Demonstrates how broadcasting works when adding a scalar to a quaternion. The scalar is broadcast to the identity element of the quaternion. ```pycon >>> dr.scalar.Quaternion4f(1, 2, 3, 4) + 10 1i+2j+3k+14 ``` -------------------------------- ### CoopVec Arithmetic with Broadcasting Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/coop_vec.rst Shows an example of arithmetic operations between a `nn.CoopVec` and a regular Dr.Jit array, illustrating implicit broadcasting. ```python import drjit as dr from drjit.nn import CoopVec # Assume x is a CoopVec of dr.cuda.Float16 # Assume y is a dr.cuda.Float16 # z = dr.maximum(x, 0) + y ``` -------------------------------- ### Dr.Jit Freeze: Fractional Size Inference Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/freeze.rst Demonstrates how Dr.Jit infers output size as a fraction of input size when using @dr.freeze. The recorded fraction is used for subsequent calls. ```python x = dr.arange(Float, 8) y1 = func(x) assert dr.width(y1) == 4 x = dr.arange(Float, 16) y2 = func(x) assert dr.width(y2) == 8 ``` -------------------------------- ### Pack and Update Neural Network Weights (Old API) Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/changelog.rst Demonstrates the previous method for packing neural network weights and updating them with an optimizer. Requires manual casting between precisions. ```python weights, net = nn.pack(net, layout='training') opt = Adam(lr=1e-3, params={'weights': Float32(weights)}) for i in range(n): weights[:] = Float16(opt['weights']) ... ``` -------------------------------- ### Get Native Metal Texture Handle Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/textures.rst Retrieve the native handle of a Dr.Jit-allocated Metal texture to hand to a GUI for display. ```python tex = dr.metal.Texture2f.from_native_handle(mtl_texture) # sample it ``` -------------------------------- ### Set Install RPATH for Dynamic Libraries Source: https://github.com/mitsuba-renderer/drjit/blob/master/CMakeLists.txt Configures the RPATH for dynamic libraries based on the operating system when Dr.Jit is the master project. ```cmake if (DRJIT_MASTER_PROJECT) if (APPLE) set(DRJIT_ORIGIN "@loader_path") elseif(UNIX) set(DRJIT_ORIGIN "$ORIGIN") endif() set(CMAKE_INSTALL_RPATH "${DRJIT_ORIGIN}") endif() ``` -------------------------------- ### Enable LLVM Backend Source: https://github.com/mitsuba-renderer/drjit/blob/master/CMakeLists.txt Enables the LLVM backend for Dr.Jit and sets DRJIT_ENABLE_JIT to TRUE. Logs the status. ```cmake if (DRJIT_ENABLE_LLVM) set(DRJIT_ENABLE_JIT TRUE) message(STATUS "Dr.Jit: building the LLVM backend.") else() message(STATUS "Dr.Jit: *not* building the LLVM backend.") endif() ``` -------------------------------- ### Capture Range with Nsight Systems CLI (CUDA) Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/bench.rst Launch CUDA programs with the Nsight Systems CLI and the '--capture-range=cudaProfilerApi' option to tie recording to drjit.profile_enable regions. ```bash # Example usage (actual command may vary) # nsight_systems --capture-range=cudaProfilerApi [args...] ``` -------------------------------- ### Gradient-Based Optimization with Dr.Jit Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/changelog.rst Illustrates the usage of gradient-based optimizers like Adam for optimizing a function. It shows how to register parameters, compute loss and gradients, and update parameters within an optimization loop. ```python from drjit.opt import Adam from drjit.cuda import Float # Create optimizer and register parameters opt = Adam(lr=1e-3) rng = dr.rng(seed=0) opt['params'] = Float(rng.normal(Float, 100)) # Optimization loop for unknown function f(x) for i in range(1000): # Fetch current parameters params = opt['params'] # Compute loss and gradients loss = f(params) # Some function to optimize dr.backward(loss) # Update parameters opt.step() ``` -------------------------------- ### Reshape Tensor Example Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Converts a 1D tensor into a 2D tensor with a specified shape. The '-1' in the shape infers the dimension size. ```pycon >>> from drjit.llvm.ad import TensorXf >>> value = dr.arange(TensorXf, 6) >>> dr.reshape(value, (3, -1)) [[0, 1] [2, 3] [4, 5]] ``` -------------------------------- ### Create a Writable Texture Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/textures.rst Create a texture that can be written to from within a kernel, turning it into a render target. Requires a JIT backend. ```python tex = Texture2f([height, width], channels=4, writable=True) ``` -------------------------------- ### Symbolic Operation with @dr.syntax Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst The @dr.syntax decorator can generate symbolic operations automatically. This example predicates the execution of the body based on a condition. ```python from drjit.cuda import Float @dr.syntax def f(x: Float): if a < 0: # ... ``` -------------------------------- ### Reshape and Sum-Reduce Tensor Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Example of how to reshape a tensor and then perform a sum reduction on specific axes. This is useful for reducing blocks within a tensor. ```python result = dr.sum(dr.reshape(value, shape=(4, 4, 8, 2)), axis=(1, 3)) ``` -------------------------------- ### Record GPU Activity Timeline with Instruments CLI Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/bench.rst For a timeline view of GPU activity, use 'xctrace record' with the 'Metal System Trace' template. This method does not require dr.profile_enable() or MTL_CAPTURE_ENABLED. ```bash xctrace record --template "Metal System Trace" \ --output gpu.trace --launch -- python myscript.py ``` -------------------------------- ### Get DLPack device info with drjit.dlpack_device() Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Retrieve the DLPack device type and device ID for a given Dr.Jit array using drjit.dlpack_device(). ```python dr.dlpack_device(array) ``` -------------------------------- ### Avoid Modifying Non-State Variables in Loop Body Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst The loop body should not modify variables that are not declared as loop state. This example shows an incorrect modification of 'y'. ```python y = .. def loop_body(x): y[0] += x # <-- don't do this. 'y' is not a loop state variable dr.while_loop(body=loop_body, ...) ``` -------------------------------- ### Dr.Jit as a Header-Only Library Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/cpp.rst Demonstrates how to include and use Dr.Jit as a header-only library in a C++ project, including basic array and matrix operations. ```APIDOC ## Using Dr.Jit as a Header Library Dr.Jit operates as a header-only library by default, requiring no additional dependencies. ### Example Usage ```cpp #include namespace dr = drjit; using Array3f = dr::Array; using Matrix3f = dr::Matrix; int main(int, char**) { Array3f x(1, 2, 3); y(1, 0, 1); Array3f z = dr::normalize(dr::cross(x, y)) * .5f; printf("Result = %s\n", dr::string(z).c_str()); } ``` ``` -------------------------------- ### Run Pytest with Libasan (macOS) Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/debug.rst Execute the Python test suite using pytest with libasan preloaded. Ensure to use --capture no to see sanitizer messages. Adjust PYTHON_BIN and PYTHON_DYLD paths as needed. ```bash PYTHON_BIN="/opt/homebrew/Cellar/python@3.12/3.12.1/Frameworks/Python.framework/Versions/3.12/Resources/Python.app/Contents/MacOS/Python" PYTHON_DYLD="$(clang -print-file-name=libclang_rt.asan_osx_dynamic.dylib)" DYLD_INSERT_LIBRARIES=$PYTHON_DYLD $PYTHON_BIN -m pytest --capture no ``` -------------------------------- ### Vectorizing and Parallelizing Array Operations Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/optim.rst Dr.Jit automatically vectorizes and parallelizes traced code. The behavior is backend-specific. This example demonstrates squaring an integer sequence. ```pycon >>> from drjit.auto import Int >>> dr.arange(Int, 10000)**2 [0, 1, 4, .. 9994 skipped .., 99940009, 99960004, 99980001] ``` -------------------------------- ### Enable Metal Backend Source: https://github.com/mitsuba-renderer/drjit/blob/master/CMakeLists.txt Enables the Metal backend for Dr.Jit and sets DRJIT_ENABLE_JIT to TRUE. Logs the status. ```cmake if (DRJIT_ENABLE_METAL) set(DRJIT_ENABLE_JIT TRUE) message(STATUS "Dr.Jit: building the Metal backend.") else() message(STATUS "Dr.Jit: *not* building the Metal backend.") endif() ``` -------------------------------- ### Build Dr.Jit Documentation with Sphinx Source: https://github.com/mitsuba-renderer/drjit/blob/master/CMakeLists.txt This target builds the HTML documentation using Sphinx. It requires Sphinx to be found and sets up the input and output directories for the documentation. ```cmake if (DRJIT_MASTER_PROJECT) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/resources) find_package(Sphinx) if (Sphinx_FOUND) set(SPHINX_INPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/docs") set(SPHINX_OUTPUT_DIR "${CMAKE_CURRENT_BINARY_DIR}/html") add_custom_target(mkdoc ${CMAKE_COMMAND} -E env PYTHONPATH="${CMAKE_CURRENT_BINARY_DIR}" ${SPHINX_EXECUTABLE} -b html "${SPHINX_INPUT_DIR}" "${SPHINX_OUTPUT_DIR}" COMMENT "Building HTML documentation with Sphinx" USES_TERMINAL) endif() endif() ``` -------------------------------- ### Vectorized while loop example Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst This snippet demonstrates how to use drjit.while_loop to perform a vectorized loop operation, equivalent to a standard Python while loop but supporting array inputs. ```python i, x = dr.while_loop( state=(i, x), cond=lambda i, x: i < 10, body=lambda i, x: (i+1, x*x) ) ``` -------------------------------- ### Unsupported Return Type Example Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/freeze.rst Illustrates an unsupported return type from a frozen function. Objects of `MyClass` cannot be created at replay time because its constructor requires an argument. ```python class MyClass: x: Float DRJIT_STRUCT = { "x": Float, } # Non-default constructor (requires argument `x`) def __init__(self, x: Float): self.x = x @dr.freeze def func(x): return MyClass(x + 1) ``` -------------------------------- ### Construct Dr.Jit Array via Broadcast Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Demonstrates creating a Dr.Jit array where a single value is broadcast to all components. ```python Array3f(1) ``` -------------------------------- ### Vectorized If Statement in C++ Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/cpp.rst Example of a vectorized if statement using dr::if_stmt in C++. This function allows for symbolic and evaluated conditionals, analogous to the Python interface. ```cpp using Int = dr::CUDAArray; Int i = ..., j = ....; ``` -------------------------------- ### Creating a Matrix View Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Shows how to create a MatrixView from a Dr.Jit array or tensor. This view provides metadata about the buffer, shape, and type without copying data. ```python # Convert a Dr.Jit array or tensor into a *view*. view = drjit.nn.view(tensor) ``` -------------------------------- ### Get Python Executable Path (macOS) Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/debug.rst Use this Python script with ctypes to determine the path of the actual Python executable on macOS. This is necessary for preloading libasan. ```python import ctypes dyld = ctypes.cdll.LoadLibrary('/usr/lib/system/libdyld.dylib') namelen = ctypes.c_ulong(1024) name = ctypes.create_string_buffer(b'\000', namelen.value) dyld._NSGetExecutablePath(ctypes.byref(name), ctypes.byref(namelen)) print(name.value) ``` -------------------------------- ### Construct and Compute with 1D Float Arrays in Dr.Jit Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/types.rst Demonstrates creating a 1D Float array, printing its contents, and performing a computation. The kernel generated for the computation is fused and cached for reuse. ```pycon >>> import drjit as dr >>> from drjit.llvm import Float >>> x = Float(1, .5, .25) >>> print(x) [1, 0.5, 0.25] >>> y = dr.sqrt(1-x**2) >>> print(y) [0, 0.866025, 0.968246] ``` -------------------------------- ### Dr.Jit gather operation with Array4f Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Example of using dr.gather to collect 4D vectors from a flat array. Ensure the source array is compatible with the target array type. ```python from drjit.auto import Array4f, Float, UInt32 source = Float(...) result = dr.gather(Array4f, source, index=UInt32(...)) ``` -------------------------------- ### Packing and Unpacking Cooperative Vectors Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Demonstrates how to create cooperative vectors from individual components or arrays, and how to unpack them back into components or arrays. It also shows converting multiple arrays into a single cooperative vector. ```python # Pack individual components into a cooperative vector vec = drjit.nn.CoopVec(x, y, z) # Unpack components x, y, z = vec # Unpack directly into 3D array xyz = Array3f(vec) # Convert a 3D array and a 2D array into a 5D cooperative vector a1: Array3f = ... a2: Array2f = ... vec = drjit.nn.CoopVec(a1, a2) ``` -------------------------------- ### Vectorized while loop with @drjit.syntax decorator Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst This example shows how the @drjit.syntax decorator can be used to write vectorized while loops using natural Python syntax, which is then automatically rewritten by Dr.Jit. ```python @dr.syntax def f(i, x): while i < 10: x *= x i += 1 return i, x ``` -------------------------------- ### Event_init Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Create a new Event object for synchronization and timing. ```APIDOC ## Event_init ### Description Create a new Event. ### Parameters #### Arguments - **enable_timing** (bool) - If True, the event can be used for timing measurements. Default: True. This flag has no effect on the Metal backend. ### Returns - **Event**: A new Event object. ``` -------------------------------- ### Initialize HashGridEncoding in Dr.Jit Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/nn.rst Demonstrates the initialization of a HashGridEncoding layer for neural networks. This encoding is suitable for low-dimensional inputs and uses a hash table for memory efficiency. It requires specifying the data type, input dimension, number of levels, features per level, and scaling factor. ```python from tqdm.auto import tqdm import imageio.v3 as iio import drjit as dr import drjit.nn as nn from drjit.opt import Adam, GradScaler from drjit.auto.ad import Texture2f, TensorXf, TensorXf16, Float16, Float32, Array2f, Array3f # Load a test image and construct a texture object ref = TensorXf(iio.imread("https://d38rqقومh7iukm.cloudfront.net/media/uploads/wjakob/2024/06/wave-128.png") / 256) tex = Texture2f(ref) # Instantiate a random number generator to initialize the network weights rng = dr.rng(seed=0) # Create a two dimensional hash grid encoding, with 8 levels, 2 features per # level and a scaling factor between levels of 1.5. enc = nn.HashGridEncoding( Float16, 2, n_levels=8, n_features_per_level=2, per_level_scale=1.5, rng=rng, ) # Alternatively we can also use a permutohedral encoding. In contrast to a hash # grid, it uses triangles, tetrahedrons and their higher dimensional # equivalences as simplexes. Their vertex count scales linearly with dimension, # allowing for higher dimensional inputs, while keeping the memory lookup # overhead minimal. # Uncomment the following lines to enable the permutohedral encoding. # enc = nn.PermutoEncoding( # Float16, # 2, # n_levels=8, # n_features_per_level=2, # per_level_scale=1.5, # ) print(enc) ``` -------------------------------- ### Accumulator Class with Positive Addition Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/cflow.rst This example demonstrates an accumulator class where the add_positive method only updates the value if the input is positive. It utilizes @dr.syntax for control flow tracing. ```python from drjit.auto import Int class Accum: def __init__(self): """Create a zero-initialized accumulator""" self.value = Int(0) @dr.syntax def add_positive(self, x: Int): """Accumulate 'x', but only if it is positive""" if x > 0: ``` -------------------------------- ### Dr.Jit CUDA Green Context Initialization Source: https://github.com/mitsuba-renderer/drjit/blob/master/docs/misc.rst Shows how to use the drjit.cuda.green_context context manager to isolate a specified number of SMs for kernel execution. ```python from drjit.cuda import green_context with green_context(16): ... # kernels launched here run on 16 SMs ``` -------------------------------- ### Get Associated Scalar Type with scalar_t Source: https://github.com/mitsuba-renderer/drjit/blob/master/src/python/docstr.rst Use scalar_t to determine the lowest-level scalar type of a Dr.Jit array or type. If the input is not a Dr.Jit type, it is returned unchanged. ```python assert dr.scalar_t(dr.scalar.Array3f) is bool assert dr.scalar_t(dr.cuda.Array3f) is float assert dr.scalar_t(dr.cuda.Matrix4f) is float assert dr.scalar_t(dr.cuda.TensorXf) is float assert dr.scalar_t(str) is str assert dr.scalar_t("test") is str ```