<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Harsh Patel on Medium]]></title>
        <description><![CDATA[Stories by Harsh Patel on Medium]]></description>
        <link>https://medium.com/@harsh20111997?source=rss-3cc076fdef4d------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*Yn5iZfU6jqCLMQWQCNvG9A.png</url>
            <title>Stories by Harsh Patel on Medium</title>
            <link>https://medium.com/@harsh20111997?source=rss-3cc076fdef4d------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 08:12:14 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@harsh20111997/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[CUDA Programming: 2D convolution]]></title>
            <link>https://medium.com/@harsh20111997/cuda-programming-2d-convolution-8476300f566e?source=rss-3cc076fdef4d------2</link>
            <guid isPermaLink="false">https://medium.com/p/8476300f566e</guid>
            <category><![CDATA[mlops]]></category>
            <category><![CDATA[cuda]]></category>
            <category><![CDATA[nvidia]]></category>
            <category><![CDATA[gpu-computing]]></category>
            <dc:creator><![CDATA[Harsh Patel]]></dc:creator>
            <pubDate>Mon, 02 Oct 2023 11:45:47 GMT</pubDate>
            <atom:updated>2023-10-02T11:45:47.829Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*XBY4b_PHYxgeZjCWuTD_rw.png" /></figure><p>In this blog, I will guide you through how to code the cuda kernel for 2D convolution.</p><h3>Libs Required:</h3><pre>#include &lt;stdio.h&gt;<br>#include &lt;cuda_runtime.h&gt;</pre><h3>Kernel:</h3><pre>#define IS 5<br>#define KS 3</pre><pre>__global__<br>void convolution2DKernel(const float *input, const float *kernel, float *output,<br>                          int inputWidth, int inputHeight,<br>                          int kernelWidth, int kernelHeight) {<br>    int col = blockIdx.x * blockDim.x + threadIdx.x;<br>    int row = blockIdx.y * blockDim.y + threadIdx.y;<br><br>    if (col &lt; inputWidth &amp;&amp; row &lt; inputHeight) {<br>        int halfKernelWidth = kernelWidth / 2;<br>        int halfKernelHeight = kernelHeight / 2;<br><br>        float result = 0.0f;<br><br>        for (int i = 0; i &lt; kernelHeight; ++i) {<br>            for (int j = 0; j &lt; kernelWidth; ++j) {<br>                int inputRow = row - halfKernelHeight + i;<br>                int inputCol = col - halfKernelWidth + j;<br><br>                if (inputRow &gt;= 0 &amp;&amp; inputRow &lt; inputHeight &amp;&amp; inputCol &gt;= 0 &amp;&amp; inputCol &lt; inputWidth) {<br>                    result += input[inputRow * inputWidth + inputCol] * kernel[i * kernelWidth + j];<br>                }<br>            }<br>        }<br><br>        output[row * inputWidth + col] = result;<br>    }<br>}</pre><p>In this program, we have a kernel function called “convolution2DKernel”, which takes four arguments: two float arrays “input” and “kernal”, an float array “output”, and an integer “kernelSize”. The kernel function apply “kernel ” on “input ” array and stores the result in array “output”.</p><h3>Running Kernel:</h3><pre>int main() {<br>    // Example input data<br>    const int inputWidth = IS;<br>    const int inputHeight = IS;<br>    const int kernelWidth = KS;<br>    const int kernelHeight = KS;</pre><pre>    float input[inputHeight * inputWidth];<br><br>    for (int i = 0; i &lt; inputHeight; i++)<br>        for (int j = 0; j &lt; inputWidth; j++)<br>            input[i * inputHeight + j] = i + j;<br><br>    float kernel[kernelHeight * kernelWidth] = {<br>        0.5, 1.0, 0.5,<br>        1.0, 2.0, 1.0,<br>        0.5, 1.0, 0.5<br>    };<br><br>    float output[inputHeight * inputWidth];<br><br><br>    printf(&quot;array:input \n&quot;);<br>    for (int i = 0; i &lt; inputHeight ; i++) {<br>        for (int j = 0; j &lt; inputWidth; j++)<br>            printf(&quot;%f &quot;, input[i * inputHeight + j]);<br>        printf(&quot;\n&quot;);<br>    }<br><br>    printf(&quot;array:kernel \n&quot;);<br>    for (int i = 0; i &lt; kernelHeight; i++) {<br>        for (int j = 0; j &lt; kernelWidth; j++)<br>            printf(&quot;%f &quot;, kernel[i * kernelHeight + j]);<br>        printf(&quot;\n&quot;);<br>    }<br><br>    float *d_input, *d_kernel, *d_output;<br>    cudaMalloc((void**)&amp;d_input, inputHeight * inputWidth * sizeof(float));<br>    cudaMalloc((void**)&amp;d_kernel, kernelHeight * kernelWidth * sizeof(float));<br>    cudaMalloc((void**)&amp;d_output, inputHeight * inputWidth * sizeof(float));<br><br>    cudaMemcpy(d_input, input, inputHeight * inputWidth * sizeof(float), cudaMemcpyHostToDevice);<br>    cudaMemcpy(d_kernel, kernel, kernelHeight * kernelWidth * sizeof(float), cudaMemcpyHostToDevice);<br><br>    dim3 blockSize(16, 16);<br>    dim3 gridSize((inputWidth + blockSize.x - 1) / blockSize.x, (inputHeight + blockSize.y - 1) / blockSize.y);<br><br>    <br>    convolution2DKernel&lt;&lt;&lt;gridSize, blockSize&gt;&gt;&gt;(d_input, d_kernel, d_output,<br>                                                 inputWidth, inputHeight,<br>                                                 kernelWidth, kernelHeight);<br><br>    <br>    cudaMemcpy(output, d_output, inputHeight * inputWidth * sizeof(float), cudaMemcpyDeviceToHost);<br><br>    cudaFree(d_input);<br>    cudaFree(d_kernel);<br>    cudaFree(d_output);<br><br>    printf(&quot;array:output \n&quot;);<br><br>    for (int i = 0; i &lt; inputHeight; i++) {<br>        for (int j = 0; j &lt; inputWidth; j++)<br>            printf(&quot;%f &quot;, output[i * inputHeight + j]);<br>        printf(&quot;\n&quot;);<br>    }<br><br>    return 0;<br>}</pre><p>In the main function, we declare and initialize the necessary variables. We allocate memory on both the host and the device using the “malloc” and “cudaMalloc” functions, respectively. We then initialize the matrix “input” and “kernel” with values, and copy them to the device using the “cudaMemcpy” function. We launch the kernel function using the “&lt;&lt;&lt; &gt;&gt;&gt;” syntax, and then copy the result from the device to the host using “cudaMemcpy” again. Finally, we print the result of the vector output and free the memory.</p><h3>Compile and Running:</h3><p>To compile the program, we need to use the “nvcc” compiler provided by the CUDA Toolkit. We can compile the program with the following command:</p><pre>nvcc 2d_convolution_code.cu -o 2d_convolution_code</pre><p>To run the program, we simply execute the binary file generated by the compiler:</p><pre>./2d_convolution_code</pre><h3>Conclusion:</h3><p>I hope this blog has given you a good introduction to CUDA programming with C, and that you’re excited to explore more advanced topics in CUDA programming. Happy coding!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8476300f566e" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[CUDA Programming: 1D convolution]]></title>
            <link>https://medium.com/@harsh20111997/cuda-programming-1d-convolution-7234bebad652?source=rss-3cc076fdef4d------2</link>
            <guid isPermaLink="false">https://medium.com/p/7234bebad652</guid>
            <category><![CDATA[gpu-programming]]></category>
            <category><![CDATA[nvidia]]></category>
            <category><![CDATA[mlops]]></category>
            <category><![CDATA[cuda]]></category>
            <dc:creator><![CDATA[Harsh Patel]]></dc:creator>
            <pubDate>Mon, 02 Oct 2023 07:21:55 GMT</pubDate>
            <atom:updated>2023-10-02T11:41:23.112Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*XBY4b_PHYxgeZjCWuTD_rw.png" /></figure><p>In this blog, I will guide you through how to code the cuda kernel for 1D convolution.</p><h3>Libs Required:</h3><pre>#include &lt;stdio.h&gt;<br>#include &lt;cuda_runtime.h&gt;</pre><h3>Kernel:</h3><pre>#define KS 3<br>#define IS 10</pre><pre>__global__<br>void convolutionKernel(const float *input, const float *kernel, float *output, int inputSize, int kernelSize) {<br>    int tid = blockIdx.x * blockDim.x + threadIdx.x;<br><br>    if (tid &lt; inputSize) {<br>        int halfKernelSize = kernelSize / 2;<br>        float result = 0.0f;<br><br>        for (int i = 0; i &lt; kernelSize; ++i) {<br>            int inputIndex = tid - halfKernelSize + i;<br>            if (inputIndex &gt;= 0 &amp;&amp; inputIndex &lt; inputSize) {<br>                result += input[inputIndex] * kernel[i];<br>            }<br>        }<br><br>        output[tid] = result;<br>    }<br>}</pre><p>In this program, we have a kernel function called “convolutionKernel”, which takes four arguments: two float arrays “input” and “kernal”, an float array “output”, and an integer “kernelSize”. The kernel function apply “kernel ” on “input ” array and stores the result in array “output”.</p><h3>Running Kernel:</h3><pre>int main() {<br>    const int inputSize = IS;<br>    const int kernelSize = KS;<br><br>    float input[inputSize];<br>    float kernel[kernelSize] = {0.5, 1.0, 0.5};<br>    float output[inputSize];</pre><pre>    for (int i = 0; i &lt; inputSize; i++)<br>        input[i] = i;<br><br>    printf(&quot;input: &quot;);<br>    for (int i = 0; i &lt; inputSize; i++)<br>        printf(&quot;%f &quot;, input[i]);<br>    printf(&quot;\n&quot;);<br><br>    printf(&quot;kernel: &quot;);<br>    for (int i = 0; i &lt; kernelSize; i++)<br>        printf(&quot;%f &quot;, kernel[i]);<br>    printf(&quot;\n&quot;);<br><br>    float *d_input, *d_kernel, *d_output;<br>    cudaMalloc((void**)&amp;d_input, inputSize * sizeof(float));<br>    cudaMalloc((void**)&amp;d_kernel, kernelSize * sizeof(float));<br>    cudaMalloc((void**)&amp;d_output, inputSize * sizeof(float));<br><br>    cudaMemcpy(d_input, input, inputSize * sizeof(float), cudaMemcpyHostToDevice);<br>    cudaMemcpy(d_kernel, kernel, kernelSize * sizeof(float), cudaMemcpyHostToDevice);<br><br>    int blockSize = 256;<br>    int gridSize = (inputSize + blockSize - 1) / blockSize;<br><br>    convolutionKernel&lt;&lt;&lt;gridSize, blockSize&gt;&gt;&gt;(d_input, d_kernel, d_output, inputSize, kernelSize);<br><br>    cudaMemcpy(output, d_output, inputSize * sizeof(float), cudaMemcpyDeviceToHost);<br><br>    cudaFree(d_input);<br>    cudaFree(d_kernel);<br>    cudaFree(d_output);<br><br>    printf(&quot;output: &quot;);<br>    for (int i = 0; i &lt; inputSize; ++i) {<br>        printf(&quot;%f &quot;, output[i]);<br>    }<br>    printf(&quot;\n&quot;);<br><br>    return 0;<br>}</pre><p>In the main function, we declare and initialize the necessary variables. We allocate memory on both the host and the device using the “malloc” and “cudaMalloc” functions, respectively. We then initialize the matrix “input” and “kernel” with values, and copy them to the device using the “cudaMemcpy” function. We launch the kernel function using the “&lt;&lt;&lt; &gt;&gt;&gt;” syntax, and then copy the result from the device to the host using “cudaMemcpy” again. Finally, we print the result of the vector output and free the memory.</p><h3>Compile and Running:</h3><p>To compile the program, we need to use the “nvcc” compiler provided by the CUDA Toolkit. We can compile the program with the following command:</p><pre>nvcc 1d_convolution_code.cu -o 1d_convolution_code</pre><p>To run the program, we simply execute the binary file generated by the compiler:</p><pre>./1d_convolution_code</pre><h3>Conclusion:</h3><p>I hope this blog has given you a good introduction to CUDA programming with C, and that you’re excited to explore more advanced topics in CUDA programming. Happy coding!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7234bebad652" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[CUDA programming: Custom MNIST MLP engine]]></title>
            <link>https://medium.com/@harsh20111997/cuda-programming-custom-mnist-mlp-engine-832d09ded591?source=rss-3cc076fdef4d------2</link>
            <guid isPermaLink="false">https://medium.com/p/832d09ded591</guid>
            <category><![CDATA[gpu-programming]]></category>
            <category><![CDATA[cuda]]></category>
            <category><![CDATA[nvidia]]></category>
            <category><![CDATA[c-programming]]></category>
            <dc:creator><![CDATA[Harsh Patel]]></dc:creator>
            <pubDate>Sun, 01 Oct 2023 04:06:03 GMT</pubDate>
            <atom:updated>2023-10-02T07:23:46.010Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*XBY4b_PHYxgeZjCWuTD_rw.png" /></figure><p>In this blog, I will guide you through how to code the cuda kernel for MNIST MLP inference.</p><h3>Introduction:</h3><p>In the ever-evolving landscape of artificial intelligence and deep learning, neural networks have emerged as a dominant force, propelling groundbreaking advancements across various domains. Among these neural network architectures, the Multilayer Perceptron (MLP) stands out as one of the most fundamental and widely-used models for its simplicity and effectiveness in solving various tasks. One such task is digit recognition, where the classic MNIST dataset has become the de facto benchmark for evaluating the performance of machine learning algorithms.</p><p>In this blog post, we embark on an exhilarating journey into the realm of high-performance computing and CUDA programming to unleash the full potential of custom MNIST MLP inference. NVIDIA’s CUDA (Compute Unified Device Architecture) has revolutionized the way we harness the power of Graphics Processing Units (GPUs) to accelerate computationally intensive tasks. By leveraging the parallel processing capabilities of GPUs, we can achieve significant speedups in training and inference times, making them indispensable tools for modern deep learning applications.</p><p>Our objective throughout this article is to demystify the complexities of CUDA programming and empower you to build a custom MLP inference engine tailored to the MNIST dataset. Whether you are a seasoned deep learning practitioner or a curious enthusiast eager to dive into the world of GPU acceleration, this guide will equip you with the essential knowledge to wield CUDA effectively.</p><p>The knowledge gained from this blog will not only empower you to optimize MNIST digit recognition but also serve as a stepping stone to explore more complex deep learning tasks that demand high computational power.</p><p>So, buckle up and get ready to harness the parallel processing capabilities of CUDA as we embark on an exhilarating journey to supercharge our custom MNIST MLP inference engine!</p><h3>Training the Model and Saving Weights in NumPy:</h3><p>In this section of the blog, we covered the initial steps of implementing custom MNIST MLP inference using CUDA. We began by setting up the MNIST dataset and then designing the architecture of our Multilayer Perceptron (MLP) model and training it using PyTorch.</p><p>To preserve the trained model’s learned parameters for future use and compatibility with other environments, we saved the optimized weights and biases in NumPy format.</p><p>Data reading and Model training:</p><pre>import torch<br>import torch.nn as nn<br>import torch.nn.functional as F<br>from torchvision import datasets, transforms<br><br>import numpy as np<br>import matplotlib.pyplot as plt<br><br>import os<br><br><br>if torch.cuda.is_available():<br>    device = torch.device(&quot;cuda&quot;)<br>else:<br>    device = torch.device(&quot;cpu&quot;)<br><br>print(&quot;Using PyTorch version:&quot;, torch.__version__, &quot; Device:&quot;, device)<br><br>batch_size = 32<br><br>train_dataset = datasets.MNIST(<br>    &quot;./data&quot;, train=True, download=True, transform=transforms.ToTensor()<br>)<br><br>validation_dataset = datasets.MNIST(<br>    &quot;./data&quot;, train=False, transform=transforms.ToTensor()<br>)<br><br>train_loader = torch.utils.data.DataLoader(<br>    dataset=train_dataset, batch_size=batch_size, shuffle=True<br>)<br><br>validation_loader = torch.utils.data.DataLoader(<br>    dataset=validation_dataset, batch_size=batch_size, shuffle=False<br>)<br><br>for X_train, y_train in train_loader:<br>    print(&quot;X_train:&quot;, X_train.size(), &quot;type:&quot;, X_train.type())<br>    print(&quot;y_train:&quot;, y_train.size(), &quot;type:&quot;, y_train.type())<br>    break<br><br><br>class Net(nn.Module):<br>    def __init__(self):<br>        super(Net, self).__init__()<br>        self.fc1 = nn.Linear(28 * 28, 50)<br>        self.fc1_drop = nn.Dropout(0.2)<br>        self.fc2 = nn.Linear(50, 50)<br>        self.fc2_drop = nn.Dropout(0.2)<br>        self.fc3 = nn.Linear(50, 10)<br><br>    def forward(self, x):<br>        x = x.view(-1, 28 * 28)<br>        x = F.relu(self.fc1(x))<br>        x = self.fc1_drop(x)<br>        x = F.relu(self.fc2(x))<br>        x = self.fc2_drop(x)<br>        return F.log_softmax(self.fc3(x), dim=1)<br><br><br>model = Net().to(device)<br>optimizer = torch.optim.SGD(model.parameters(), lr=0.01, momentum=0.5)<br>criterion = nn.CrossEntropyLoss()<br><br>print(model)<br><br><br>def train(epoch, log_interval=200):<br>    # Set model to training mode<br>    model.train()<br><br>    # Loop over each batch from the training set<br>    for batch_idx, (data, target) in enumerate(train_loader):<br>        data = data.to(device)<br>        target = target.to(device)<br>        optimizer.zero_grad()<br>        output = model(data)<br>        loss = criterion(output, target)<br>        loss.backward()<br>        optimizer.step()<br><br>        if batch_idx % log_interval == 0:<br>            print(<br>                &quot;Train Epoch: {} [{}/{} ({:.0f}%)]\tLoss: {:.6f}&quot;.format(<br>                    epoch,<br>                    batch_idx * len(data),<br>                    len(train_loader.dataset),<br>                    100.0 * batch_idx / len(train_loader),<br>                    loss.data.item(),<br>                )<br>            )<br><br>def validate(loss_vector, accuracy_vector):<br>    model.eval()<br>    val_loss, correct = 0, 0<br>    for data, target in validation_loader:<br>        data = data.to(device)<br>        target = target.to(device)<br>        output = model(data)<br>        val_loss += criterion(output, target).data.item()<br>        pred = output.data.max(1)[1]  # get the index of the max log-probability<br>        correct += pred.eq(target.data).cpu().sum()<br><br>    val_loss /= len(validation_loader)<br>    loss_vector.append(val_loss)<br><br>    accuracy = 100.0 * correct.to(torch.float32) / len(validation_loader.dataset)<br>    accuracy_vector.append(accuracy)<br><br>    print(<br>        &quot;\nValidation set: Average loss: {:.4f}, Accuracy: {}/{} ({:.0f}%)\n&quot;.format(<br>            val_loss, correct, len(validation_loader.dataset), accuracy<br>        )<br>    )<br><br>epochs = 5<br><br>lossv, accv = [], []<br>for epoch in range(1, epochs + 1):<br>    train(epoch)<br>    validate(lossv, accv)</pre><p>Weights preserving:</p><pre>weights = [<br>    (name, param.detach().cpu().numpy()) for name, param in model.named_parameters()<br>]<br><br>for w in weights:<br>    with open(&quot;./model/&quot; + str(w[0]) + &quot;.npy&quot;, &quot;wb&quot;) as f:<br>        print(&quot;shape&quot;)<br><br>        if &quot;bias&quot; in w[0]:<br>            weights = np.expand_dims(w[1], axis=(0))<br>            print(weights.shape)<br><br>            weights = np.ascontiguousarray(weights)<br>            np.save(f, weights)<br>        else:<br>            weights = w[1].T<br>            print(weights.shape)<br><br>            weights = np.ascontiguousarray(weights)<br>            np.save(f, weights)</pre><h3>Loading NumPy Weights in CUDA in C++:</h3><p>In this section we will read the numpy weight in C++ using python interpeter. As we ready using Python interpeter we get PyArrayObject , which we will convert it into float. And we will move the float array to GPU using CUDA.</p><pre><br>#include &lt;stdio.h&gt;<br>#include &lt;stdlib.h&gt;<br>#include &lt;Python.h&gt;<br>#include &lt;cuda_runtime.h&gt;<br>#include &lt;numpy/arrayobject.h&gt;<br><br>#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION<br><br>struct Weights {<br>    float* matrix;<br>    int ndims;<br>    int *shape;<br>    long int size;<br>};<br><br>PyObject* read_numpy_file(const char* file_path) {<br>    // Import the Python module containing the function<br>    PyObject* numpy_module = PyImport_ImportModule(&quot;numpy&quot;);<br>    if (numpy_module == nullptr) {<br>        PyErr_Print();<br>        return nullptr;<br>    }<br><br>    // Get the reference to the function<br>    PyObject* numpy_function = PyObject_GetAttrString(numpy_module, &quot;load&quot;);<br>    if (numpy_function == nullptr) {<br>        PyErr_Print();<br>        Py_DECREF(numpy_module);<br>        return nullptr;<br>    }<br><br>    // Create the arguments tuple<br>    PyObject* args = PyTuple_New(1);<br>    PyTuple_SetItem(args, 0, PyUnicode_FromString(file_path));<br><br>    // Call the Python function with the arguments<br>    PyObject* result = PyObject_CallObject(numpy_function, args);<br>    if (result == nullptr) {<br>        PyErr_Print();<br>        Py_DECREF(numpy_module);<br>        Py_DECREF(numpy_function);<br>        Py_DECREF(args);<br>        return nullptr;<br>    }<br><br>    // Print the shape of the NumPy array<br>    PyObject* shape = PyObject_GetAttrString(result, &quot;shape&quot;);<br>    if (shape != nullptr) {<br>        PyObject* repr = PyObject_Repr(shape);<br>        const char* str = PyUnicode_AsUTF8(repr);<br>        printf(&quot;Shape: %s\n&quot;, str);<br>        Py_DECREF(repr);<br>        Py_DECREF(shape);<br>    } else {<br>        printf(&quot;Failed to get shape.\n&quot;);<br>    }<br><br>    // Clean up references<br>    Py_DECREF(numpy_module);<br>    Py_DECREF(numpy_function);<br>    Py_DECREF(args);<br>    return result;<br>}<br><br>PyArrayObject* read_weights_from_numpy(const char* file_path, int print) {<br>    // Call the Python function and get the PyObject reference to the NumPy array<br>    PyObject* numpy_array = read_numpy_file(file_path);<br>    if (numpy_array == nullptr) {<br>        // Handle error<br>        return nullptr;<br>    }<br><br>    // Use the PyObject reference to the NumPy array as needed<br>    // Example: Print the array<br>    if (print == 1){<br>        PyObject* repr = PyObject_Repr(numpy_array);<br>        const char* str = PyUnicode_AsUTF8(repr);<br>        printf(&quot;%s\n&quot;, str);<br>    }<br><br>    // Convert the result to a NumPy array<br>    PyArrayObject* array = reinterpret_cast&lt;PyArrayObject*&gt;(numpy_array);<br><br>    return array;<br>}<br><br>int get_numpy_ndims(PyArrayObject* array){<br>    // Get number of dimensions<br>    int ndim = PyArray_NDIM(array);<br>    printf(&quot;%d \n&quot;, ndim);<br>    return ndim;<br>}<br><br>long int get_numpy_size(PyArrayObject* array){<br>    // Get the total size of the array<br>    npy_intp total_size_intp = PyArray_SIZE(array);<br>    printf(&quot;%&quot; NPY_INTP_FMT &quot;\n&quot;, total_size_intp);<br>    <br>    long int total_size = static_cast&lt;long int&gt;(total_size_intp);<br>    return total_size;<br>}<br><br>float* convert_PyArrayObject_to_float(PyArrayObject* array, int print, int *shape, int ndim) {<br><br>    printf(&quot;values %d %d \n&quot;, PyArray_TYPE(array), NPY_DOUBLE);<br>    // Check the data type of the numpy array<br>    if (PyArray_TYPE(array) != NPY_FLOAT32) {<br>        printf(&quot;Input numpy array is not of type float.\n&quot;);<br>    }<br><br>    // Convert the weight into float<br>    float* matrix = static_cast&lt;float*&gt;(PyArray_DATA(array));<br><br>    // Printing weights for checking it after conversion <br>    if (print == 1){<br>        if (ndim == 2){<br>            for (int i = 0; i &lt; shape[0]; ++i) {<br>                if (i ==0){<br>                    for (int j = 0; j &lt; shape[1]; ++j) {<br>                        // matrix[j+(i*shape[1])] = 0.5f;<br>                        if(j&lt;3 || j&gt;shape[1]-3){<br>                            printf(&quot;%d index %.5f &quot;, j+(i*shape[1]), matrix[j+(i*shape[1])]);<br>                        }<br>                    }<br>                    printf(&quot;\n&quot;);<br>                }<br>            }<br>        }<br>        else if (ndim == 1){<br>            for (int i = 0; i &lt; shape[0]; ++i) {<br>                // matrix[i] = 0.5f;<br>                if(i&lt;5 || i&gt;shape[0]-5){<br>                    printf(&quot;%d index %.5f &quot;, i, matrix[i]);<br>                }<br>                <br>            }<br>            printf(&quot;\n&quot;);<br>        }<br>       <br>    }<br><br>    return matrix; <br>}<br><br><br>float* move_weight_to_cuda(float* weights ,long int total_size){<br>    // Allocate CUDA device memory<br>    float* d_data;<br>    printf(&quot;total size %d \n&quot;, total_size);<br><br>    cudaError_t cudaStatus;<br>    cudaStatus = cudaMalloc((void**)&amp;d_data, total_size * sizeof(float));<br>    if (cudaStatus != cudaSuccess) {<br>        fprintf(stderr, &quot;cudaMalloc failed: %s\n&quot;, cudaGetErrorString(cudaStatus));<br>        // Handle the error or return an error code<br>    }<br>    // Copy the array data from host (CPU) to device (CUDA)<br>    cudaStatus = cudaMemcpy(d_data, weights, total_size * sizeof(float), cudaMemcpyHostToDevice);<br>    if (cudaStatus != cudaSuccess) {<br>        fprintf(stderr, &quot;cudaMalloc failed: %s\n&quot;, cudaGetErrorString(cudaStatus));<br>        // Handle the error or return an error code<br>    }<br>    return d_data;<br>}<br><br>Weights read_weights(const char* file_path, int print){<br>    Weights weight;<br><br>    // reading numpy weights<br>    PyArrayObject* array = read_weights_from_numpy(file_path, print);<br>    if (array == nullptr) {<br>        // Handle error<br>        weight.matrix = nullptr;<br>        return weight;<br>    }<br><br>    int ndims = get_numpy_ndims(array);<br>    get_numpy_shape(array, weight, ndims);<br>    <br>    long int size = get_numpy_size(array);<br>    float* matrix = convert_PyArrayObject_to_float(array, print, weight.shape, ndims);<br>    <br>    // Release the PyObject reference<br><br>    float* cuda_weights = move_weight_to_cuda(matrix, size);<br>    Py_DECREF(array);<br><br>    weight.ndims = ndims;<br>    weight.size = size;<br>    weight.matrix = cuda_weights;<br><br>    return weight;<br>}</pre><h3><strong>Defining CUDA kernels for MLP in C++:</strong></h3><p>We have to define 3 kernel for make MLP to work <strong>matrixMulKernel</strong>, <strong>matrixAddKernel</strong> and <strong>softmaxKernel. </strong>For more details please check links in <strong>references</strong>.</p><pre>__global__ void matrixMulKernel(float* matrixA, float* matrixB, float* matrixC, int rowsA, int colsA, int colsB) {<br>    int row = blockIdx.y * blockDim.y + threadIdx.y;<br>    int col = blockIdx.x * blockDim.x + threadIdx.x;<br><br>    if (row &lt; rowsA &amp;&amp; col &lt; colsB) {<br>        float sum = 0.0f;<br>        for (int k = 0; k &lt; colsA; k++) {<br>            sum += matrixA[row * colsA + k] * matrixB[k * colsB + col];<br>        }<br>        matrixC[row * colsB + col] = sum;<br><br>        // Print intermediate result<br>        // printf(&quot;Intermediate result at rowsA %d, colsB %d  [%d][%d]: %.5f\n&quot;, rowsA, colsB, row, col, sum);<br>    }<br>}<br><br><br>__global__ void matrixAddKernel(float* matrixA, float* matrixB, float* matrixC, int rows, int cols) {<br>    int row = blockIdx.y * blockDim.y + threadIdx.y;<br>    int col = blockIdx.x * blockDim.x + threadIdx.x;<br><br>    if (row &lt; rows &amp;&amp; col &lt; cols) {<br>        int index = row * cols + col;<br>        matrixC[index] = matrixA[index] + matrixB[index];<br>    }<br>}<br><br>__global__ void softmaxKernel(float* input, float* output, int rows, int cols) {<br>    int row = blockIdx.y * blockDim.y + threadIdx.y;<br>    int col = blockIdx.x * blockDim.x + threadIdx.x;<br><br>    if (row &lt; rows &amp;&amp; col &lt; cols) {<br>        int index = row * cols + col;<br><br>        // Compute the exponential of each element<br>        float expVal = expf(input[index]);<br><br>        // Compute the sum of exponentials for the row<br>        float sumExp = 0.0f;<br>        for (int i = 0; i &lt; cols; ++i) {<br>            sumExp += expf(input[row * cols + i]);<br>        }<br><br>        // Compute the softmax value for the element<br>        output[index] = expVal / sumExp;<br>    }<br>}<br><br><br>float* matrixMul(float* matrixA, float* matrixB, int rowsA, int colsA, int rowsB, int colsB){<br>    float* matrixC;<br><br>    printf(&quot; ROW A %d  COLS A %d \n&quot;,rowsA, colsA);<br>    printf(&quot; ROW B %d  COLS B %d \n&quot;,rowsB, colsB);<br><br>    cudaMalloc((void **)&amp;matrixC, rowsA * colsB * sizeof(float));<br><br>    dim3 blockSize(16, 16);<br>    dim3 gridSize((colsB + blockSize.x - 1) / blockSize.x, (rowsA + blockSize.y - 1) / blockSize.y);<br><br>    matrixMulKernel&lt;&lt;&lt;gridSize, blockSize&gt;&gt;&gt;(matrixA, matrixB, matrixC, rowsA, colsA, colsB);<br><br>    return matrixC;<br>}<br><br>float* matrixAdd(float* matrixA, float* matrixB, int rows, int cols){<br>    float* matrixC;<br><br>    printf(&quot; ROW %d  COLS %d \n&quot;,rows, cols);<br><br>    cudaMalloc((void **)&amp;matrixC, rows * cols * sizeof(float));<br><br>    dim3 blockSize(16, 16);<br>    dim3 gridSize((cols + blockSize.x - 1) / blockSize.x, (rows + blockSize.y - 1) / blockSize.y);<br><br>    matrixAddKernel&lt;&lt;&lt;gridSize, blockSize&gt;&gt;&gt;(matrixA, matrixB, matrixC, rows, cols);<br><br>    return matrixC;<br>}<br><br><br>float* softmax(float* input, int rows, int cols){<br>    float* matrixC;<br><br>    printf(&quot; ROW %d  COLS %d \n&quot;,rows, cols);<br><br>    cudaMalloc((void **)&amp;matrixC, rows * cols * sizeof(float));<br><br>    dim3 blockSize(16, 16);<br>    dim3 gridSize((cols + blockSize.x - 1) / blockSize.x, (rows + blockSize.y - 1) / blockSize.y);<br><br>    softmaxKernel&lt;&lt;&lt;gridSize, blockSize&gt;&gt;&gt;(input, matrixC, rows, cols);<br><br>    return matrixC;<br>}</pre><h3>Defining main function for inference in C++:</h3><p>In this section, we will combine all the reading and kernel defination for MLP inference on CUDA.</p><pre>int main() {<br>    // Initialize the Python interpreter<br>    Py_Initialize();<br><br>    // Ensure that NumPy is available<br>    import_array();<br>    Weights fc1_w = read_weights(&quot;./mlp/mnist_mlp/model/fc1.weight.npy&quot;, 0);<br>    Weights fc2_w = read_weights(&quot;./mlp/mnist_mlp/model/fc2.weight.npy&quot;, 0);<br>    Weights fc3_w = read_weights(&quot;./mlp/mnist_mlp/model/fc3.weight.npy&quot;, 0);<br>    printf(&quot;#############################\n&quot;);<br>    Weights fc1_b = read_weights(&quot;./mlp/mnist_mlp/model/fc1.bias.npy&quot;, 0);<br>    Weights fc2_b = read_weights(&quot;./mlp/mnist_mlp/model/fc2.bias.npy&quot;, 0);<br>    Weights fc3_b = read_weights(&quot;./mlp/mnist_mlp/model/fc3.bias.npy&quot;, 0);<br><br>    //Read image<br>    Inputs image = read_image(&quot;./mlp/mnist_mlp/images/1.npy&quot;, 0);<br>    // Inputs image = read_image(&quot;./mlp/mnist_mlp/2.npy&quot;, 0);<br><br>    // Finalize the Python interpreter<br>    Py_Finalize();<br><br>    int output_row = 1;<br>    int output_col = 10;<br><br>    float* matrixC = nullptr;<br>    <br>    matrixC = matrixMul(image.matrix, fc1_w.matrix, image.shape[0], image.shape[1], fc1_w.shape[0], fc1_w.shape[1]);<br>    matrixC = matrixAdd(matrixC, fc1_b.matrix, fc1_b.shape[0], fc1_b.shape[1]);<br><br>    matrixC = matrixMul(matrixC, fc2_w.matrix, fc1_b.shape[0], fc1_b.shape[1], fc2_w.shape[0], fc2_w.shape[1]);<br>    matrixC = matrixAdd(matrixC, fc2_b.matrix, fc2_b.shape[0], fc2_b.shape[1]);<br><br>    matrixC = matrixMul(matrixC, fc3_w.matrix, fc2_b.shape[0], fc2_b.shape[1], fc3_w.shape[0], fc3_w.shape[1]);<br>    matrixC = matrixAdd(matrixC, fc3_b.matrix, fc3_b.shape[0], fc3_b.shape[1]);<br><br>    matrixC = softmax(matrixC, fc3_b.shape[0], fc3_b.shape[1]);<br><br>    printf(&quot;output shape 1: %d, %d&quot;, fc3_b.shape[0], fc3_b.shape[1]);<br><br>    float* C = (float *)malloc(output_row * output_col * sizeof(float));<br><br>    cudaMemcpy(C, matrixC,  output_row * output_col * sizeof(float), cudaMemcpyDeviceToHost);<br>    cudaDeviceSynchronize();<br><br>    printf(&quot;rowsA %d\n&quot;, output_row);<br>    printf(&quot;colsB %d\n&quot;, output_col);<br>    for (int i = 0; i &lt; output_row; i++) {<br>        for (int j = 0; j &lt; output_col; j++){<br>            printf(&quot;%f &quot;, C[i * output_row + j]);<br>            <br>        }<br>        printf(&quot;\n&quot;);<br>    }<br><br><br>    sleep(5);<br> <br>    // Clean up CUDA device memory<br>    cudaFree(fc1_w.matrix);<br>    cudaFree(fc2_w.matrix);<br>    cudaFree(fc3_w.matrix);<br>    <br>    cudaFree(fc1_b.matrix);<br>    cudaFree(fc2_b.matrix);<br>    cudaFree(fc3_b.matrix);<br><br>    return 0;<br>}</pre><h3>Compile and Running:</h3><p>To compile the program, we need to use the “nvcc” compiler provided by the CUDA Toolkit. We can compile the program with the following command:</p><pre>nvcc -o ml.o ml.cu -I/usr/include/python3.8/ -I/user/lib/python3/dist-packages/numpy/ -lpython3.8</pre><p>To run the program, we simply execute the binary file generated by the compiler:</p><pre>./ml.o</pre><h3>Conclusion:</h3><p>I hope this blog has given you a good introduction to CUDA programming with C, and that you’re excited to explore more advanced topics in CUDA programming. Happy coding!</p><h3>References:</h3><ol><li><a href="https://github.com/harsh2011/cuda_learning">https://github.com/harsh2011/cuda_learning</a> (Github Repo)</li><li><a href="https://medium.com/p/4d1f0b8535a3">https://medium.com/p/4d1f0b8535a3</a> (CUDA Programming: Array Addition)</li><li><a href="https://medium.com/p/1aa774b8d703">https://medium.com/p/1aa774b8d703</a> (CUDA Programming: 2D Matrix Multiplication)</li></ol><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=832d09ded591" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[CUDA Programming: Basics]]></title>
            <link>https://medium.com/@harsh20111997/cuda-programming-basics-42003540e351?source=rss-3cc076fdef4d------2</link>
            <guid isPermaLink="false">https://medium.com/p/42003540e351</guid>
            <category><![CDATA[cuda]]></category>
            <category><![CDATA[c-programming]]></category>
            <category><![CDATA[gpu-programming]]></category>
            <category><![CDATA[nvidia]]></category>
            <dc:creator><![CDATA[Harsh Patel]]></dc:creator>
            <pubDate>Fri, 03 Mar 2023 17:14:33 GMT</pubDate>
            <atom:updated>2023-03-03T17:20:42.774Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*XBY4b_PHYxgeZjCWuTD_rw.png" /></figure><p>The evolution of computer architecture has witnessed a shift from single-core to multi-core processing. CPUs have been developed to increase their core counts, but there is a limit to the number of cores that can be added to a CPU. As a result, researchers have turned their attention to another type of processor: the GPU (Graphics Processing Unit).</p><p>GPUs are highly parallel and have many more cores than CPUs. GPUs were first made for processing graphics, but they have become popular in scientific and technical computing because they can do a lot of calculations at once. NVIDIA made CUDA (Compute Unified Device Architecture) in 2006 so that GPUs could be used to their fullest potential. CUDA is a platform and programming model for parallel computing that lets developers use the power of graphics processing units (GPUs) for general-purpose computing.</p><p>In this series of blogs, we will cover the basics of CUDA programming, starting with the installation of the CUDA toolkit and moving on to the development of a simple CUDA program.</p><h3>Installing the CUDA Toolkit</h3><p>Before we can start programming in CUDA, we need to install the CUDA toolkit. The CUDA toolkit includes the necessary compilers, libraries, and development tools for CUDA programming.</p><p>To install the CUDA toolkit, follow these steps:</p><ol><li>Visit the NVIDIA CUDA website at <a href="https://developer.nvidia.com/cuda-toolkit">https://developer.nvidia.com/cuda-toolkit</a>.</li><li>Select the appropriate version of the CUDA toolkit for your system.</li><li>Download and run the installer.</li><li>Follow the instructions provided by the installer.</li><li>Once the installation is complete, restart your computer.</li><li>Verify that the CUDA toolkit is installed correctly by running the following command in a terminal window:</li></ol><pre>nvcc --version</pre><h3>Steps of Cuda Programming</h3><p>To begin, we must understand the structure of a cuda-based code; there are a few simple steps to take.</p><ul><li>Data initialization on the CPU</li><li>Data should be transferred from CPU to GPU.</li><li>Kernel launch (instructions on GPU)</li><li>Bring the results from GPU back to CPU.</li><li>Reclaim the memory from both CPU and GPU</li></ul><p>In such an environment, we will call <strong>host code</strong> the code that is going to run on the CPU, and d<strong>evice code </strong>the code that is going to run on the GPU.</p><h3>CUDA Kernels</h3><p>We now understand how the fundamentals of cuda work. I&#39;ll go over some basic kernel programming examples to help you learn and understand how the kernel works.</p><ol><li><a href="https://medium.com/@harsh20111997/cuda-programming-101-array-addition-4d1f0b8535a3"><strong>Array Addition</strong></a></li><li><a href="https://medium.com/@harsh20111997/cuda-programming-2d-matrix-multiplication-1aa774b8d703"><strong>2D Matrix Multiplication</strong></a></li></ol><h3>Conclusion:</h3><p>I hope this blog has given you a good introduction to CUDA programming with C, and that you’re excited to explore more advanced topics in CUDA programming. Happy coding!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=42003540e351" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[CUDA Programming: 2D Matrix Multiplication]]></title>
            <link>https://medium.com/@harsh20111997/cuda-programming-2d-matrix-multiplication-1aa774b8d703?source=rss-3cc076fdef4d------2</link>
            <guid isPermaLink="false">https://medium.com/p/1aa774b8d703</guid>
            <category><![CDATA[c-programming]]></category>
            <category><![CDATA[cuda]]></category>
            <category><![CDATA[gpu-programming]]></category>
            <category><![CDATA[nvidia]]></category>
            <dc:creator><![CDATA[Harsh Patel]]></dc:creator>
            <pubDate>Fri, 03 Mar 2023 07:47:09 GMT</pubDate>
            <atom:updated>2023-03-03T07:47:09.273Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*XBY4b_PHYxgeZjCWuTD_rw.png" /></figure><p>In this blog, I will guide you through how to code the cuda kernel for 2D matrix multiplication.</p><h3>Libs Required:</h3><pre>#include &lt;stdio.h&gt;<br>#include &lt;cuda_runtime.h&gt;</pre><h3>Kernel:</h3><pre>#define N 3<br><br>__global__ void matrix_mul(int *a, int *b, int *c, int n) {<br>    int i = blockIdx.x * blockDim.x + threadIdx.x;<br>    int j = blockIdx.y * blockDim.y + threadIdx.y;<br>    int sum = 0;<br>    if (i &lt; n &amp;&amp; j &lt; n) {<br>        for (int k = 0; k &lt; n; k++)<br>            sum += a[i * n + k] * b[k * n + j];<br>        c[i * n + j] = sum;<br>    }<br>}</pre><p>In this program, we have a kernel function called “add”, which takes four arguments: two integer arrays “a” and “b”, an integer array “c”, and an integer “n”. The kernel function adds the corresponding elements of arrays “a” and “b” and stores the result in array “c”. The if statement ensures that only valid elements of arrays “a”, “b”, and “c” are accessed.</p><h3>Running Kernel:</h3><pre>int main() {<br>    int n = N;<br>    int *a, *b, *c;<br>    int *d_a, *d_b, *d_c;<br>    int size = n * n * sizeof(int);<br><br>    a = (int *)malloc(size);<br>    b = (int *)malloc(size);<br>    c = (int *)malloc(size);<br><br>    for (int i = 0; i &lt; n; i++)<br>        for (int j = 0; j &lt; n; j++) {<br>            a[i * n + j] = i + j;<br>            b[i * n + j] = i * j;<br>        }<br><br>    cudaMalloc((void **)&amp;d_a, size);<br>    cudaMalloc((void **)&amp;d_b, size);<br>    cudaMalloc((void **)&amp;d_c, size);<br><br>    cudaMemcpy(d_a, a, size, cudaMemcpyHostToDevice);<br>    cudaMemcpy(d_b, b, size, cudaMemcpyHostToDevice);<br><br>    dim3 blockSize(N, N);<br>    dim3 gridSize((n + N - 1) / N, (n + N - 1) / N);<br>    matrix_mul&lt;&lt;&lt;gridSize, blockSize&gt;&gt;&gt;(d_a, d_b, d_c, n);<br><br>    cudaMemcpy(c, d_c, size, cudaMemcpyDeviceToHost);<br><br>    for (int i = 0; i &lt; n; i++) {<br>        for (int j = 0; j &lt; n; j++)<br>            printf(&quot;%d &quot;, c[i * n + j]);<br>        printf(&quot;\n&quot;);<br>    }<br><br>    cudaFree(d_a);<br>    cudaFree(d_b);<br>    cudaFree(d_c);<br>    free(a);<br>    free(b);<br>    free(c);<br><br>    return 0;<br>}<br></pre><p>In the main function, we declare and initialize the necessary variables. We allocate memory on both the host and the device using the “malloc” and “cudaMalloc” functions, respectively. We then initialize the matrix “a” and “b” with values, and copy them to the device using the “cudaMemcpy” function. We launch the kernel function using the “&lt;&lt;&lt; &gt;&gt;&gt;” syntax, and then copy the result from the device to the host using “cudaMemcpy” again. Finally, we print the result of the vector addition and free the memory.</p><h3>Compile and Running:</h3><p>To compile the program, we need to use the “nvcc” compiler provided by the CUDA Toolkit. We can compile the program with the following command:</p><pre>nvcc matrix_multiplication.cu -o matrix_multiplication</pre><p>To run the program, we simply execute the binary file generated by the compiler:</p><pre>./matrix_multiplication</pre><h3>Conclusion:</h3><p>I hope this blog has given you a good introduction to CUDA programming with C, and that you’re excited to explore more advanced topics in CUDA programming. Happy coding!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1aa774b8d703" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[CUDA Programming: Array Addition]]></title>
            <link>https://medium.com/@harsh20111997/cuda-programming-101-array-addition-4d1f0b8535a3?source=rss-3cc076fdef4d------2</link>
            <guid isPermaLink="false">https://medium.com/p/4d1f0b8535a3</guid>
            <category><![CDATA[nvidia]]></category>
            <category><![CDATA[cuda]]></category>
            <category><![CDATA[c-programming]]></category>
            <category><![CDATA[gpu-programming]]></category>
            <dc:creator><![CDATA[Harsh Patel]]></dc:creator>
            <pubDate>Fri, 03 Mar 2023 04:11:35 GMT</pubDate>
            <atom:updated>2023-03-03T16:17:50.101Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/500/1*XBY4b_PHYxgeZjCWuTD_rw.png" /></figure><p>In this blog, I will guide you through how to code the cuda kernel for array addition.</p><h3>Libs Reguired:</h3><pre>#include &lt;stdio.h&gt;<br>#include &lt;cuda_runtime.h&gt;</pre><h3>Kernel:</h3><pre>__global__ void add(int *a, int *b, int *c, int n)<br>{<br>    int i = blockDim.x * blockIdx.x + threadIdx.x;<br>    if (i &lt; n) <br>        c[i] = a[i] + b[i];<br>}</pre><p>In this program, we have a kernel function called “add”, which takes four arguments: two integer arrays “a” and “b”, an integer array “c”, and an integer “n”. The kernel function adds the corresponding elements of arrays “a” and “b” and stores the result in array “c”. The if statement ensures that only valid elements of arrays “a”, “b”, and “c” are accessed.</p><h3>Running Kernel:</h3><pre>int main() {<br>    int n = 10;<br>    int *a, *b, *c;<br>    int *d_a, *d_b, *d_c;<br>    int size = n * sizeof(int);<br><br>    a = (int *)malloc(size);<br>    b = (int *)malloc(size);<br>    c = (int *)malloc(size);<br><br>    for (int i = 0; i &lt; n; i++) {<br>        a[i] = i;<br>        b[i] = i * 2;<br>    }<br><br>    cudaMalloc((void **)&amp;d_a, size);<br>    cudaMalloc((void **)&amp;d_b, size);<br>    cudaMalloc((void **)&amp;d_c, size);<br><br>    cudaMemcpy(d_a, a, size, cudaMemcpyHostToDevice);<br>    cudaMemcpy(d_b, b, size, cudaMemcpyHostToDevice);<br><br>    add&lt;&lt;&lt;1, n&gt;&gt;&gt;(d_a, d_b, d_c, n);<br><br>    cudaMemcpy(c, d_c, size, cudaMemcpyDeviceToHost);<br><br>    for (int i = 0; i &lt; n; i++)<br>        printf(&quot;%d + %d = %d\n&quot;, a[i], b[i], c[i]);<br><br>    cudaFree(d_a);<br>    cudaFree(d_b);<br>    cudaFree(d_c);<br>    free(a);<br>    free(b);<br>    free(c);<br><br>    return 0;<br>}</pre><p>In the main function, we declare and initialize the necessary variables. We allocate memory on both the host and the device using the “malloc” and “cudaMalloc” functions, respectively. We then initialize the arrays “a” and “b” with values, and copy them to the device using the “cudaMemcpy” function. We launch the kernel function using the “&lt;&lt;&lt; &gt;&gt;&gt;” syntax, and then copy the result from the device to the host using “cudaMemcpy” again. Finally, we print the result of the vector addition and free the memory.</p><h3>Compile and Running:</h3><p>To compile the program, we need to use the “nvcc” compiler provided by the CUDA Toolkit. We can compile the program with the following command:</p><pre>nvcc vector_addition.cu -o vector_addition</pre><p>To run the program, we simply execute the binary file generated by the compiler:</p><pre>./vector_addition</pre><h3>Conclusion:</h3><p>I hope this blog has given you a good introduction to CUDA programming with C, and that you’re excited to explore more advanced topics in CUDA programming. Happy coding!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4d1f0b8535a3" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[GenerativeAdversarialNetwork(GAN) in Android — tictactoe.ai (Part 2)]]></title>
            <link>https://medium.com/data-science/generativeadversarialnetwork-gan-in-android-tictactoe-ai-part-2-70155c5ca55b?source=rss-3cc076fdef4d------2</link>
            <guid isPermaLink="false">https://medium.com/p/70155c5ca55b</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[deep-learning]]></category>
            <category><![CDATA[tensorflow]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[ai]]></category>
            <dc:creator><![CDATA[Harsh Patel]]></dc:creator>
            <pubDate>Sun, 07 Oct 2018 23:54:12 GMT</pubDate>
            <atom:updated>2022-12-11T03:52:19.636Z</atom:updated>
            <content:encoded><![CDATA[<h3>GenerativeAdversarialNetwork(GAN) in Android — tictactoe.ai (Part 2)</h3><p>Generative Adversarial Network is a deep network that works for generating images from random data. It comprises two different networks: the generator and the discriminator. The discriminator network is a standard convolutional neural network that can classify the images fed to it, similar to how a binomial classifier classifies images as real or fake. The generator is an inverse convolutional network that upsamples a vector of random noise to produce an image.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cxnqsjXYP-lx-3afYsuxXQ.png" /><figcaption>source: <a href="https://skymind.ai/images/wiki/gan_schema.png">https://skymind.ai/images/wiki/gan_schema.png</a></figcaption></figure><p>As a discriminator, you assist the generator in creating images that resemble real ones. It aids in the training of the GAN because it has a min-max loss function. Whereas the Generator minimizes log(1- D(G(z))) (z is a random data vector), the Discriminator maximizes the output log(D(x). (x is a real image which you can call as ground truth to generate an image)</p><p>Training a GAN is a difficult task because both networks are fighting to decrease its loss. They are inversely proportional; if one decreases, the other increases. We have to train GAN properly, giving them equal iterations to train. Also, check the generated image&#39;s output to see if it&#39;s correct.</p><h3>What is the use of GAN in tictactoe.ai?</h3><p>Thinking of taking this game to a single player, there should be someone who draws for the computer side, so I thought of introducing two different GANs to generate X and O.</p><h3>Generative Adversarial Network</h3><p>We only need a Generator part of the network.</p><p>Defining Input and Output node and giving them specify names.</p><pre><strong>input_node_name </strong>= &#39;noise_input_x&#39;<br><strong>output_node_name </strong>= &#39;gen_x&#39;</pre><pre>gen_inp = tf.placeholder(tf.float32,shape=[None, noise_dim],name=<strong>input_node_name</strong>)<br>disc_inp = tf.placeholder(tf.float32,shape= [None, img_dim])</pre><pre>def gen_fun(x,output_node_name):<br>    h1 = tf.matmul(x,W[&quot;w1&quot;])<br>    h1 = tf.add(h1,b[&quot;b1&quot;])<br>    h1 = tf.nn.relu(h1)<br>    <br>    h1 = tf.matmul(h1,W[&quot;w2&quot;])<br>    h1 = tf.add(h1,b[&quot;b2&quot;])<br>    h1 = tf.nn.sigmoid(h1, name=<strong>output_node_name</strong>)<br>    <br>    return h1</pre><pre>def disc_fun(x):<br>    h2 = tf.matmul(x,W[&quot;w3&quot;])<br>    h2 = tf.add(h2,b[&quot;b3&quot;])<br>    h2 = tf.nn.relu(h2)<br>    <br>    h2 = tf.matmul(h2,W[&quot;w4&quot;])<br>    h2 = tf.add(h2,b[&quot;b4&quot;])<br>    h2 = tf.nn.sigmoid(h2)<br>    <br>    return h2</pre><h3>Training output</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/209/1*zdC4o6ZJuliO5dP4VAEpGA.png" /><figcaption>generated image</figcaption></figure><h3><strong>Extracting Generator from the Graph</strong></h3><pre>freeze_graph.freeze_graph(&#39;out/&#39; + <strong>MODEL_NAME </strong>+ &#39;.pbtxt&#39;, None, False,<br>    &#39;out/&#39; + <strong>MODEL_NAME </strong>+ &#39;.chkp&#39;, <strong>output_node_name</strong>, &quot;save/restore_all&quot;,<br>    &quot;save/Const:0&quot;, &#39;out/frozen_&#39; + <strong>MODEL_NAME </strong>+ &#39;.pb&#39;, True, &quot;&quot;)</pre><pre>input_graph_def = tf.GraphDef()<br>with tf.gfile.Open(&#39;out/frozen_&#39; + <strong>MODEL_NAME </strong>+ &#39;.pb&#39;, &quot;rb&quot;) as f:<br>    input_graph_def.ParseFromString(f.read())</pre><pre><strong>input_node_names = [&#39;noise_input_x&#39;]</strong><br>    <br>output_graph_def = optimize_for_inference_lib.optimize_for_inference(<br>        input_graph_def, <strong>input_node_names</strong>, [<strong>output_node_name</strong>],<br>        tf.float32.as_datatype_enum)</pre><pre>with tf.gfile.FastGFile(&#39;out/opt_&#39; + <strong>MODEL_NAME </strong>+ &#39;.pb&#39;, &quot;wb&quot;) as f:<br>    f.write(output_graph_def.SerializeToString())</pre><p>For the above code, you will get an Optimized graph of the generator network</p><h3>Putting it in Android</h3><p>Firstly, copy your Optimized Graph of the generator in asset folder of Android</p><pre>private String MODEL_GAN_O = &quot;file:///android_asset/opt_gan_O.pb&quot;;<br>private String MODEL_GAN_X = &quot;file:///android_asset/opt_gan_X.pb&quot;;</pre><pre>private void loadGANs(){<br>        inferenceInterface_GAN_O = new TensorFlowInferenceInterface(getAssets(),MODEL_GAN_O);<br>        inferenceInterface_GAN_X = new TensorFlowInferenceInterface(getAssets(),MODEL_GAN_X);<br>}</pre><p>To Generate O, we have to pass the random noise vector to the Graph</p><pre>public int[] getGAN_O(){</pre><pre><strong>        // random noise input vector</strong>    <br>        <strong>float [] noise_input = new float [100];<br>        for(int i =0 ; i&lt;noise_input.length; i++){<br>            float value = rand.nextFloat();<br>            noise_input[i] = (value*2)-1;<br>        }</strong><br>        inferenceInterface_GAN_O.feed(INPUT_NODE_GAN_O, noise_input,1,100);<br>        inferenceInterface_GAN_O.run(new String[]{OUTPUT_NODE_GAN_O},false);</pre><pre>        float [] image = new float[784];<br>        int [] int_image = new int[784];<br>        //get the output<br>        inferenceInterface_GAN_O.fetch(OUTPUT_NODE_GAN_O,image);</pre><pre>       <strong> //output image</strong><br>        <strong>for(int i =0 ; i&lt;image.length; i++){<br>            int_image[i] = (int)(image[i]*255);<br>        }<br>        return int_image;</strong><br>}</pre><p>Same to Generate X, we have to pass the random noise vector to the Graph</p><pre>public int[] getGAN_X(){</pre><pre><strong>        // random noise input vector</strong>    <br>        <strong>float [] noise_input = new float [100];<br>        for(int i =0 ; i&lt;noise_input.length; i++){<br>            float value = rand.nextFloat();<br>            noise_input[i] = (value*2)-1;<br>        }</strong><br>        inferenceInterface_GAN_X.feed(INPUT_NODE_GAN_X, noise_input,1,100);<br>        inferenceInterface_GAN_X.run(new String[]{OUTPUT_NODE_GAN_X},false);</pre><pre>float [] image = new float[784];<br>        int [] int_image = new int[784];<br>        //get the output<br>        inferenceInterface_GAN_X.fetch(OUTPUT_NODE_GAN_X,image);</pre><pre><strong>        //output image</strong><br>        <strong>for(int i =0 ; i&lt;image.length; i++){<br>            int_image[i] = (int)(image[i]*255);<br>        }<br>        return int_image;</strong><br>}</pre><figure><img alt="" src="https://cdn-images-1.medium.com/max/288/1*gRqKR2KdHr0820RekqVEDA.gif" /></figure><p>This is the result after integrating the CNN and GAN. Completing all the logic of the application.</p><p>You can try out the application it is uploaded on the play store: <a href="https://play.google.com/store/apps/details?id=com.harsh.xo">https://play.google.com/store/apps/details?id=com.harsh.xo</a></p><p><strong>Future works</strong>: Maybe working on Conditional GAN, which helps me to generate X and O from the same network.</p><ul><li><a href="https://towardsdatascience.com/android-with-tensorflow-part-1-6897ba617b1e">ConvolutionNeuralNetwork(CNN) in Android — tictactoe.ai (Part 1)</a></li><li><a href="https://play.google.com/store/apps/details?id=com.harsh.xo">tictactoe.ai - Apps on Google Play</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=70155c5ca55b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/generativeadversarialnetwork-gan-in-android-tictactoe-ai-part-2-70155c5ca55b">GenerativeAdversarialNetwork(GAN) in Android — tictactoe.ai (Part 2)</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[ConvolutionNeuralNetwork(CNN) in Android — tictactoe.ai (Part 1)]]></title>
            <link>https://medium.com/data-science/android-with-tensorflow-part-1-6897ba617b1e?source=rss-3cc076fdef4d------2</link>
            <guid isPermaLink="false">https://medium.com/p/6897ba617b1e</guid>
            <category><![CDATA[android]]></category>
            <category><![CDATA[android-app-development]]></category>
            <category><![CDATA[tensorflow]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[deep-learning]]></category>
            <dc:creator><![CDATA[Harsh Patel]]></dc:creator>
            <pubDate>Wed, 20 Jun 2018 03:43:42 GMT</pubDate>
            <atom:updated>2018-10-07T07:13:06.399Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/730/1*InKCb9BfLS7G5w5YTdm_3A.jpeg" /><figcaption>Image source from- <a href="https://techcrunch.com/2017/05/17/googles-tensorflow-lite-brings-machine-learning-to-android-devices/">https://techcrunch.com/2017/05/17/googles-tensorflow-lite-brings-machine-learning-to-android-devices/</a></figcaption></figure><p>Google Tensorflow has now been used in Android for integrating Machine Learning Model.</p><p>So I want to create an Android App with Tensorflow, as other people just use the pre-trained model of the Tensorflow and integrate it inside the app. But I want to try something new, so have trained my own model and learned how Tensorflow interacts with Android. To know how to save the model for mobile usage.</p><h3>Tensorflow</h3><p>I have implemented code for Convolutional Neural Network to classify X and O for TicTacToe Game.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*cPAmSB9nziZPI73VC5HAHg.png" /><figcaption>Image sources from :- <a href="https://www.analyticsvidhya.com/blog/2017/06/architecture-of-convolutional-neural-networks-simplified-demystified/">https://www.analyticsvidhya.com/blog/2017/06/architecture-of-convolutional-neural-networks-simplified-demystified/</a></figcaption></figure><p>Input image size is 28x28 and Output layer size is 2. As we have to classify the image in X and O.</p><p>While building the model you have to define which is your <strong>output node</strong> and which is your<strong> input node</strong>, give those nodes some specify name.</p><p>Then training of the model, I have trained my model on 6000 different images of X and O, run over 3 epochs</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/644/1*gN-_uQmgXhwxNfyKQcCJvg.png" /><figcaption>Training result of CNN</figcaption></figure><p>As the Trained model has trained weight which gives the perfect classification of the X and O. Now, we have to save the graph of the Tensorflow with the weights.</p><p>While freezing a graph we require a list of Input and Output node name, that why we have given a name to those to input and output nodes, which helpful while freezing the graph.</p><p>Frozen Graph consist of sequence of operation that has to perform to get the output. Operation consist of the matrix multiplication, addition and reshaping of the matrix with the frozen weight of trained model.</p><p>Below is the code of freezing a save model.</p><pre>freeze_graph.freeze_graph(&#39;out/&#39; + MODEL_NAME + &#39;.pbtxt&#39;, <strong>None</strong>, <strong>False</strong>,&#39;out/&#39; + MODEL_NAME + &#39;.chkp&#39;, output_node_name, &quot;save/restore_all&quot;,&quot;save/Const:0&quot;, &#39;out/frozen_&#39; + MODEL_NAME + &#39;.pb&#39;, <strong>True</strong>, &quot;&quot;)<br><br>input_graph_def = tf.GraphDef()<br><strong>with</strong> tf.gfile.Open(&#39;out/frozen_&#39; + MODEL_NAME + &#39;.pb&#39;, &quot;rb&quot;) <strong>as</strong> f:<br>    input_graph_def.ParseFromString(f.read())<br><br>input_node_names = [&#39;input&#39;]<br>    <br>output_graph_def = optimize_for_inference_lib.optimize_for_inference(<br>        input_graph_def, input_node_names, [output_node_name],<br>        tf.float32.as_datatype_enum)<br><br><strong>with</strong> tf.gfile.FastGFile(&#39;out/opt_&#39; + MODEL_NAME + &#39;.pb&#39;, &quot;wb&quot;) <strong>as</strong> f:<br>    f.write(output_graph_def.SerializeToString())</pre><p>Check out the frozen graph of my project <a href="https://raw.githubusercontent.com/harsh2011/XO-Models/master/out/opt_xo_differ.pb">here</a></p><h3>Android with Tensorflow</h3><p>Starting with Android, Firstly, we have integrated Tensorflow library just add it to dependencies.</p><pre>dependencies {<br>.....<br>implementation ‘org.tensorflow:tensorflow-android:+’<br>}</pre><p>As Tensorflow is coded in C++, so you have to integrate NDK in our Android project. Then copy the model in the asset folder of the android directory.</p><p>How to run the graph in the Android using Java?</p><pre>// added the path of model<br>private static final String MODEL_FILE_CNN = &quot;file:///android_asset/opt_xo_differ_v2.pb&quot;;<br>//declare the input and output<br>private static final String INPUT_NODE = &quot;input&quot;;<br>private static final String OUTPUT_NODE = &quot;output&quot;private TensorFlowInferenceInterface inferenceInterface;</pre><pre>//load graph<br>inferenceInterface = new TensorFlowInferenceInterface(getAssets(),MODEL_FILE_CNN);</pre><p>Loading the model .pd file and create a <strong>TensorFlowInferenceInterface </strong>object</p><p>For detecting, I have created a method which reads <strong>Image pixels</strong> in a float. As DrawView is a canvas which gives us the pixels value of canvas drawn image then converting them into float and pass it to <strong>TensorflowInferenceInterface</strong> object.</p><p>So first you have to feed the data in<strong> Input Node (input_node and keep_prob), </strong>then run the InferenceInterface with the<strong> output_node</strong></p><pre>public float[] getDetectofDV(DrawView d){</pre><pre>float pixels[] = d.getPixelData();</pre><pre>inferenceInterface.feed(INPUT_NODE, pixels,1,28,28,1);<br>inferenceInterface.feed(&quot;keep_prob&quot;, new float[] { 1 });</pre><pre>final Operation operation = inferenceInterface.graphOperation(OUTPUT_NODE);</pre><pre>final int numClasses = (int) operation.output(0).shape().size(1);</pre><pre>// this run the operation of the graph<br>inferenceInterface.run(new String[]{OUTPUT_NODE},false);</pre><pre>float [] outputarray = new float[numClasses];<br>//get the output<br>inferenceInterface.fetch(OUTPUT_NODE,outputarray);</pre><pre>return outputarray;<br>}</pre><p><strong>outputarray</strong> returns the answer of the detection which has 2 values if one index 0 value in greater than index 1. Then the image is detected to be ‘O’, else it is ‘X’.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/360/1*JH1QqrGT7FRQQnjxBJhh5Q.gif" /></figure><p>This is the result after integrating the model with Android. As if work on touch listener when you pick up your finger from the canvas it pass the image for the classification and you will get the output in below matrix.</p><p>Check out the application on playstore. <a href="https://play.google.com/store/apps/details?id=com.harsh.xo">https://play.google.com/store/apps/details?id=com.harsh.xo</a></p><h3>Future work</h3><p>First I will try to reduce the size of the model. Model size of CNN is 17MB as it took a lot of space in the application. And the final size of the application 55 MB.</p><p>Working on integrating new model in the same application. A single user can play with the computer.</p><p><a href="https://play.google.com/store/apps/details?id=com.harsh.xo">https://play.google.com/store/apps/details?id=com.harsh.xo</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6897ba617b1e" width="1" height="1" alt=""><hr><p><a href="https://medium.com/data-science/android-with-tensorflow-part-1-6897ba617b1e">ConvolutionNeuralNetwork(CNN) in Android — tictactoe.ai (Part 1)</a> was originally published in <a href="https://medium.com/data-science">TDS Archive</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Check out My First Android Library( Firebase JSON Reference)]]></title>
            <link>https://medium.com/@harsh20111997/check-out-my-first-android-library-2c872e1d39e4?source=rss-3cc076fdef4d------2</link>
            <guid isPermaLink="false">https://medium.com/p/2c872e1d39e4</guid>
            <category><![CDATA[firebaseauth]]></category>
            <category><![CDATA[firebase]]></category>
            <category><![CDATA[android]]></category>
            <category><![CDATA[access-token]]></category>
            <category><![CDATA[androiddev]]></category>
            <dc:creator><![CDATA[Harsh Patel]]></dc:creator>
            <pubDate>Thu, 20 Jul 2017 11:14:42 GMT</pubDate>
            <atom:updated>2017-07-22T05:13:38.092Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/512/1*Y8UJ-sdTDRBq-WBNQTOJ6w.png" /></figure><p>As it’s small one but , I think it will be helpful to developer. This library is to get Firebase Reference JSON value.</p><p>While using ValueChangeListener to get data, I found some difficulties because it ran the code every time when data got change. So I wanted to get rid of this ValueChangeListener to get the data of the given reference.</p><p>That’s the reason I developed <a href="https://github.com/harsh2011/FirebaseJSONReference">FirebaseJSONReference</a>.</p><h4>Details need in Release 0.1.1</h4><blockquote>Firebase URL: “<a href="https://example.firebaseio.com/">https://example.firebaseio.com</a>&quot;</blockquote><blockquote>Reference URL: “/data/value”</blockquote><blockquote>User Token: Auth token from Firebase</blockquote><h3>How to get Auth Token :-</h3><blockquote>FirebaseUser mUser = FirebaseAuth.getInstance().getCurrentUser();<br> mUser.getIdToken(true)<br> .addOnCompleteListener(new OnCompleteListener&lt;GetTokenResult&gt;() {<br> public void onComplete(@NonNull Task&lt;GetTokenResult&gt; task) {<br> if (task.isSuccessful()) {<br> String token = task.getResult().getToken();<br> // Send token to your backend via HTTPS<br> // ...<br> } else {<br> // Handle error -&gt; task.getException();<br> }<br> }<br> });</blockquote><h3>Add Dependencies :-</h3><h4>Add following to your root build.gradle at the end of repositories:</h4><blockquote>allprojects {<br> repositories {<br> ...<br> maven { url &#39;https://jitpack.io&#39; }<br> }<br>}</blockquote><h4>Add following dependency</h4><blockquote>dependencies {<br> compile &#39;com.github.harsh2011:FirebaseJSONReference:0.1.1&#39;<br> }</blockquote><h3>Demo of Library:-</h3><h4>How to use it.</h4><blockquote>FirebaseJSONReference firebaseJSONReference = new FirebaseJSONReference(MainActivity.this);<br> firebaseJSONReference.setFirebaseDatabaseURL(&quot;https://example.firebaseio.com&quot;);<br> firebaseJSONReference.setFirebaseRef(&quot;/requestlist&quot;);<br> firebaseJSONReference.setAuth(&quot;auth token&quot;);<br> firebaseJSONReference.setResponseListener(new ResponseListener() {<br> @Override<br> public void onResponse(String s) {<br> System.out.println(&quot;response:&quot;+s);<br> try {<br> //JSONobject response <br> JSONObject main = new JSONObject(s);<br> <br> } catch (JSONException e) {<br> e.printStackTrace();<br> }</blockquote><blockquote>}<br> });<br> //build the request<br> firebaseJSONReference.build();<br> //execute the request and get response in Response Listener<br> firebaseJSONReference.execute();</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2c872e1d39e4" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Idea to Hiding Audio, by it convert into Image.(Data hiding)]]></title>
            <link>https://medium.com/@harsh20111997/idea-to-hiding-audio-by-convert-into-image-e06265198dc6?source=rss-3cc076fdef4d------2</link>
            <guid isPermaLink="false">https://medium.com/p/e06265198dc6</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[audio]]></category>
            <category><![CDATA[steganography]]></category>
            <category><![CDATA[hiding]]></category>
            <category><![CDATA[image]]></category>
            <dc:creator><![CDATA[Harsh Patel]]></dc:creator>
            <pubDate>Thu, 16 Mar 2017 20:27:46 GMT</pubDate>
            <atom:updated>2018-06-19T12:23:34.802Z</atom:updated>
            <content:encoded><![CDATA[<p>While working with Steganography. I want to hide Audio in Image. But lastly, I convert Audio in Image to hide data of the Audio.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ORv0_VAZiJEmlCENF82jkw.png" /><figcaption>Logic of hiding Audio file in form of Image</figcaption></figure><p>So I start finding out Libraries to ready Audio data</p><p>Libraries used:-</p><ol><li>ffmpy (python) For file conversion</li><li>soundfile (python) Read and Write the WAV file in python</li><li>numpy (pyhton) Handling N dimensional array</li><li>cv2 (python) Use for writing the PNG image</li></ol><p>Reading of WAV file</p><p>read() method of soundfile returns two thing</p><ol><li>samplerate</li><li>2.data (frames)(data types are (float,int))(array of data)</li></ol><p>As this Program reads int16 ,datatype. range of (-32768 to 32767)</p><p>One of the given data</p><pre>data = 6000 //range of (-32768 to 32767)<br>data = data + 32768<br>// divide data bits(data is of 16 bits)<br>datafront = first8bitsof(data) // 8bits<br>datalast = last8bitsof(data) // 8bits</pre><p>then,for the 2 channel in the data of 16 bits convert in 4 channel of 8 bits.which easy represent the image pixel value between 0 to 255</p><p>Using open write the data in image form. But image file must be PNG(lossless compression).</p><h3>Check out whole code on my github profile:-</h3><h3><a href="https://github.com/harsh2011/Steganography/tree/master/AudiotoImage(hidding%20audio%20in%20image)">https://github.com/harsh2011/Steganography/tree/master/AudiotoImage(hidding%20audio%20in%20image)</a></h3><p>Here is an ENCODE IMAGE:-</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TTOv4CvBylVwjeCrmwZdxw.png" /><figcaption>this the 1/4 image of data</figcaption></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e06265198dc6" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>