## 2 Technical Enablers
### Deploying in Heterogeneous Computing Environments  
The main benefit of the development of IoT enabled systems that are cloud-centric is the simplicity of their design with straight-to-cloud data collection and central processing. During the previous years numerous platforms have been presented, such as Amazon Web Services (AWS) IoT ([[https://aws.amazon.com/iot/](https://aws.amazon.com/iot/)]([https://aws.amazon.com/iot/](https://aws.amazon.com/iot/))), Google Cloud IoT ([[https://cloud.google.com/solutions/iot/](https://cloud.google.com/solutions/iot/)]([https://cloud.google.com/solutions/iot/](https://cloud.google.com/solutions/iot/))) or Microsoft Azure IoT ([[https://azure.microsoft.com/en-us/overview/iot/](https://azure.microsoft.com/en-us/overview/iot/)]([https://azure.microsoft.com/en-us/overview/iot/](https://azure.microsoft.com/en-us/overview/iot/))). These cloud-based platforms provide a uniform and homogeneous computing environment that allows developers to focus on the analysis of the data and the integration of the extracted knowledge with existing enterprise infrastructures. Systems that are designed using the fog computing paradigm inherently incorporate different platforms with heterogeneous computing, processing and networking capabilities. In such deployments, heterogeneous computing elements usually contain one or more CPUs, each one with a set of computing cores, and possibly also a GPU [84]. Moreover, the physical implementation of MEC within the RAN currently integrates more and more heterogeneous hardware, such as Field Programmable Gate Arrays (FPGAs) in their servers, enabling their clients to accelerate their applications via programmable hardware. Ideally, programmers want to make use of as many resources as possible, primarily to increase performance and save energy [85]. However, contemporary systems do not provide a homogeneous programming environment that at the same time abstracts the heterogeneous hardware characteristics and yet allows taking advantage of all heterogeneous resources available within a computer system [84; 86]. Some of the acclaimed frameworks for stream-processing and big data analytics such as Apache Flink [87], Spark [88] and Storm [89] are implemented on top of Java Virtual Machines (JVMs), due to their fundamental requirements for portability and interoperability with commonly used high-level programming languages. These frameworks became popular partially because they are able to operate on a large variety of platforms and operating systems, despite the fact that most production JVMs only generate CPU-oriented code. Consequently, the task of creating code suitable for execution on heterogeneous devices such as GPUs or FPGAs falls back to the developers. Despite the fact that this approach is common in several frameworks such as HadoopCL [90], HeteroSpark [91] and Glasswing [92], there are certain omnipresent disadvantages that compromise any chance of a wider adoption or applicability [93]. **Code fragmentation:** Every developers' code base needs to provide inherent support for more than one programming language while at the same time integrate several different programming models [90; 91; 92]. For instance, in an attempt to provide out-of-the-box GPU acceleration, developers need to consolidate Scala and Java source code with low-level APIs such as CUDA or OpenCL [94]. This poses great programmability, as well as maintainability challenges since it demands familiarity with a variety of different concepts, APIs and tool-chains. Developers with such a broad spectrum of expertise are substantially hard to find. **Lack of code portability:** Given the fact that code segments are optimized for a particular device or hardware [95], migrating to a new cloud ecosystem, hardware architecture or sometimes to similar devices having different firmware requires extensive source code porting.