<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://piyja.github.io/feed.xml" rel="self" type="application/atom+xml"/><link href="https://piyja.github.io/" rel="alternate" type="text/html" hreflang="en"/><updated>2026-07-28T13:56:41+00:00</updated><id>https://piyja.github.io/feed.xml</id><title type="html">blank</title><entry><title type="html">We Are Developers 2026 — Trip Report</title><link href="https://piyja.github.io/blog/2026/we-are-developers-2026-trip-report/" rel="alternate" type="text/html" title="We Are Developers 2026 — Trip Report"/><published>2026-07-10T00:00:00+00:00</published><updated>2026-07-10T00:00:00+00:00</updated><id>https://piyja.github.io/blog/2026/we-are-developers-2026-trip-report</id><content type="html" xml:base="https://piyja.github.io/blog/2026/we-are-developers-2026-trip-report/"><![CDATA[<h1 id="wad-2026">We Are Developers 2026 — Berlin</h1> <p>We Are Developers is one of those conferences where the sheer volume of content makes it impossible to catch even 10–15% of what is happening. With <strong>10+ tracks</strong> of tech talks, <strong>6+ workshops</strong> running 2 hours each, and a packed exhibition floor, the only winning strategy is to be deliberately selective — pick the areas that matter most to your current work and go deep there. Most of the talks end up on YouTube anyway, so the real value of attending in person is the workshops, the hallway conversations, and the booth visits.</p> <p>I spent most of my time at the conference attending hands-on workshops, talking to people to catch key insights on <strong>Edge AI application development</strong>, visiting booths to understand what they offer and how their tools could fit into our work, and cherry-picking talks that aligned with these interests.</p> <h2 id="booth-visits">Company booth visits</h2> <p>The exhibition floor is where you get a concentrated view of where the industry is heading — each booth is a window into a specific bet someone is making. Here are the ones that stood out:</p> <ul> <li><strong>Antithesis</strong> — their approach to test generation from “key property” based testing is compelling. Instead of writing individual test cases, you define the properties your system must satisfy, and their platform generates the tests automatically. Great potential for catching edge cases that manual test writing tends to miss.</li> <li><strong>Qualcomm + Arduino + Edge Impulse</strong> — a joint showcase around Edge AI. Qualcomm has spun off an edge compute initiative where you can collect and train data using their software stack, paired with Arduino hardware for on-device deployment. The end-to-end flow from data collection to model training to edge deployment was well demonstrated.</li> <li><strong>Snowflake</strong> — stopped by to understand the breadth of cloud services they now offer beyond the data warehousing core. The platform has expanded significantly into data applications and AI workloads.</li> <li><strong>OpenSearch</strong> — the open-source search platform continues to mature. Useful to see how it positions against managed alternatives, especially for use cases where data sovereignty matters.</li> <li><strong>Neo4j</strong> — graph-based search and knowledge representation. With the growing interest in graph-based retrieval for RAG systems, this was a timely visit to understand the current state of their APIs and integrations.</li> <li><strong>Vercel</strong> — showcased their AI-powered platform capabilities — agents, skills, and the developer experience they are building around server-side AI inference. Interesting to see how they are thinking about the developer workflow for agentic applications.</li> <li><strong>LaunchDarkly</strong> — beyond feature flags, they are now running tests automatically to find vulnerabilities and can revert deployments automatically when issues are detected. The shift from feature management to automated safety nets is a notable evolution.</li> </ul> <h2 id="talks">Talks</h2> <h3 id="day0-copilot">Day 0 — Copilot inside IntelliJ IDEs</h3> <p>Day 0 was overcrowded and I could only attend one talk. The session on <strong>Co-Pilot inside IntelliJ IDEs</strong> showcased practices that are fairly regular for us now — code completion, context-aware suggestions, and the usual workflow integrations. One new learning stood out: a <strong>containerised method to run parallel tasks</strong> with a coding agent, enabling multiple agents to work simultaneously. You can also use <code class="language-plaintext highlighter-rouge">git worktree</code> to achieve something similar — spinning up isolated working trees so each agent has its own clean context to operate in. Practical and immediately useful.</p> <h3 id="day1-talks">Day 1</h3> <p><strong>Thomas Dohmke — The Agentic Assembly Line</strong> was a highlight. The core idea: store context and memory that can be transferred across sessions. Instead of every coding session starting from scratch, the system retains the chat history and commit context alongside the code changes — so it understands not just <em>what</em> was done, but <em>how</em> the solution space was explored to arrive there. This is a significant step towards making coding agents feel like continuous collaborators rather than stateless tools.</p> <p><strong>The R in RAG: Why Retrieval is Often the Weakest Link (and How to Fix It)</strong> dug into the part of the RAG pipeline that most practitioners struggle with. The talk went beyond the usual “chunk your data better” advice and addressed the structural issues in retrieval that cause downstream generation quality to suffer.</p> <p><strong>Goodbye Microservices, Hello Self-Contained Systems</strong> made a case for a middle ground between monoliths and microservices — systems that are self-contained enough to be independently deployable and understandable, without the operational overhead that microservices architectures tend to accumulate.</p> <p><strong>Owning the Inference Layer: When and How to Run Your Own Models</strong> covered the decision framework for when to self-host inference versus relying on API providers, and the practical considerations around cost, latency, and control that go into that choice.</p> <p><strong>The Retrieval Layer for Edge AI</strong> was a demo session showing what edge AI applications can do in practice — live object detection through smart glasses. Seeing the retrieval and inference pipeline run in real-time on a constrained device made the practical possibilities feel much more tangible.</p> <p><strong>Inside Mercedes-Benz: 140 Years of Heritage Meet AI</strong> explored how a legacy automotive giant is integrating AI into its operations and products — a useful perspective on the challenges of bringing modern AI capabilities into established engineering cultures.</p> <p><strong>Nemotron: NVIDIA’s Open Model Strategy for Developers</strong> covered NVIDIA’s approach to open models aimed at giving developers more flexibility in deploying inference workloads, particularly for specialised domains.</p> <p><strong>Building the Nervous System of AI</strong> framed the infrastructure layer — the connectivity, data pipelines, and orchestration — that ties AI components together into functioning systems, much like a nervous system coordinates a body.</p> <p><strong>Physical AI for the Next Wave of Industrial Digitalisation</strong> was one of the most forward-looking talks. It covered the NVIDIA stack for physical AI: <strong>Omniverse</strong> for simulation environments, <strong>Cosmos</strong> for synthetic data generation, and <strong>Isaac</strong> for physical AI foundational models. All built around open-source models and blueprints designed to run on specific hardware. This is where the digital-physical gap starts closing.</p> <h3 id="day2-talks">Day 2</h3> <p><strong>Future of Mobile AI: What On-Device Intelligence Means for App Developers</strong> was a comprehensive overview of where edge inference is heading. The key points:</p> <ul> <li><strong>Models are small enough to run on devices</strong> — ranging from 300M to 1B to 3B parameters. Models like Gemma, Qwen, and Phi are making on-device inference practical for real applications.</li> <li><strong>Runtimes</strong> — ONNX Runtime and llama.cpp are the dominant options for running these models efficiently on constrained hardware.</li> <li><strong>Frameworks</strong> — MediaPipe and Cactus are making it easier to integrate on-device models into mobile applications without deep ML expertise.</li> <li><strong>Hardware</strong> — NPUs and TPUs are now measured in FLOP/s and TOP/s (tera operations per second), and the available silicon is finally catching up to what these small models need.</li> <li><strong>Arbitration approaches</strong> — the question of when to run on-device versus when to fall back to the cloud. Patterns discussed included mobile-first, cloud-first, intent classification to route requests, and a cascading approach where you try on-device first and escalate to cloud only when needed.</li> </ul> <h2 id="workshops">Workshops</h2> <h3 id="day1-workshops">Day 1</h3> <p><strong>Accelerating AI Inference at Scale: A Deep Dive into NVIDIA Dynamo on Kubernetes</strong> was a hands-on session with dedicated hardware — 2 H100 GPUs each. The workshop covered:</p> <ul> <li>Basics of inferencing and the tokenization process inside LLMs — understanding what actually happens when tokens flow through the model.</li> <li><strong>Disaggregation optimisation techniques</strong> — separating different stages of the inference pipeline (prefill vs decode) to optimise throughput and latency independently.</li> <li>Performance benchmarking with AI Perf for LLM inferencing workloads.</li> </ul> <p>Having dedicated H100s for a hands-on notebook session is a rare opportunity — it made the optimisation concepts much more concrete when you could see the performance numbers change in real time.</p> <p><strong>Edge Impulse — Ducks, Sensors &amp; Agents: Hands-On Edge AI with Arduino UNO Q</strong> was a full end-to-end edge AI workshop. Using the Arduino Q with the Qualcomm chip:</p> <ul> <li>Collected data on the Edge Impulse cloud instance — image data for object recognition and gyroscope data for motion classification.</li> <li>Trained models on the collected data directly within the platform.</li> <li>Deployed the trained models onto the Arduino hardware and ran inference locally — classifying ducks in real time from camera input.</li> </ul> <p>The workshop was a clean demonstration of the full edge AI loop: collect → train → deploy → infer, all within a constrained hardware setup.</p> <h3 id="day2-workshops">Day 2</h3> <p><strong>Compress, Cut, and Distill: The Latest Gen AI Model Compression Techniques in Practice</strong> was directly relevant to anyone working on deploying models on edge devices. The workshop covered the full toolkit:</p> <ul> <li><strong>Quantisation</strong> — reducing the precision of model weights to shrink model size and speed up inference, with practical guidance on when to use INT8, INT4, or mixed precision.</li> <li><strong>Depth-wise pruning</strong> — removing entire layers from the model to reduce depth, trading some accuracy for significant gains in inference speed.</li> <li><strong>Breadth-wise pruning</strong> — reducing the width of layers (fewer neurons per layer) while keeping the depth, a finer-grained approach to compression.</li> <li><strong>Distillation techniques</strong> — training a smaller student model to mimic the behaviour of a larger teacher model, preserving much of the capability at a fraction of the compute cost.</li> </ul> <p><strong>Generate Synthetic Data for Physical AI with NVIDIA Cosmos World Foundation Models</strong> covered:</p> <ul> <li>What Cosmos models are and how they fit into the physical AI pipeline.</li> <li>Generating synthetic data with these models for training — particularly useful when real-world data is expensive or dangerous to collect.</li> </ul> <h2 id="takeaways">Key takeaways</h2> <p>The overarching theme across the conference was clear: <strong>AI is moving closer to the edge, and the tooling to make that practical is finally maturing.</strong> From the small models (Gemma, Qwen, Phi) that can run on phones, to the runtimes (ONNX Runtime, llama.cpp) that make it efficient, to the hardware (NPUs, TPUs) that provides the compute — the full stack for on-device intelligence is coming together.</p> <p>The other thread running through many talks and workshops was <strong>model optimisation as a first-class concern</strong> — quantisation, pruning, distillation, and disaggregated inference are no longer niche techniques but essential tools in any engineer’s toolkit for deploying AI at scale.</p> <p>And the agentic wave continues to build — from coding agents that retain context across sessions, to the assembly-line patterns for orchestrating multiple agents, to the infrastructure plays from NVIDIA and others making it possible to run these systems efficiently. The shift from stateless tools to continuous collaborators is underway.</p>]]></content><author><name></name></author><category term="Field Notes"/><category term="Edge AI"/><category term="Agents"/><category term="Inference"/><category term="Conferences"/><summary type="html"><![CDATA[A trip report from We Are Developers 2026 in Berlin — workshops, talks, booth visits, and key takeaways on Edge AI, inference optimisation, and the agentic wave.]]></summary></entry><entry><title type="html">Review: PhD Thesis — Dr Ilias Trommer</title><link href="https://piyja.github.io/blog/2026/phd-thesis-ilias-trommer/" rel="alternate" type="text/html" title="Review: PhD Thesis — Dr Ilias Trommer"/><published>2026-06-15T00:00:00+00:00</published><updated>2026-06-15T00:00:00+00:00</updated><id>https://piyja.github.io/blog/2026/phd-thesis-ilias-trommer</id><content type="html" xml:base="https://piyja.github.io/blog/2026/phd-thesis-ilias-trommer/"><![CDATA[<p>On the quest of learning about machine learning at the edge — from building and optimizing models to tuning data pipelines and the infrastructure around them — I came across Dr. Trommer’s talk at an event in Berlin. It sparked enough interest to follow up, and along with some references, he suggested reading his thesis to get a grounded understanding of fundamental optimization techniques for model training and inference. I’ll admit that some sections were not easy reads, but in the interest of time I focused on understanding the main arguments and conclusions rather than working through every mathematical derivation.</p> <p>The thesis covers techniques for optimizing neural networks to run on edge devices. The central constraint at the edge is power — tokens per watt is the metric that matters, not raw throughput. Dr Trommer’s argument is that models can be optimized through quantization (both during training and post-training at inference time), and that quantization-aware training in particular yields meaningful gains. A key premise throughout is that training and inference should not be designed in isolation — thinking about them jointly produces better outcomes when deploying on embedded hardware.</p> <hr/> <h2 id="key-challenges-of-edge-ai-focused-in-this-work">Key Challenges of Edge AI Focused in this Work</h2> <ul> <li><strong>Energy efficiency</strong>: power consumed per inference is the primary performance metric; tokens per watt is what counts</li> <li><strong>Memory constraints</strong>: RAM is limited, which affects how large a model can be, how fast it runs, and how much context it can hold — target inference speeds for coding models, for example, are around 40–50 tokens per second</li> </ul> <h2 id="thinking-from-first-principles">Thinking from First Principles</h2> <ul> <li>The bulk of computation during inference is spent on multiplication</li> <li>This is the core operation that GPUs and NPUs are built around</li> <li>Approximate multiplication exploits the fact that exact precision is not always necessary — tolerating small arithmetic errors in exchange for lower cost</li> <li>Model weights tend to be highly sparse: many values are near zero after training. By identifying and encoding only the non-zero parameters, the model can be compacted significantly, reducing both memory footprint and the number of operations needed at runtime — directly addressing the memory and power constraints of edge deployment</li> </ul> <h2 id="chapter-1-foundations-of-efficient-neural-networks">Chapter 1: Foundations of Efficient Neural Networks</h2> <ul> <li>Overview of how to make models more efficient for deployment</li> <li>Post-training quantization: reducing numerical precision after training is complete</li> <li>Quantization-aware training: simulating quantization during training so the model learns to be robust to reduced precision</li> <li>Pruning: inducing sparsity by removing less important weights from the model</li> <li>Approximate computing: accepting small arithmetic errors to reduce computational cost</li> </ul> <h2 id="torchapprox-a-pytorch-extension-for-approximate-multiplication">TorchApprox: A PyTorch Extension for Approximate Multiplication</h2> <ul> <li>An extension to PyTorch that brings approximate multiplication into standard deep learning workflows</li> <li>Includes support for multiple quantization techniques, making it practical to experiment with approximate computing in training</li> </ul> <h2 id="chapters-3--4-approximate-multiplication-in-depth">Chapters 3 &amp; 4: Approximate Multiplication in Depth</h2> <ul> <li>Introduces approximate multiplication as a first-class design consideration for efficient models</li> <li>Model sensitivity to approximation errors can be predicted — this makes it possible to apply approximate multiplication selectively where it does least harm</li> <li>The space of possible approximate multipliers is unbounded, but bounding it to a practical subset enables hardware-efficient implementations</li> </ul> <h2 id="chapter-5-memory-efficient-sparse-parameter-encoding">Chapter 5: Memory-Efficient Sparse Parameter Encoding</h2> <ul> <li>Introduces a memory-efficient encoding scheme for sparse parameter matrices</li> <li>Addresses unstructured pruning, where individual weights are zeroed out rather than entire structures like filters or layers</li> </ul> <h2 id="chapter-6-end-to-end-application">Chapter 6: End-to-End Application</h2> <ul> <li>Combines approximate multiplication and unstructured pruning in a practical deployment scenario</li> <li>The result: arithmetic resource usage and memory footprint are each reduced by approximately 50%</li> </ul> <hr/> <p>Dr Trommer is notably clear-eyed about the scope and limitations of the work — he explicitly identifies which perspectives are missing and what the study does not measure, with energy consumption being the primary axis of evaluation throughout. The thesis offers a coherent set of insights into how model training and inference can be co-optimized by targeting the most fundamental operation a processor performs: multiplication. The parallel thread on sparse parameter representation and memory-efficient encoding adds another practical dimension, showing how the structural properties of trained weights can themselves be leveraged to reduce the cost of running models on constrained hardware. Taken together, it is a focused and technically honest contribution to the problem of deploying capable models at the edge.</p>]]></content><author><name></name></author><category term="ai-engineering"/><category term="MLSystems"/><category term="LLM"/><summary type="html"><![CDATA[Notes from reading Dr. Ilias Trommer's PhD thesis on efficient neural network inference]]></summary></entry><entry><title type="html">My Personalised Coding Agent Workflows</title><link href="https://piyja.github.io/blog/2026/coding-agents-workflow/" rel="alternate" type="text/html" title="My Personalised Coding Agent Workflows"/><published>2026-06-08T00:00:00+00:00</published><updated>2026-06-08T00:00:00+00:00</updated><id>https://piyja.github.io/blog/2026/coding-agents-workflow</id><content type="html" xml:base="https://piyja.github.io/blog/2026/coding-agents-workflow/"><![CDATA[<h1 id="my-personalised-coding-agent-workflows">My Personalised Coding Agent Workflows</h1> <h2 id="what-is-the-agentic-coding-workflow">What is the agentic coding workflow?</h2> <p>The agentic coding workflow is about using LLMs as a <strong>thinking partner and a coding assistant</strong> — not just a smarter autocomplete. I started skeptical. Chat bots felt like a party trick; agentic workflows felt like hype. That changed when I started seeing real productivity gains on tasks that would have otherwise cost me hours: complex refactors, iterative debugging, developing implementations from high level design. Now I use coding agents across the full spectrum — from quick planning sketches to multi-session tasks that evolve well beyond my initial idea.</p> <h2 id="setup-of-the-coding-harness">Setup of the coding harness</h2> <p>Every week there are new frontier coding models dropping, each claiming to break the previous benchmark. I’ve stopped chasing benchmarks and instead optimised for flexibility.</p> <p>My daily workflow runs on two harnesses:</p> <ul> <li><strong>Pi coding agent</strong> — fully open source, minimalist by design. You bring your own models, including local ones. That model-agnostic freedom is the main reason I consider it my primary harness. I’ve connected both local and frontier models to it, and the ability to swap without changing my workflow is something Claude Code can’t match.</li> <li><strong>Claude Code</strong> — excellent capabilities, but strictly tied to Anthropic’s models behind API walls. I use it when I need the full weight of Sonnet/Opus on a hard problem.</li> </ul> <h4 id="how-much-can-a-12b-edge-model-actually-do-for-coding">How much can a 12B edge model actually do for coding?</h4> <p>Quite a lot, if you prompt it right. A 12B model falls apart on complex tasks when you dump everything at once — but break the task into small, well-scoped steps and prompt iteratively, and it holds up well. It handles code reviews, simple generation, and debugging reliably. My current pattern: use a heavy frontier model to create a clear, well-structured plan, then hand execution to the small model. It follows defined plans well. The cost savings are significant and the quality loss is minimal when the plan is tight.</p> <h2 id="using-skills-effectively">Using skills effectively</h2> <p>Skills are how I extend what coding agents can do without burning tokens reinventing workflows in every session.</p> <p>Skills I keep coming back to:</p> <ul> <li><code class="language-plaintext highlighter-rouge">tutor</code> — when I want to go deep on a concept rather than just get an answer. Install: <code class="language-plaintext highlighter-rouge">npx skills add piyja/myAgentsSkills/skills/tutor</code></li> <li><code class="language-plaintext highlighter-rouge">system design</code> — when I’m designing a new system or architecture and want structured thinking from the agent</li> <li><code class="language-plaintext highlighter-rouge">grill-with-docs</code> — starts a challenge session against your plan, grounded in your actual domain docs. Excellent for stress-testing a design before committing to it</li> <li><code class="language-plaintext highlighter-rouge">superpowers</code> (Anthropic) — a collection of workflow primitives covering code generation, debugging, TDD, and more</li> </ul> <h2 id="tips-for-cost-effective-and-efficient-use-of-coding-agents">Tips for cost-effective and efficient use of coding agents</h2> <ol> <li><strong>Use plan mode first.</strong> High-level design before any code. Review and push back on the plan using your own engineering judgement — the agent is not always right.</li> <li><strong>Compact the context aggressively.</strong> When you’re approaching context limits, summarise and reset. Stale context degrades output quality.</li> <li><strong>Match model to task.</strong> Thinking and planning → heavy frontier model. Executing a clear plan → smaller, cheaper model.</li> <li><strong>Use skills.</strong> Don’t rebuild common workflows from scratch in every session.</li> <li><strong>Delegate plan execution to smaller models.</strong> A well-defined plan from a large model runs cleanly on a 12B. The quality gap closes fast when the task is well-specified.</li> <li><strong>Create session summaries.</strong> At the end of a long session, generate a structured summary and use it as context seed for the next one. Saves tokens, keeps the important decisions in scope.</li> </ol> <h2 id="where-i-spend-most-of-my-time-as-a-software-engineer">Where I spend most of my time as a Software Engineer</h2> <p>The biggest leverage I’ve found with coding agents is in <strong>abstract thinking and solution design</strong> — not code generation. The agent becomes a sparring partner for exploring the problem space: brainstorming approaches, debating trade-offs, thinking through edge cases. It’s a good rubber duck, but one that pushes back.</p> <p>The other place I invest heavily is <strong>test-driven development</strong>. Writing tests first forces you to think clearly about the problem before touching implementation. I use the agent to help write the tests, then write code to pass them. The loop is tighter and the designs come out cleaner.</p>]]></content><author><name></name></author><category term="Field Notes"/><category term="ai-engineering"/><category term="Agents"/><category term="Thoughts"/><category term="MLOps"/><summary type="html"><![CDATA[Practical patterns for working effectively with AI coding agents like Claude Code and Copilot]]></summary></entry><entry><title type="html">Review of Nvidia’s article on Agentic Design for Automotive</title><link href="https://piyja.github.io/blog/2026/Review-Agentic-Design-Automotive/" rel="alternate" type="text/html" title="Review of Nvidia’s article on Agentic Design for Automotive"/><published>2026-05-27T00:00:00+00:00</published><updated>2026-05-27T00:00:00+00:00</updated><id>https://piyja.github.io/blog/2026/Review-Agentic-Design-Automotive</id><content type="html" xml:base="https://piyja.github.io/blog/2026/Review-Agentic-Design-Automotive/"><![CDATA[<h2 id="about">About the article - <a href="https://developer.nvidia.com/blog/how-to-build-in-vehicle-ai-agents-with-nvidia-from-cloud-to-car/">How to Build In-Vehicle AI Agents with NVIDIA: From Cloud to Car</a></h2> <p>Nvidia’s DRIVE team recently published a blog post on developing in-vehicle edge AI agents. I wanted to share my notes on it here and add further thoughts about the critical focus areas from the lens of product strategy and user requirements. Since I am working in the automotive domain, I find it important to keep an eye on the developments in the industry and also to understand how the big players are thinking about the future of in-vehicle AI agents. We can hinge our product development on these key evaluation parameters and critical focus areas and develop a reliable and robust agentic AI systems.</p> <h3 id="arguments">Arguments made in the article - a quick analysis</h3> <ol> <li>As building AI models powered applications is becoming common we are shifting away from hard Rule-based programming and entering new phase in which we make use of the AI powered Agents, the so called agentic AI shift. As fixed command-response doesn’t scale well; LLMs/VLMs enable conversational AI with memory, reasoning, and proactive assistance.</li> <li>Although to get reliable output AI model requires a good amount of hardware acceleration. Real-time AI at the edge can be hard — if you have need to run 7B+ param models locally, preferably for multimodal use case. Importantly it also requires rethinking of the memory budget and not just the compute budget. The in cabin edge computation would require tight SLO/SLA of 400-500ms response time, &gt;30 tokens/sec, multimodal inputs (camera + audio + telemetry), all while preserving privacy of the users.</li> <li>The user experience for invehicle can be greatly enhanced by leveraging edge models with input from the cloud in form of compute, tools or peer agents. This blog talked about the hybrid cloud-edge architecture — Local agents for in-car tasks, cloud agents for use case like web/trip planning; key challenges would be here to correctly route intent, context sharing, and graceful degradation when the vehicle is offline.</li> <li> <p>The pipeline for agentic voice based assistants briefly contains this chain</p> <p><code class="language-plaintext highlighter-rouge">wake word -&gt; ASR -&gt; Orchestrator -&gt; LLM inference -&gt; Tools -&gt; TTS -&gt; audio output</code></p> <p>The orchestrator is the key component that routes user input to the right LLM, manages context, and handles fallback when the vehicle is offline. Nvidia’s NeMo Agent Toolkit serves as the glue for building, orchestrating and evaulating these agents.</p> </li> <li>For the OEMs, Nvidia comes with a hardware solution in 3 levels each with more commitment for AI ready hardware stack: <ul> <li>AI Box build with DRIVE AGX as a modular add-on to the existing IVI system providing a plug and play solution for AI agents without full E/E redesign. But the downside would be increased inter processor communication latency and potential bottlenecks.</li> <li>DRIVE AGX Thor taking the above solution further by utlizing blackwell GPUs serving a platform for AI workload for the whole vehicle</li> <li>A single central car computer fused with DRIVE AGX fused with the MediaTek Dimensity AX SoC - a fully integrated solution for infotainment and AI workloads, but would require more commitment to the new hardware architecture. Will have a great upside that latency for data communication will be the lowest but then again it would require a full redesign of the E/E architecture and software stack.</li> </ul> </li> </ol> <h3 id="critical-focus-areas">Critical focus areas for building in-vehicle AI agents</h3> <ol> <li> <p><strong>Specialised models for the voice pipeline</strong> — The 500ms-700ms end-to-end SLA is a budget distributed across every stage of the pipeline. Each arrow in <code class="language-plaintext highlighter-rouge">Wake Word → ASR → Orchestrator → LLM → TTS → Audio Output</code> carries a latency cost, leaving roughly 150ms per stage — which immediately constrains model size and quantization decisions at every step.</p> <p>Starting upstream: always-on wake word detection is a distinct engineering problem that precedes the ASR stage. It must run continuously on a low-power audio DSP with a near-zero false-positive rate — misfires while driving are both annoying and a safety distraction.</p> <p>For ASR, Mixture-of-Experts (MoE) architectures are well suited to automotive conditions because the acoustic environment is finite set of profiles (highway noise, HVAC, music, quiet cabin). MoE routing can specialise experts per acoustic profile, and the router can be conditioned on vehicle telemetry (speed as a proxy for road noise, HVAC state) before audio even arrives — proactive expert selection rather than reactive. The tradeoff: MoE models have a higher total parameter count even when only a fraction activates, so they require careful VRAM budgeting on edge hardware.</p> <p>For TTS, streaming token-by-token output directly to the audio renderer is the single highest-leverage latency optimisation available. The first audio chunk can begin playing while subsequent tokens are still being generated, cutting perceived response time significantly even if wall-clock total is unchanged.</p> <p>The orchestrator LLM also deserves specific attention: for a voice assistant context, its fine-tuning objective is fundamentally different from a general-purpose LLM. Inputs are short, intent-dense, and often acoustically degraded. The model needs to be optimised for rapid intent classification and slot filling. The reasoning part can be tricky and optional as we could have complex queries coming from user which would require reasoning over multiple tools. Alas we have to find a balance here.</p> <p>Finally, user feedback comes in three distinct forms with different pipeline implications: explicit (thumbs up/down), implicit (user rephrasing the same request after a failure), and behavioural (abandoning the interaction entirely). Treating all three as a single “feedback loop” leads to muddled improvement signals — each requires a different data pipeline and triggers different retraining decisions.</p> </li> <li> <p><strong>Platform scalability and the standardisation gap</strong> — We need automotive software standards that address agentic AI orchestration. AUTOSAR Adaptive has introduced ML model management interfaces, but we also need agent-to-agent communication contracts, tool calling interfaces, memory management for multi-turn context, or evaluation criteria for agentic behaviour. OEM-specific frameworks share the same gap and in my opinion this is a significant structural requirement for long-term scalability of in-vehicle AI agents.</p> <p>The cloud/edge routing question also carries a hard constraint that “location-agnostic” framing obscures: some tasks cannot be cloud-routed regardless of latency or connectivity, not for performance reasons but for safety and regulatory ones. An agent recognising a medical emergency must complete that interaction fully on-edge. Safety-critical voice paths and comfort/infotainment paths have fundamentally different routing requirements, fallback policies, and hardware resource allocations — treating them as a single routable workload is architecturally incorrect.</p> <p>Testing and evaluation for automotive voice agents cannot rely on general-purpose LLM benchmarks. What is needed — and does not yet exist as a public standard — is domain-specific evaluation covering: navigation command accuracy across real address formats, HVAC and media control intent parsing, multi-turn context retention under acoustic degradation, and regional language and accent coverage. Building such an evaluation framework is a prerequisite for any serious agent improvement programme.</p> </li> <li> <p><strong>Agents deep in the automotive software stack</strong></p> <p>Automotive software enforces hard partitioning between safety domains through a hypervisor managing multiple OSes simultaneously: typically a real-time OS for safety-critical functions, QNX or equivalent for high-availability services, and Linux for infotainment and AI workloads. An AI agent running in the Linux partition has no direct path to safety-critical vehicle functions — all communication must cross hypervisor guest boundaries via IPC or RPC, adding latency and introducing a new class of failure modes that must be explicitly designed against.</p> <p>The core tension is that LLM-powered flexibility is inherently non-deterministic, while Classic AUTOSAR at ASIL-D requires hard real-time determinism. These properties cannot be reconciled by pushing the LLM deeper into the stack. The practical architectural answer is that the LLM remains at the application layer and communicates intent downward through well-defined, auditable tool-calling interfaces — constrained API boundaries that enforce certifiable behaviour at the safety layer while allowing flexible reasoning above it.</p> </li> <li> <p><strong>Personalised and context-aware setup</strong> — Agentic setup offers means to highly personalise the setup as per the user and continuously improve the agents - dedicated pipelines can be designed to receive and store feedback from the user, handle errors, and continuous improvement of the agent’s performance in real-world conditions.</p> </li> </ol> <h3 id="closing">Closing points</h3> <p>Navigating this moving landscape of AI engineering and taking steps to create platform for building and iterating on AI agents in the future can be tough. But with wholistic design thinking and a user-product centric approach we can build system ready for the future. Finally the onus is on the decision making step - on deciding what to build!</p>]]></content><author><name></name></author><category term="Field Notes"/><category term="MLOps,"/><category term="MLSystems"/><summary type="html"><![CDATA[About the article - How to Build In-Vehicle AI Agents with NVIDIA: From Cloud to Car]]></summary></entry><entry><title type="html">Thinking as a PM (product) + SWE (Product Engineering)- Personal reflections</title><link href="https://piyja.github.io/blog/2026/Thinking-as-a-SWE-PM/" rel="alternate" type="text/html" title="Thinking as a PM (product) + SWE (Product Engineering)- Personal reflections"/><published>2026-05-18T00:00:00+00:00</published><updated>2026-05-18T00:00:00+00:00</updated><id>https://piyja.github.io/blog/2026/Thinking-as-a-SWE-PM</id><content type="html" xml:base="https://piyja.github.io/blog/2026/Thinking-as-a-SWE-PM/"><![CDATA[<h1 id="personal-reflections">Personal reflections on my journey as Design engineer</h1> <p>In the last weeks and months I have been reflecting on my journey as software engineer, how my formal studies of <a href="https://ed.iitm.ac.in/">Engineering Design</a> played a role into shaping my perspective as a engineer. I have been keeping this perspective in mind while working on various projects but recently thought of adding it here to keep it as live journal. On the high level these I have captured my reflections in the following sections. I started to work as product development engineer for embedded systems and transitioned into software engineering developing full software systems but still focusing on resource constraints embedded devices. I want to jot down some thoughts on how the background of design engineering helps me to think at layers of abstraction.</p> <h2 id="design-engineering">What is design engineering?</h2> <p>Design engineering involves amalgamating principles of different engineerings disciplines, understanding the <strong>user needs</strong>, the problem space and the <strong>solution space</strong>, and designing solutions that are not only technically sound but also user-friendly, scalable, and maintainable. It requires a deep understanding of the problem domain, abstract thinking in designing solutions, systems thinking and most importantly the ability to think holistically about the system being designed.</p> <h3 id="framework-abstraction">Provides a framework to think about problems and solutions at different layers of abstraction</h3> <ul> <li>Finding which problems to solve first, understanding the user needs and the business opportunity, etc. This helps in prioritizing the work and focusing on the most impactful problems to solve.</li> <li>Solutions thinking - from problem break down, targetted solutions and how to form strategies to tackle them. Holistically thinking about the system, the users, the problem space, the solution space, helps to understand the problems and solution space. Designing solutions weighing different trade-offs and considering different constraints.</li> <li>From the high level of abstraction - understanding the user needs, the problem space and the solution space, etc. This helps in not getting bogged down by the details and focusing on the bigger picture, understanding the dependencies between different components of the system.</li> <li>From the low level of abstraction - understanding the technical details, the constraints and trade-offs involved in building solutions, etc.</li> </ul> <h3 id="abstract-thinking">What is abstract thinking - how does it help in problem solving and solution design?</h3> <ul> <li>Abstract thinking involves looking at the problem from a high level of abstraction, understanding the problem space and the solution space, etc.</li> <li>This helps in not getting bogged down by the details and focusing on the bigger picture, understanding the dependencies between different components of the system, etc.</li> <li>Breaking down the problem into smaller subproblems, understanding the dependencies between them, etc.</li> </ul> <h2 id="design-as-asset">What ticks me and using this Design Engineering background as an asset</h2> <p>The framework discuss above helps lock the perspective towards owning the outcome (impact) of the work vs from the output perspective (know how and why from engineering).</p> <h3 id="journey">My journey into product development, embedded systems, and now in SWE. What is Software engineering to me?</h3> <ul> <li>In the early years of product development - exploring building blocks of engineering, understanding how things work, how they are built, etc. To dive deeper into the working of each I decided to understand the embedded systems - from PCB designs, hardware selection, firmware and driver development. This helped me to understand the working of the system at a deeper level and also understand the constraints and trade-offs involved in building solutions for embedded systems.</li> <li>Scaling those embedded systems both horizontally (across different product lines) and vertically (adding more features and capabilities) led me to software engineering. I started to work on building software solutions providing targeted solutions in form of platforms and modular designs to increase reusability and bring scale inherently into the design. This helped me to draw the design thinking into the software products and bring the abstract thinking into the software design and development process.</li> <li>To me software engineering is about building software products that are technically sound, user-friendly, scalable, and maintainable as it also involves understanding the problem space and the solution space. It is a building block of a system which works together with other building blocks to create a complete system.</li> </ul> <h3 id="pm-first">Thinking as a PM first and then SWE</h3> <ul> <li>Traits of a good PM - vision on what to build, understanding of the users and their needs, <strong>business value</strong> it generates, understanding of the problem space and the solution space, ability to drive the product development process.</li> <li>One crucial aspect which design engineering did not explicitly teach but I have learned over the years is the importance of <strong>business value</strong> and how it is crucial to understand the business value of the solutions we build. This is important to ensure that we are building solutions that aligns and generate value for the business and the users.</li> <li>Thinking as a PM first helps to understand who our customers are really, what are their problems and needs and then focus on solution development around them.</li> <li>How I fit this perspective into my work as a SWE - as every role has their customers - for a SWE the customers are the users of the software, the stakeholders who are impacted by the software and the business sense it drives</li> <li>Thinking from the design frameworks point of view - understanding the user needs, the problem space and the solution space, etc. helps to understand the problems and solution space. Designing solutions weighing different trade-offs and considering different constraints.</li> <li>There is a great overlap of this thought process with <strong>Software Architect</strong> roles who are usually responsible for designing the overall structure of the software system and greatly benefiting from the abstract thinking perspective and using the above framework.</li> </ul> <h2 id="future">What I am excited about in the future?</h2> <ul> <li>Future of software engineering and how it is coming towards product thinking</li> <li>Working as a SWE during the GenAI and agentic transformation <ul> <li>Helps one to think on higher level of abstraction</li> </ul> </li> <li>Building products that are powered by GenAI and agentic capabilities</li> </ul>]]></content><author><name></name></author><category term="Field Notes"/><category term="Thoughts"/><summary type="html"><![CDATA[In this post, I share my personal reflections on my journey as a design engineer and software engineer, and how I approach problems, think abstractly, and plan for the future.]]></summary></entry><entry><title type="html">Building Agentic Applications</title><link href="https://piyja.github.io/blog/2026/Making-Agentic-Applications/" rel="alternate" type="text/html" title="Building Agentic Applications"/><published>2026-05-16T00:00:00+00:00</published><updated>2026-05-16T00:00:00+00:00</updated><id>https://piyja.github.io/blog/2026/Making-Agentic-Applications</id><content type="html" xml:base="https://piyja.github.io/blog/2026/Making-Agentic-Applications/"><![CDATA[<h1 id="what-are-agentic-apps">What are agentic applications?</h1> <p>Agentic applications are softwares which builds around AI models to utilize it as a decision making and reasoning engine along with the tools and external systems it interacts with. AI models are used as the controller to this systems that can also trigger the actions based on the data and context it receives. This enables the applications to shift away from hard coded rules and logic increasingly making them more flexible, adaptable and intelligent.</p> <p>Before the agentic term was coined by Andrew Ng, Lilian Weng described such application in her blog “LLM Powered Autonomous Agents” in 2023. In her blog, she describes how LLMs can be used to build autonomous agents that can perform complex tasks by breaking them down into smaller sub-tasks and delegating them to different agents or tools. Here in this blog we are building on the ideas which Lilian pitched had already picthed and have become standard to develop agentic applications today but also going to add more structure, design principles and learning from the community over this time.</p> <h2 id="benefits">Benefits of agentic applications</h2> <p>Agentic applications utilises the power of AI models more effectively. By building around the AI models, agentic applications can leverage the models’ ability to learn from data and adapt to new situations, making them more flexible and adaptable than traditional applications. This allows for more complex and sophisticated applications that can handle a wider range of tasks and scenarios. It also allows the applications to be not hard coded and rule based anymore.</p> <h2 id="core-components">Core components of an agentic application</h2> <p>Agentic applications typically consist of several core components that work together to enable the application to function autonomously. These components include:</p> <ol> <li>AI models and inference server layer - the core reasoning engine which comprehends and derives meaning from the application <ul> <li>This is the core component of the agentic application which is responsible for understanding the context, making decisions and generating responses based on the data it receives. The AI model can be a large language model (LLM) or any other type of AI model that is suitable for the task at hand. The inference server layer is responsible for managing the communication between the AI model and the other components of the application, as well as handling the inference requests and responses.</li> </ul> </li> <li>Reasoning and task planning module <ul> <li>Reasoning step is the most crucial step where the AI model thinks about the task at hand and generates a plan of action to achieve the desired outcome. This can be steps like breaking down the task into smaller sub-tasks, identifying the tools and resources needed to complete the task, and determining the best course of action to take.</li> <li>Task decomposition step - methods which breaks down complex tasks into smaller sub-tasks to be delegated to different agents or tools in the system. This can involve techniques such as hierarchical task decomposition, where tasks are broken down into a hierarchy of sub-tasks, or flat task decomposition, where tasks are broken down into a flat list of sub-tasks.</li> </ul> </li> <li>Orchestrator layer and agent loop architecture - the system that manages the flow of information and tasks between the AI model, task decomposer, tools, other agents and evaluate results. <ul> <li>The react loop of observe → think → act → observe again. This sits at the heart of the application and is responsible for ensuring that the different components cordinates and communicates seamlessly to achieve the desired outcomes.</li> <li>Together with the reasoning step this forms the basis for ReAct (Reasoning and Acting) pattern which is widely used in agentic applications</li> </ul> </li> <li>Taking actions via tools - the external systems and APIs that the AI model can interact with the external world by performing actions and gather information <ul> <li>Tool usage can be triggered by the reasoning module or can be hard coded for specific tasks. For example, if the task is to book a flight, the reasoning module can trigger the use of a flight booking tool to complete the task.</li> <li>Standards used for tool usage and integration - A2A protocol, MCP servers, etc. which allows to scale and develop such tools independently and also share them across different agents in the system</li> <li>Each agent can use multiple tools at a time and also share tools with other agents in the system</li> </ul> </li> <li>Context management - system which decides how to prune vs summarize the stored cache used for the session data <ul> <li>Context is basically what the AI model can see right now, as inherently models are stateless and every call must contains all the details required by it to generate the output.</li> <li>What does the current context contain? <ul> <li>system prompt</li> <li>retrived data</li> <li>recent messages</li> <li>tools and it’s output</li> </ul> </li> <li>As the context can grow linearly over time, we need strategies to trim or summarize it. Common techniques include sliding window, summarize-and-compress, hierarchical isolation, etc.</li> </ul> </li> <li>Memory - unlike context here the context data is stored for future use by the models as well as read for current inference cycle <ul> <li>Short term memory - the system that stores the information and context for the AI model to use in its decision making process over a short period of time</li> <li>Long term memory - the system that stores the information and context for the AI model to use in its decision making process over a long period of time</li> <li>External memory and knowledge base stored as vector embeddings or more recently graph database are gaining popularity as the long term memory for the AI models</li> </ul> </li> <li>Data and evaluation metrics pipeline - the system that collects, processes and feeds data to the AI model <ul> <li>This can include data from user interactions, tool usage, and other sources that can be used to train and improve the AI model over time. It also includes the evaluation metrics that are used to measure the performance of the AI model and the overall system. This can include metrics such as accuracy, precision, recall, F1 score, etc. which are used to evaluate how well the AI model is performing on the tasks it is designed to handle.</li> <li>Heuristic-based agents - Heuristics means the rules of thumb, the mental shortcut a pragmatic engineer would take while designing a product. These are agents that are designed to follow a set of predefined rules or heuristics to make decisions and take actions. These agents can be useful in situations where the task is well-defined and can be easily codified into a set of rules. However, they may not be as flexible or adaptable as AI model-based agents, which can learn from data and adapt to new situations. <ul> <li>rule-based systems</li> <li>expert systems</li> <li>decision trees</li> <li>finite state machines</li> </ul> </li> <li>Chain of hindsight - the system that collects feedback from users and other sources to improve the performance of the AI model over time. This can include techniques such as reinforcement learning, where the AI model learns from the feedback it receives to improve its performance on the tasks it is designed to handle. Chain of hindsight is a technique where the AI model can learn from its past mistakes and successes by analyzing the outcomes of its actions and using that information to improve its future decision making process.</li> </ul> </li> <li>Trust &amp; safety boundaries — one of the most critical design concerns in agentic systems. How do you constrain what an agent can do? Sandboxing, permission scopes, human-in-the-loop checkpoints. irreversible action guards. <ul> <li>This is a crucial aspect of designing agentic applications, as it is important to ensure that the AI model does not take actions that could be harmful or unethical. This can be achieved through techniques such as sandboxing, where the AI model is isolated from the rest of the system and can only interact with it through a controlled interface, or through permission scopes, where the AI model is only allowed to access certain resources or perform certain actions based on predefined rules. Additionally, human-in-the-loop checkpoints can be used to allow for human oversight and intervention in critical decision-making processes.</li> </ul> </li> </ol> <h1 id="multi-agent">Developing application with Multi-agent</h1> <h2 id="why-multi-agent">Why do we need multiple agents in an application?</h2> <p>Inorder to maintain separation of concerns and make expert modules for different tasks, it is advices to have multiple agents in an application. This allows for better modularity, scalability and maintainability of the application. Each agent can be designed to specialize in a specific task or domain, allowing for more efficient and effective performance. Although it add challenges on the communication and task orchestration between the agents, it is a trade off worth making for the benefits it provides.</p> <h2 id="design-principles">Design principles for multi-agent systems</h2> <ul> <li>Modularity - each agent should be designed to specialize in a specific task or domain, allowing for better modularity and separation of concerns</li> <li>Communication - communicate and share information effectively to achieve the desired outcomes</li> <li>Coordination - coordinate their actions and tasks to achieve the desired outcomes</li> <li>Scalability - scale as the number of agents and tasks increases</li> <li>Robustness - handle failures and errors gracefully by retry/fallback/partial-pass/escalate mechanisms</li> </ul> <h2 id="orchestration-patterns">Orchestration patterns for multi-agent systems</h2> <h3 id="decision-control">Decision Control Patterns</h3> <ul> <li>Centralized orchestration - a single orchestrator agent manages the flow of information and tasks between the different agents in the system. This can be simpler to implement but may become a bottleneck as the number of agents increases.</li> <li>Decentralized orchestration - each agent is responsible for managing its own tasks and communication with other agents. This can be more complex to implement but can provide better scalability and robustness.</li> <li>Hybrid orchestration - a combination of centralized and decentralized orchestration, where some agents are responsible for managing their own tasks and communication, while others are managed by a central orchestrator. This can provide a balance between simplicity and scalability.</li> </ul> <h3 id="flow-control">Flow Control Patterns</h3> <ul> <li>hierarchical orchestration - agents are organized in a hierarchical structure, where higher-level agents manage the flow of information and tasks between lower-level agents. This can provide better modularity and separation of concerns but may require more complex communication and coordination between agents.</li> <li>peer-to-peer orchestration - agents communicate and coordinate directly with each other without a central orchestr ator. This can provide better scalability and robustness but may require more complex communication and coordination between agents.</li> <li>event-driven orchestration - agents communicate and coordinate based on events and triggers, allowing for more flexible and dynamic interactions between agents. This can provide better adaptability and responsiveness but may require more complex event management and coordination between agents.</li> <li>pipeline orchestration - agents are organized in a pipeline structure, where the output of one agent serves as the input for the next agent in the pipeline. This can provide better modularity and separation of concerns but may require more complex communication and coordination between agents.</li> </ul> <p>I hope this gives a good overview of the moving parts and design principles for building agentic applications. As the state of the art of this field is evolving rapidly, I will keep updating this post with new learnings and insights from the community. If you have any suggestions or feedback, please feel free to reach out!</p>]]></content><author><name></name></author><category term="Field Notes"/><category term="MLOps"/><summary type="html"><![CDATA[In this post, we will explore the concept of agentic applications, their design principles, and how they can be leveraged to create more autonomous and intelligent systems.]]></summary></entry><entry><title type="html">Book Review Building Secure Cars</title><link href="https://piyja.github.io/blog/2024/Book-review-Building-Secure-Cars/" rel="alternate" type="text/html" title="Book Review Building Secure Cars"/><published>2024-05-05T00:00:00+00:00</published><updated>2024-05-05T00:00:00+00:00</updated><id>https://piyja.github.io/blog/2024/Book-review-Building-Secure-Cars</id><content type="html" xml:base="https://piyja.github.io/blog/2024/Book-review-Building-Secure-Cars/"><![CDATA[<h2 id="how-i-found-it">How I got around the book</h2> <p>On the quest of learning the horizontals topics in automotive software, I found myself willing to know more about the security features and measures used in automotive software development. As developer within the infotainment business of the automotive I find security as growing requirement as the capabilities of it are ever-growing. Infotainment Electronic Control Units (ECUs) have emerged as potent components within vehicles, often handling critical functionalities. My expectation from the book was to gain insights into how security is intricately woven into the software development lifecycle. I anticipated learning about various security features implemented in automotive systems, as well as the diverse types of security testing conducted. This knowledge would not only enrich my understanding of current practices but also equip me with the necessary tools to navigate and contribute effectively within the humungous landscape of automotive software development.</p> <h2 id="learnings">What did I learn from the book</h2> <p>The author effectively underscores the critical importance of security and adeptly caters to newcomers by providing detailed explanations. While seasoned professionals may find some concepts verbose, this approach ultimately deepens understanding. Key concepts that stood out and are worthy of highlighting are mentioned in the below part of the blog:</p> <h3 id="importance-of-security">Importance of security in automotive</h3> <p>Given the rapid evolution and increasing complexity of modern vehicles following are points which state why software security is crucial:</p> <ol> <li>Growing Capabilities and Dependency on Software: Modern vehicles are becoming increasingly sophisticated, relying heavily on software to manage everything from basic functions to advanced features like autonomous driving. This growing dependency means that the integrity and security of the software are paramount.</li> <li>Increased Code Complexity and Potential Vulnerabilities: As the amount of code within a vehicle’s systems increases, so does the potential for vulnerabilities. More lines of code create more opportunities for bugs and security flaws, making robust security measures essential.</li> <li>Elevated Risk Factors: With the introduction of more capabilities, the risk associated with potential vulnerabilities also rises. Security breaches can have severe consequences, affecting not only the vehicle’s functionality but also the safety of passengers and pedestrians.</li> <li>Necessity for Updated Security Features and Testing: The dynamic nature of automotive technology demands the most current security features to protect against emerging threats. Regular and thorough security testing is crucial to identify and address vulnerabilities early in the development process, ensuring that vehicles remain secure against potential attacks.</li> </ol> <h3 id="static-approaches">How can we make automotive more secure - Static approaches</h3> <h4 id="secure-hardware">Secure hardware solutions</h4> <p>Hardware solutions play a crucial role in enhancing the security of automotive software by enabling privileged access to applications and ensuring the integrity of the system. Key hardware-based security features include secure boot, secure flash, secure log, and secure debug. These mechanisms ensure that only authorized software can run on the vehicle’s systems, protecting against unauthorized access and tampering.</p> <p>Additionally, trust-based systems can be implemented to physically isolate sensitive data and manage secure connections. This can be achieved through secure trust zones, which create a dedicated and protected environment within the hardware. These secure zones store sensitive information and control access using robust security protocols, thereby enhancing the overall security posture of the automotive system. By leveraging these hardware security measures, automotive manufacturers can provide a more secure and resilient platform for their vehicles, safeguarding against a wide range of potential threats.</p> <h4 id="sca-oss">Software composition analysis of open source components</h4> <p>Software composition analysis involves understanding the various components that make up an application and the dependencies it relies on. By thoroughly analyzing the composition of your software, you can identify all the open-source components integrated into your application. It helps in recognizing known vulnerabilities and flaws associated with these open-source components. Many open-source libraries and modules have publicly documented security issues, and being aware of these can prevent the introduction of potential security risks into your software. It enables proactive management of software updates and patches, ensuring that any vulnerabilities discovered in the open-source components are promptly addressed. It also supports compliance with industry standards and regulations, thereby contributing to the creation of a secure and reliable automotive software environment.</p> <h4 id="static-code-analysis">Static code analysis (SCA)</h4> <p>Static code analysis (or linters) are means of checking software code for abiding to the coding standards by parsing the source code. These checks are run without executing the code on the software code base. The checks are not just on a particular statement or definition but can also detect issues in a block of related source code. It can find both syntactic and semantic code violations within the code base. Specific to automotive industry some consortiums have developed coding standards to be followed in automotive software, like <a href="https://misra.org.uk/">MISRA</a> and <a href="https://www.autosar.org/fileadmin/standards/R22-11/AP/AUTOSAR_RS_CPP14Guidelines.pdf">AUTOSAR</a>. There are many open sources projects which offers many of these standards included in the SCA tooling software. As well there few proprietary software like, <a href="">Coverity</a> covers about the majority of the coding standards into their linter and has about 400 coding guidelines which it covers. These standards are split in categories of severeness - mandatory, required and advised. For safety related code within automotive there are stricter guidelines which are covered in ASIL-D &lt;(ISO, SIL B-C??)&gt; coding standards. Not all software component would need to abide by all coding standards and can be configured according to the functional severity. Albeit, one thing is worth mentioning some violations could be false positive and there are provisions to bypass this and allow deviations case by case, although this requires human code review.</p> <p>For the legacy code where we would get unmanageable amount of code violations at first, one has to set up a framework to be able to introduce this gradually into the full working. This could mean segregation of the software components based on the functional severity and enabling the coding guidelines as per this severity. Then case by case going through the violations to identify which ones should be resolved at a priority hierarchy.</p> <h3 id="dynamic-approaches">How can we make automotive more secure</h3> <h4 id="shift-left">By Shifting left</h4> <p>By introducing security testing approaches in the (software development V cycle)[] we can bring more robustness into the software. These testing can be performed in the cycle to expose vulnerability earlier and to avoid making security being an afterthought at the verifications step.</p> <h4 id="tara">Theoretical Approach</h4> <p>Theoretical approaches like Threat Analysis and Risk Assessment (TARA) can prove to be a beneficial starting step to analyze the software. It involves identifying the assets and threat scenarios and creating risk assessment of the identifies threats. It proves to be greatly beneficial if carried out multiple times in the development cycle. The final output of this analysis is list of identifies threats and associated risks with it which can be sorted by their priorities. There are good open source tools like (pyTM)[https://github.com/izar/pytm] which can be used create a graphical output of the analysis using graphviz. Albeit, TARA would also be classified as a static approach in identifying threats.</p> <p>To make automotive more secure, more than static approaches are essential, by dynamic I mean in which we emulate close to actual use case of the automotive systems. From testing point of view this involves controlling the external environment for the system under test (SUT) and monitoring its behavior. In the following section we will see more about them.</p> <h4 id="practical-testing">Practical testing approaches</h4> <p>Practical testing approaches can be divided into following sections:</p> <h5 id="functional-security-testing">Functional security testing</h5> <p>Akin to system function testing, the focus is on validating the effectiveness of essential security functionalities. This encompasses rigorous testing of critical security features integrated into the communication stack, such as SecOC (Secure Onboard Communication), and evaluating standard encryption mechanisms applied to cryptographic algorithms for handling sensitive data. Additionally, assessing the reliability and performance of components like the true random generator is vital.</p> <h5 id="vulnerability-testing">Vulnerability testing</h5> <p>In vulnerability testing, the initial phase involves comprehensive information gathering focused on understanding the system’s core components. This process employs various scanning techniques from multiple perspectives to thoroughly examine the software. Communication ports are scanned to identify potential vulnerabilities, while configurations used within the software are meticulously scrutinized. Additionally, critical details such as the communication protocols utilized by the target system are analyzed to gain deeper insights into its operational structure. Once these key components are identified, the next step involves gathering and analyzing potential threats. This proactive approach ensures that developers can anticipate security risks early in the development process, thereby integrating robust defensive measures into the automotive software.</p> <h5 id="fuzz-testing">Fuzz testing</h5> <p>Fuzz testing is a method used to evaluate the behavior and robustness of an application by providing randomly generated data as input and observing how the system responds. It is highly adaptable, with no single fixed approach and also incorporate model-based input generation, which systematically produces random data inputs to enhance the testing process. This technique is instrumental in identifying vulnerabilities and weaknesses within the software.</p> <p>A typical fuzz testing setup involves three main components:</p> <ul> <li>Engine: Responsible for generating randomized inputs.</li> <li>Injector: Introduces these inputs into the application under test.</li> <li>Monitor: Observes and checks the application’s behavior for any anomalies or crashes.</li> </ul> <p>There are three main types of fuzz testing:</p> <ul> <li>Black Box Testing: Testers have no knowledge of the internal workings of the application. Inputs are generated and injected without any insight into the system’s internals.</li> <li>Grey Box Testing: Involves partial knowledge of the system, allowing testers to create more informed and targeted inputs while still retaining some randomness.</li> <li>White Box Testing: Testers have full knowledge of the system, enabling them to create highly specific and strategic inputs to probe for vulnerabilities. The author covers fuzz testing in great detail across many chapters of the book. This comprehensive exploration provides a deeper understanding of how fuzz testing can be effectively employed to enhance the security and reliability of automotive software. We will cover key information here in the blog but for more detailed explanations and advanced topics on fuzz testing, refer to the later sections of the book.</li> </ul> <h6 id="testing-classic-autosar">Testing classical AUTOSAR components</h6> <p>“Shifting-left” approach in the software development <a href="https://en.wikipedia.org/wiki/V-model_(software_development)">V model</a> pushes us to integrate testing earlier in the development process to identify and resolve issues sooner. Owning to the vast security knowledge coming from IT industry, testing automotive specific CAN protocol based Classic AUTOSAR components can be particularly challenging, necessitating the use of Hardware-in-the-Loop (HIL) testing to ensure thorough and accurate validation. HIL testing involves two primary types of result monitoring:</p> <ul> <li>White Box Testing: This approach involves monitoring the internal states of the System Under Test (SUT). It provides detailed insights into the internal workings and allows for the identification of specific issues within the system’s components.</li> <li>Black Box Testing: In this method, the overall behavior of the system is monitored without focusing on its internal states. Usually in the case system’s performance is compared against an identical reference behavior to ensure it operates as expected.</li> </ul> <p>The integration of HIL in fuzz testing offers significant benefits, particularly in terms of quality of the feedback. By simulating real-world conditions we can get the closer to real life feedback from the hardware interactions, which helps in identifying and catching exceptions that might not be evident through software-only testing. This approach leads to the development of more robust and reliable automotive software, ensuring the system meets the stringent requirements of modern automotive applications.</p> <h6 id="testing-os-services">Testing Services Within Operating Systems (OS)</h6> <p>As automotive software becomes increasingly complex with the integration of custom OS, it is essential to adapt our testing strategies accordingly. One effective approach is white box fuzz testing, which employs agents to monitor and capture detailed information about various processes composed in the automotive OS. These agents track critical OS details such as memory corruptions (e.g., use-after-free errors), heap and stack checks, initialization order problems, memory leaks, core dumps, process monitoring, system logs etc.</p> <p>External agents play a significant role in monitoring the communication layer, including protocols like Bluetooth, WiFi, MQTT, and file formats. This comprehensive monitoring helps in identifying vulnerabilities and ensuring the robustness of the automotive software.</p> <p>There are two primary types of monitoring methodologies:</p> <ul> <li>Asynchronous Monitoring: random inputs are provided without waiting for corresponding results. The advantage of asynchronous monitoring is the speed at which results are delivered. However, the downside is that there are fewer options for tracking and tracing the outcomes, which can make it harder to diagnose issues.</li> <li>Synchronous Monitoring: This method involves waiting for the results of each input action before proceeding to the next which cause delays. The main advantage of synchronous monitoring is that it allows for easy tracking and tracing of results, making it simpler to identify and resolve issues.</li> </ul> <h5 id="penetration-testing">Penetration testing</h5> <p>Penetration testing is a crucial security evaluation performed in the final stages of product development. Its primary objective is to identify and exploit potential vulnerabilities within the system to understand how it might fail under various attack scenarios. This type of testing requires detailed understanding of the system to create situations that could lead to application failures.</p> <ul> <li> <p>Black Box Testing: In this approach, the tester has an understanding of the system behavior but no insider knowledge of its internal workings. The tester uses this information to attempt to exploit the system, identifying vulnerabilities that an external attacker might find.</p> </li> <li> <p>White Box Testing: This method involves the tester having comprehensive insider knowledge of the system. While it can be debated how realistic such attack scenarios might be, this approach is invaluable for understanding the risks associated with internal threats. By leveraging detailed system information, testers can perform more targeted and thorough security assessments.</p> </li> </ul> <p>Penetration testing provides a holistic view of the system’s security posture, helping developers identify and mitigate potential risks before the product is released. This ensures that the releases are more robust and resilient against potential attacks.</p> <h4 id="robust-frameworks">Robust frameworks are required</h4> <p>While various tests are crucial for proving the robustness of a system, merely having test suites is insufficient. To ensure comprehensive security testing throughout the product development and maintenance lifecycle, a robust framework is essential. Such a framework provides a systematic approach to security testing, ensuring that all aspects of the system are thoroughly evaluated, and any potential vulnerabilities are addressed promptly. A robust framework must contain following steps: Analyse the problems, set the goals, Identify the current state, define strategy to archive goals and execution.</p> <h3 id="continuous-monitoring">Continuous monitoring</h3> <p>Performing security tests once is not sufficient to ensure the ongoing robustness and security of automotive software systems. Continuous monitoring is essential to maintain a high level of security and quickly identify and address new vulnerabilities as they arise. Such a system continuously monitors the application and its environment for potential security threats and anomalies. This approach ensures that any new vulnerabilities or changes in the system’s behavior are detected promptly, allowing for immediate corrective actions.</p> <p>Hope you enjoyed reading the blog and learned new concepts about security testing. If this blog intrigued I would recommend diving further into the book.</p>]]></content><author><name></name></author><category term="Field Notes"/><category term="Automotive,"/><category term="Security"/><summary type="html"><![CDATA[Book review - Building secure cars - Assuring the Automotive Software Development Lifecycle - by Dennis Kengo Oka]]></summary></entry><entry><title type="html">Why Automotive Software Is Moving Towards Adaptive Autosar</title><link href="https://piyja.github.io/blog/2024/Why-Automotive-Software-is-moving-towards-Adaptive-Autosar/" rel="alternate" type="text/html" title="Why Automotive Software Is Moving Towards Adaptive Autosar"/><published>2024-03-27T00:20:00+00:00</published><updated>2024-03-27T00:20:00+00:00</updated><id>https://piyja.github.io/blog/2024/Why-Automotive-Software-is-moving-towards-Adaptive-Autosar</id><content type="html" xml:base="https://piyja.github.io/blog/2024/Why-Automotive-Software-is-moving-towards-Adaptive-Autosar/"><![CDATA[<p>In the last few days, I dedicated some time to learning about the Adaptive AUTOSAR (AA) platform. Anticipating the course of automotive software development, it becomes important to understand the problems that AA aims to solve. In the past, our team worked closely with AA to develop a consumer service application that provided some sensitive data, but the inner workings of the platform were still to be explored. The challenge in understanding AA was in the multilevel workflow from modeling the system and deployments to finally developing the applications. Wrapping one’s head around the complete process is a time-consuming task. In a functional automotive project, there are teams working on each level of this development work, which together execute the complete process. In the following sections, I have jotted down important points to gain a high-level understanding of AA.</p> <p>Before delving more into AA, let’s understand more about AUTOSAR and its developments before AA.</p> <h2 id="autosar-consortium">What is the AUTOSAR Consortium?</h2> <p>The <a href="https://www.autosar.org/">AUTOSAR Consortium</a> is a joint effort from leading automotive industry companies to create and define open system architecture standards for automotive. This includes not only providing a standardized software architecture and framework, but also the base standards for E/E architecture. It’s fascinating to see how competitive automobile companies have come together to create unified standards and pave the road for future developments.</p> <h3 id="software-standards">So, what software standards are they?</h3> <ul> <li><em>Foundation standards</em> - created to ensure a high degree of interoperability between components of AUTOSAR platforms, i.e., Adaptive and Classic, as well as within AUTOSAR to non-AUTOSAR platforms.</li> <li><em>Platform standards</em> - like Classic and Adaptive AUTOSAR standards. More on this in the following sections of the article.</li> <li><em>Application interfaces</em> - introduced various standardization processes for the communication protocols, syntax, and semantics for all applications to communicate in commonly understood terms.</li> <li><em>Acceptance test packages</em> - various standards are set for system tests to ensure the developed applications comply with the set standards.</li> </ul> <h3 id="classic-autosar">More about Classic AUTOSAR</h3> <p>The main purpose of Classic AUTOSAR is to achieve hardware and platform independence for AUTOSAR applications. The underlying layers of software are more dedicated to the type of hardware and platform. AUTOSAR provides a runtime environment (RTE), which is a software abstraction layer that the application software uses to work with hardware-oriented basic software (BSW). AUTOSAR also provides standardization guidelines for this BSW layer. Along with this, it has introduced common methodologies for configuring the AUTOSAR stacks.</p> <p>Classic AUTOSAR provides the base format for integrating a new ECU into the vehicle network. It mainly addresses the signal-based approach of communication, i.e., <a href="https://en.wikipedia.org/wiki/CAN_bus">CAN bus</a>, <a href="https://en.wikipedia.org/wiki/Local_Interconnect_Network">LIN bus</a>, etc. With this approach, endpoints can be easily configured with config files without changing the application software. However, for an update in the software component, an update of the entire ECU firmware is essential, which is a major drawback. Another disadvantage is that adding a new ECU usually requires a major change in the schema.</p> <p>However, in the following sections, we will see how Adaptive AUTOSAR overcomes these challenges and at what cost.</p> <h2 id="understanding-adaptive-autosar">Understanding Adaptive AUTOSAR</h2> <h3 id="why-adaptive-autosar">Why are automotive software components moving towards Adaptive AUTOSAR?</h3> <p>As more compute-demanding features like ADAS and V2X are being integrated, the number of ECUs and the computational capacity of the ECUs in automotive have been continually growing. This poses a challenge for designing the communication between these endpoints. Adaptive AUTOSAR (AA) proposes to integrate domain-specific high-performance ECUs in the vehicle to serve as a gateway for communication into each domain. Smaller footprint embedded ECUs directly connect to their respective domain’s high-performance ECU in order to communicate with the entire vehicle network. Another advantage of an AA application is that it can be configured and integrated into the system at runtime. This allows a number of independent services to be developed, tested, and deployed as applications independently.</p> <h3 id="communication-change">Embracing the change in the <strong>way of communication</strong> between the software components</h3> <p>As we have seen, there is increased usage of gateway ECUs to enhance the efficiency of the vehicle network. These domain ECUs manage the communication with smaller ECUs using a signal-based protocol and communicate with other domain ECUs using IP-based protocols to form a <a href="https://www.vector.com/int/en/know-how/autosar/autosar-adaptive/#c122761">domain controller architecture</a>. This allows more sophisticated frameworks like <a href="https://en.wikipedia.org/wiki/Service-oriented_communications">service-oriented communication</a> to be possible in automotive software. These services can be either servers (data providers or provider ports) or clients (data consumers or required ports) and communicate in the following ways for any data transfer:</p> <ul> <li>Direct method calls</li> <li>Event-based communication</li> <li>Topic or Data field subscription</li> </ul> <p>The system design manifest files define how these servers and clients are laid out in the E/E architecture. An application developer can use both <a href="https://en.wikipedia.org/wiki/Inter-process_communication">IPC</a> or <a href="https://en.wikipedia.org/wiki/Remote_procedure_call">RPC</a> method calls to a known service in the same manner without knowing the underlying modes of communication. AA also uses what is commonly known as the <a href="https://en.wikipedia.org/wiki/Service_discovery">“Service Discovery”</a> mechanism to keep track of up and running services offered on the vehicle network.</p> <h3 id="adaptive-autosar-architecture">Adaptive AUTOSAR Architecture</h3> <p>The Adaptive AUTOSAR (AA) software middleware stack can be thought of as a broader and wider design than Classic AUTOSAR, also known as AUTOSAR Runtime for Adaptive Applications (ARA). The modules within the ARA can be accessed through the <code class="language-plaintext highlighter-rouge">ara::</code> namespace within C++ applications and are platform-agnostic. The AA application uses ARA modules and sits at the top of the software architecture block designs, while the hardware drivers, hypervisors, and container modules sit at the bottom of the ARA components. The following is a non-exhaustive list of modules that ARA offers:</p> <ul> <li>Core platform services <ul> <li>Network</li> <li>State management, etc.</li> </ul> </li> <li>Platform foundation <ul> <li>Communications stack</li> <li>Persistency</li> <li>Logging and trace</li> <li>Platform health, etc.</li> <li>Includes all PSE51 POSIX APIs provided by the OS</li> </ul> </li> </ul> <h3 id="process-workflow">Process Workflow and Modelling for AA Applications</h3> <p>The process workflow for developing AA applications consists of modelling, auto-generating source code, and then developing the application software. The modelling steps involve filling in the details of the manifest files, which are then used to develop the auto-generated source code. Manifest files are divided into the following three parts:</p> <ul> <li>System design</li> <li>Machine and execution level</li> <li>Deployment level</li> </ul> <h3 id="what-is-adaptive">So, what is <strong>adaptive</strong> about Adaptive AUTOSAR?</h3> <p>While learning about AA topics, many of us have queries centered around this question. I will attempt to explain this in my own words.</p> <p>Adaptive AUTOSAR (AA) provides a platform for applications to become platform-agnostic. This means that the applications developed are not constrained to a particular platform or hardware type, as it separates configurations from the application software. It uses manifest files in the form of JSON extensions, which are configured alongside the application being developed. The final binary flashed onto the ECUs contains the application binaries and deployment configuration manifest files. These manifest files also define the service and client endpoint definitions, allowing for dynamic runtime linking between them for communication.</p> <p>As we also saw earlier in this article how independent features can be divided into AA applications or services. These applications can be also tested and deployed into the ECUs making it a very easy process to roll out any AA updates into the vehicle as opposed to completely re-flashing the ECU software. This adds a lot of agility into the AA applications.</p> <h3 id="safety-critical">Do you have safety-critical or hard real-time requirements for your applications?</h3> <p>As AA applications run on the ARA platform, which is capable of keeping the soft real-time requirements, it is not completely reliable for the hard real-time requirements. For example, engine control and brake systems. If the application’s requirement is to provide safety-critical features such as air-bag ECUs, it is recommended to use classic AUTOSAR applications. However, for safety features which are not specified as hard-real time, AA applications can achieve up to ASIL-B (these days also ASIL-D) using the safety libraries provided by different vendors. As Classic AUTOSAR application does not need an OS to run, its bootup time is also quite less compared to AA applications.</p> <h2 id="criticisms">Technical criticisms on AUTOSAR</h2> <p>Every design decision has a trade-off associated with it. AUTOSAR standards have used an approach of “one solution fits all”, making it form a heavy footprint software stack. This causes application sizes to bloat up. In very resource-constrained embedded environments, this application may not be the right choice and more targeted applications could do a better job. There are many <a href="https://medium.com/volvo-cars-engineering/the-reality-of-autosar-and-the-way-forward-36af39ec4099#:~:text=One%20of%20the%20biggest%20problems,of%20OEM%2Dspecific%20software%20applications">criticisms</a> on AUTOSAR and a lot of development entities are looking for alternative approaches.</p> <h2 id="further-words">Further Words</h2> <p>For full disclosure, I have been learning about AA from detailed training courses from <a href="https://www.vector.com/int/en/">Vector</a> in the last few days, where we delved into the implementation details of Vector’s AUTOSAR products.</p> <p>I hope you now have a high-level understanding of AUTOSAR, what AA is, its motivation for existence, and how AA applications are used in automotive.</p>]]></content><author><name></name></author><category term="Field Notes"/><category term="Automotive"/><summary type="html"><![CDATA[What is adaptive about Adaptive AUTOSAR?]]></summary></entry><entry><title type="html">Book Review Fundamentals Of Software Architecture</title><link href="https://piyja.github.io/blog/2024/Book-review-Fundamentals-of-Software-Architecture/" rel="alternate" type="text/html" title="Book Review Fundamentals Of Software Architecture"/><published>2024-03-09T00:20:00+00:00</published><updated>2024-03-09T00:20:00+00:00</updated><id>https://piyja.github.io/blog/2024/Book-review-Fundamentals-of-Software-Architecture</id><content type="html" xml:base="https://piyja.github.io/blog/2024/Book-review-Fundamentals-of-Software-Architecture/"><![CDATA[<h1 id="why">Why did I pick this book?</h1> <p>Coming from a product design background and writing software in embedded products, curiosity drives me to go beyond software design and development layers. Just like any hardware-based product, software products are an amalgamation of different software principles. This natural curve opened an opportunity for me to take on architectural tasks within the scope of my development activities. Offlate I have been getting involved at the system level components and piecing out the different information points into the system architecture. To take this further into streamlined learning, it is impossible not to stumble upon the famous book - <a href="https://fundamentalsofsoftwarearchitecture.com/">Fundamentals of Software Architecture by Mark Richards and Neal Ford</a>.</p> <p>In the following part of this article, I have tried to give you a brief introduction to the book and give you my personal learnings from it. This article is purely for academic purposes and is part of my contribution to the software community world. If this interests you, I would highly recommend reading the book further.</p> <h1 id="structure">Structure of the book</h1> <p>This book is written in three independent sections to cover the holistic view of software architecture.<br/> <em>Part I</em>: Covers the foundation of the software architecture, defining it and breaking it down into its core blocks. It also covers means of identifying, measuring, and governing architectural characteristics.<br/> <em>Part II</em>: Here it covers different architectural designs and assessment of the characteristics of it in star rating format.<br/> <em>Part III</em>: Then it talks techniques and the soft skills to be an effective architect. Author talks about recording architectural decisions - on useful methods and tools to do it.</p> <p>Following are the key highlights I have noted and written in my words.</p> <h1 id="what-is-software-architecture">What software architecture is about?</h1> <h2 id="defining-architecture">Defining the architecture</h2> <p>On the same lines of Martin Fowler’s definition in his famous article <a href="https://martinfowler.com/ieeeSoftware/whoNeedsArchitect.pdf">“Who needs an architect”</a> quoted “Software Architecture is about the important stuff, whatever that is”, the authors re-enforces this and has made an excellent attempt to explains us to why that is true. In the age of the programming world, software architecture has a constantly evolving role and hence its definition. In the most general terms, it can be equivalent to understanding the system which is divided into its components and connected with interfaces. As the authors quoted</p> <blockquote> <p>It is the highest level concept of the expert developers and their shared understanding The focus of software architecture should be more on the <code class="language-plaintext highlighter-rouge">WHY</code> than the <code class="language-plaintext highlighter-rouge">HOW</code> part.</p> </blockquote> <h2 id="four-sides">Software architecture’s 4 sides</h2> <p>The designing process of an effective piece of software can be further split into following steps:</p> <ul> <li>Structure - The base technology stack which forms the structural part of your software</li> <li>Characteristics - The technological properties which want your software to bring across</li> <li>Decisions - The decision tree which led to final software product</li> <li>Design principles - The principles which were closely followed while development</li> </ul> <p>The authors have provided easy to understand pictorial depictions for the above point which is helpfully embossing.</p> <h3 id="architectural-thinking">Architectural thinking - broadening the breadth</h3> <p>A developer’s mindset is to dig deeper into few chosen / relevant topics, while an architect needs to have an overview on a range of different technologies. Surely an architect needs to know a few topics well in depth but the part where they start making the difference is having an overview of the technologies used in the product.</p> <h4 id="defining-characteristics">Defining architectural characteristics</h4> <p>There are two types of architecture characteristics - explicit and implicit. Explicit characteristics are the ones which directly surface based on the solution provided and are non-domain specific design considerations. On the other hand implicit characteristics are the ones which are influenced from the structural aspects of the designs and are generally related to the domain specific knowledge. Let us take an example of designing a website for an online ticket booking system - here the characteristics such as reliability, availability, performance, scalability, etc. are explicitly covered while aspects such extensibility, upgradability, privacy, security etc. could be classified as implicit. I agree it is not 100% clear on how to label the characteristics, but the important point is to think from the perspective of the difference in domains and non-domain related characteristics.</p> <h4 id="identifying-characteristics">Identifying architectural characteristics in a given use case</h4> <p>One of the initial steps while architecting is to identify the characteristics. They can be extracted from the domain knowledge and the requirement documents. There is no specific set of rules to follow while identifying them, but one can practice through architectural Kata exercises. Please refer below what architectural Katas are.</p> <h4 id="measuring-governing"><strong>Measuring</strong> and <strong>Governing</strong> these characteristics</h4> <p>Authors show us the importance of measuring the measurable characteristics as a means of justifying your decisions. Authors introduced techniques to measure characteristics of modularity via cohesion, coupling and connascence properties. This would help quantify the characteristics which sets a good platform for comparing decisions. For effective decision-making it is important to analyse the detailed output and form fitness functions. From these reports an architect gets the opportunity to govern the decision-making process.</p> <h4 id="conways-law">Component based thinking - Conways Law</h4> <p>Conways Law suggests that the organisation’s communication structure heavily influences the design structure of the product it is developing. The flow of information in an organisation is affected by how the teams are structured which then affects the decision-making process. Based on the decision the ownership of the different building blocks aka components are influenced and hence the overall design structure gets altered. As Martin Fowler mentioned there are three ways to deal with this law:</p> <ol> <li>Ignore - it is proven to be ineffective to fight against it</li> <li>Accept - make sure your architecture incorporates the designers communications pattern</li> <li>Inverse Conway Maneuver - make changes in the communication patterns to achieve design architecture</li> </ol> <p>The identification of the software components of a product can be done either based on technical or domain related. It is important to understand both divisions inorder to make knowledgeable trade off decision.</p> <h3 id="architectural-patterns">Brief introductions into the architectural patterns</h3> <p>The author covered detailed definitions, descriptions and purpose of the various architectural designs. The designs covered are the following -</p> <ul> <li>Big ball of mud</li> <li>Monolithic architecture</li> <li>Component based design</li> <li>Service oriented architecture</li> <li>Service defined architecture</li> <li>Microservices</li> <li>Space based architecture</li> </ul> <p>I will not go further into the design patterns in this article as it will not do the justice to all of them in a short article. But if you are interested to know further I encourage reading up further in the book and other online resources. The interesting part in this book is about the comparison which was made on all the designs. The following mentioned architectural characteristics are used as the comparison - Deployability, Elasticity, Evolutionary, Fault tolerance, Modularity, Cost, Performance, Reliability, Scalability, Simplicity and Testability.</p> <h2 id="techniques">Techniques for practicing architecture</h2> <h4 id="architectural-katas">Practicing with Architectural Katas</h4> <p>To become a good architect one needs to practice making architects designs. In the beginning of my journey into this I struggled to find platforms to exercise architecture and the decision-making process. This book introduces the concept of architectural katas, a concept originally formed by <a href="https://www.architecturalkatas.com/">Ted Neward</a>. It is an exercise where a bunch of enthusiasts come together to design a different system and a moderator who not only assigns the tasks but also keeps track of the time. <ins> I plan to organise such events in the near future, so if you are interested do drop a message below</ins>.</p> <h4 id="adr">Architectural Decisions Records</h4> <p>Logging architectural decisions enables people from an organisation to take further design decisions abiding to the agreed ones. It allows to have a place where one can fall back for referring to the previous decisions taken and get away from <a href="https://softwarearchitecturezen.blog/2010/01/27/architecture-anti-patterns-pattern-1-architecture-by-e-mail/">email driven architectural decisions</a>. To create a high level understanding, it is mandatory to refer to the older superseded decisions while creating new decisions. Having a standard template for such decisions helps to create standardised records. There are various open source tools as such <a href="https://github.com/npryce/adr-tools">adr-tools</a> to help align the ADRs process and become coherent with the software development process. Records could also include various types of pictorial diagrams, class diagram, state machines diagram, flow diagram etc, created with <a href="https://en.wikipedia.org/wiki/Unified_Modeling_Language">UMLs</a> to convey the idea effectively.</p> <h4 id="architectural-path">Developing your unique Architectural path</h4> <p>Becoming an effective architect is a time consuming process and requires detailed path planning. In the final concluding chapter the authors gave us useful tips on laying down the path to become an architect. Everybody’s path to become an architect is a unique one and hence there are no specific rules for it. Author suggested creating a personalised radar for the technologies we are interested in and to pay close attention to the developments in it. They have given a example of such radars which they create within their organisation called <a href="https://www.thoughtworks.com/en-de/radar">Technology Radar</a>.</p> <p>Hope this article gave you a good insight into the field of software architecture and what this book has to offer. Do drop me <a href="https://www.linkedin.com/in/piyushdjadhav/">a connect on linkedin</a> to get to know further updates from me such topics.</p> <p>Have a happy learning!</p>]]></content><author><name></name></author><category term="Field Notes"/><category term="Book-reviews,"/><category term="Architecture,"/><category term="Design"/><summary type="html"><![CDATA[Book review for Fundamentals of Software Architecture - Mark Richards and Neal Ford]]></summary></entry><entry><title type="html">Book Review For C++ Design Pattern</title><link href="https://piyja.github.io/blog/2024/Book-review-for-C++-Design-pattern/" rel="alternate" type="text/html" title="Book Review For C++ Design Pattern"/><published>2024-01-11T00:20:00+00:00</published><updated>2024-01-11T00:20:00+00:00</updated><id>https://piyja.github.io/blog/2024/Book-review-for-C++-Design-pattern</id><content type="html" xml:base="https://piyja.github.io/blog/2024/Book-review-for-C++-Design-pattern/"><![CDATA[<h1 id="about">About the book</h1> <p>Recently I got an opportunity to read C++ Software Design by Dr Klaus Iglberger. I find the concepts presented in the book if not to cover basics but quite intriguing to further the thought process. As a software developer, I do regularly of think of design patterns and use them aiming to make the codebase more modular, scalable, reusable, less coupled. Albeit I found a holistic view of the design patterns from this book and would recommend it to a seasoned software developer. In this post, I am aiming to give a summary of the book but it is not a promotional blog by any means. You can treat it as a nonexhaustive abstract of what the book covers but if you are intrigued more please dive into the book.</p> <p>The book is about 400 pages and is divided into 39 digestible guidelines. In my opinion, the best part about this book is the footnotes and further reading material the author provides us. If you have attended/heard Dr Klaus’s talks you can imagine his voice while reading the book. The author writes a lot about readers’ reactive comments while introducing the concepts, which might annoy few but also helps in covering all-around discussions on it. After going through some pages you can even anticipate when these takes are coming ;-)</p> <p>Alright, let’s dive in. Following are the sections giving the summary of the book.</p> <h1 id="part-1">[1/3] Basic Software Development principles and what they mean from architectural pov</h1> <p>In this first part of the book, the author introduces both what software design is and why it is important in any software project. If we go to the first principle it is nothing but the “Art of managing dependencies and abstraction”. The author represents software development in three levels of</p> <ol> <li>Software architecture</li> <li>Software design</li> <li>Implementation details</li> </ol> <p>and explains the differences in the architecture and design of the software. The author gives us a helpful perspective to look at any software designs, ie from high level (fairly stable) and low level (prone to change).</p> <p>The author emphasizes how <strong>change is constant</strong> and <strong>design for extension</strong> and we developers should persistently keep this in the back of our minds. The author covers the most famous software principles like SOLID, DRY, ISP (and many more) but more importantly there are discusssions on how to interpret these principles while creating the low-level designs of the software. Most of his takes boils down to a single aspect while creating the designs to think about the “separation of concerns”. Separation of concerns sits at the base for most of the design patterns, if I were to zoom into it further, separations of concerns can be thought of from these two lenses -</p> <ol> <li>Decreasing coupling (be it artificial coupling)</li> <li>Increasing cohesion</li> </ol> <p>The section <strong>Design for testability</strong> resurfaces the problems we often face while unit testing <em>badly</em> designed classes. The mitigation approach is to have white-boxed tested classes, which could be enough but is not the best approach for testing. Again the solution to this appeared to be in thinking of separating concerns at the early development stage.</p> <p>In the next section, the author takes us into the <strong>Art of building abstraction</strong> to effectively place the requirements and expectations into the code. In OOP-based languages, abstractions are usually built using base classes and also can be built using concepts (or equivalent). Many times these introduce more problems where we can use abstractions using free functions. This aspect is touched on in many ways later to show how we can achieve decoupling and separate concerns. Nevertheless, in all these forms of abstraction building it is important to adhere to LSP to forward the expectations correctly and DIP to think in terms of ownership of the introduced abstractions. Next the author talks about what purpose the design patterns serve - to provide a blueprint for the organizational software to be built upon. Naming design patterns with commonly known patterns helps to pass on intent and information to developers. The author again emphasizes that design patterns are not only limited to OOP or dynamic polymorphism, they can be very well extended to functional or generic programming.</p> <p>The open-for-extension guideline in OCP can be interpreted in two ways: open for extending types or open for extending operations. Procedural programming gives us ease of adding new code for extending the operations but gets tougher to add new polymorphic types. On the other hand with OOP, we get the ease of adding new polymorphic types but it is tougher or impossible for adding new operations without recompiling the base classes. In the early stage of the project, one must make a conscious decision about which path of extension he/she wants to follow. It is important to understand that no design fits all-purpose and has its advantages and disadvantages.</p> <h1 id="part-2">[2/3] Strategy pattern, Observer and CRTP</h1> <p>Slowly the the design topics starts getting a bit complex.</p> <p>From the second tierce of the book, we start to get into various design patterns of both structural and behavioral patterns. First, we cover the visitor pattern and embrace it to solve our problems with the extension of operation in the inheritance hierarchy using double dispatch. Although naturally with this approach it gets tougher to add new types. We also learn that since we have double indirections used this design becomes quite inefficient by design. Next author introduces the std::variant style of visitor pattern, with which creating abstraction becomes quite easy. With std::variant we can group any unrelated types and based on the the type present at the call we can perform operations accordingly with the help of std::visit(). The new operations logic can be added on top without going back and changing any of these classes. While looking at the benchmarked result, it is worth mentioning that there are further nuances of these of writing your own get_if() functions to call particular operations based on the type provided. Refer the book to see various interesting benchmarks reported by the author.</p> <p>Then we move to cover the strategy pattern and command pattern. The strategy pattern intends to extend the polymorphic types of a class without much fuss. Strategy class can be thought of as serving complimentary aspect of open for extension as of visitor and also can be thought of as extracting the complex algorithms into separate entities being it a class or free function. Strategy entity can be injected as a dependency into the subject class. One of the downside in this pattern (also to be able to follow SRP) is that for each operation we need to add one strategy. One can use a <strong>Policy-based strategy design pattern</strong> by passing a policy in the form of a function object or lambda. We investigate the command design pattern next, which looks very similar and has the same implementation as that of the strategy design pattern. The only difference comes from the architectural point of view. For that matter even from the type of structural pattern, the adaptor design patterns strike as similar to strategy but the intent it serves is different. It becomes easy to think about the design when you think from the perspective of what intent they serve. We also cover differences in reference semantics (used often by OOP-based) and value-based designs. In this case, our policy-based designs emphasize the point of value-based semantics.</p> <p>Next, we go through the Adaptor pattern, the Observer pattern, and the CRTP pattern. Adaptor patterns are used to standardize the interfaces or to introduce a shim layer between the client and implementation details. Adaptors can be formed through creating an intermediate class or even by functions. Observer pattern is used where we require a notification system for a state change of the data, we are interested in. It creates a one-to-many relation between the subject (data we are interested in) and the observers. It is good to be aware of the further niche of this design: push observer and pull observer. It is also important to highlight that the observer pattern can be attained via value semantics as well. The CRTP pattern creates a compile-time abstraction for a family of related types. This is attained by using templates of the derived type, where we static cast this pointer to the derived class and access the methods we want to call. Note here since we use a template for the base class, we do not have the same base class for all derived types. C++20 concepts help us to implement this pattern.</p> <h1 id="part-3">[3/3] Bridge, prototype and type erasure pattern</h1> <p>The final third part of the book contains few of the most complex design patterns. If I were to go back referring to this book it would be mostly for this part of the book. The bridge pattern (belongs to the structural pattern domain ) can be used to isolate different concerns and bridge them. We can remove direct physical dependency between modules so that either end can evolve without affecting others (like retriggering recompilation etc.). The Pimpl Idiom is a more famous part of the bridge pattern. We can achieve ABI stability with this pattern. If we introduce more abstraction layers (and more indirections) it may appear that the efficiency could take a toll, which is true in most of the cases, but refer to the book to see where it can be even better than the unaltered design.</p> <p>The prototype pattern is used to self-clone concrete types from its base class object pointer. It is equivalent to having a virtual copy constructor. External polymorphism is a non-intrusive method to lets the user use the non-related (no-inheritance) classes to be treated polymorphically. There are new terms like concepts class (base) and model classes (derived from concept class) used. The important thing to know is that for different types of classes, there are different base classes (which could be templatized). This pattern takes advantage of it being non-polymorphic (fewer indirections), can be easily extendable according to OCP, and follows DRY and DIP. However, this pattern does not follow value semantics.</p> <p>The intent of the type erasure design pattern is to provide value-based non-intrusive abstraction for unrelated types but with the same semantic behavior. The type erasure design pattern contains a combination of external polymorphism, bridge pattern, and potentially prototype design pattern. It got its name because of the fact that the abstract class does not store the information about the concrete type of the object hence the type is erased. The author also adds optimization techniques like using SBO instead of dynamic memory to allocate and deallocate memory or manual dispatch instead of virtual table indirections.</p> <p>Decorator pattern allows dynamically attaching new functionality to the existing types without changing the types. In other words, it is a flexible alternative to subclassing for extending functionality. The author tells the reference from the GoF book about how the analogy of strategy being the gut of the object and decorator being the skin. The author also gave a quick tour of the Singleton pattern. Singleton pattern is infamous for the issues with SIOF, hindrance to testability, etc. The author shows us how strategy patterns could be used to invert dependency of the singleton pattern easily for testability.</p> <p>I hope you enjoyed reading this summarisation and find it helpful. If you decide to read the book do enjoy it! If you have already read the book, let me know if you have something more to add.</p> <h1 id="abbreviations">Abbreviations</h1> <ul> <li>OOP: Object Oriented Programming</li> <li>DRY: Do Not Repeat yourself</li> <li>SOLID: 5 most famous software programming principle next in line -</li> <li>SRP: Sinogle Responsibility Principle</li> <li>OCP : Open Close Principle</li> <li>LSP: Liskov’s Substitution Principle</li> <li>ISP: Interface Segregation Principle</li> <li>DIP: Dependency Inversion Principle</li> <li>CRTP: Curiously Recurring Template Pattern</li> <li>SBO: Small buffer optimization</li> <li>SIOF: Static initialization order fiasco</li> <li>GoF: Gang of four book - Design Patterns: Elements of Reusable Object-oriented software</li> </ul>]]></content><author><name></name></author><category term="Field Notes"/><category term="Design,"/><category term="Book-reviews,"/><category term="C++"/><summary type="html"><![CDATA[Book-review for C++ Design pattern – Klaus Iglberger]]></summary></entry></feed>