Advertisement
Guest User

Untitled

a guest
Apr 16th, 2022
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Swift 5.27 KB | None | 0 0
  1. import MetalKit
  2.  
  3. let count: Int = 3000000
  4.  
  5. // Create our random arrays
  6. var array1 = getRandomArray()
  7. var array2 = getRandomArray()
  8. var stepSize:Int = 10
  9. // Call our functions
  10. computeWay(arr1: array1, arr2: array2, stepSize: stepSize)
  11. basicForLoopWay(arr1: array1, arr2: array2)
  12.  
  13. func computeWay(arr1: [Int], arr2: [Int], stepSize: Int) {
  14.     // Begin the process
  15.     let startTime = CFAbsoluteTimeGetCurrent()
  16.    
  17.     // The GPU we want to use
  18.     let device = MTLCreateSystemDefaultDevice()
  19.  
  20.     // A fifo queue for sending commands to the gpu
  21.     let commandQueue = device?.makeCommandQueue()
  22.  
  23.     // A library for getting our metal functions
  24.     let gpuFunctionLibrary = device?.makeDefaultLibrary()
  25.  
  26.     // Grab our gpu function
  27.     let additionGPUFunction = gpuFunctionLibrary?.makeFunction(name: "addition_compute_function")
  28.  
  29.     var additionComputePipelineState: MTLComputePipelineState!
  30.     do {
  31.         additionComputePipelineState = try device?.makeComputePipelineState(function: additionGPUFunction!)
  32.     } catch {
  33.       print(error)
  34.     }
  35.    
  36.     print()
  37.     print("GPU Way")
  38.  
  39.     // Create the buffers to be sent to the gpu from our arrays
  40.     let arr1Buff = device?.makeBuffer(bytes: arr1,
  41.                                       length: MemoryLayout<Int>.size * count,
  42.                                       options: .storageModeShared)
  43.  
  44.     let arr2Buff = device?.makeBuffer(bytes: arr2,
  45.                                       length: MemoryLayout<Int>.size * count,
  46.                                       options: .storageModeShared)
  47.  
  48.     let resultBuff = device?.makeBuffer(length: MemoryLayout<Int>.size * count,
  49.                                         options: .storageModeShared)
  50.  
  51.     print("size: \(MemoryLayout.size(ofValue: stepSize)) bytes")
  52.     print("val index 0 : \(stepSize)")
  53.     print("val index 0 : \(arr1[0])")
  54.  
  55.     let asBytes = withUnsafeBytes(of: stepSize, Array.init)
  56.     let myValBuf = device?.makeBuffer(bytes: asBytes,
  57.                                           length: MemoryLayout.size(ofValue:stepSize),
  58.                                           options: .storageModeShared)
  59.  
  60.    
  61.    
  62.     //let stepSize = UnsafeRawPointer(uint8Pointer)
  63.                               //.bindMemory(to: UInt64.self, capacity: 1)
  64.     let commandBuffer = commandQueue?.makeCommandBuffer()
  65.  
  66.    
  67.     // Create an encoder to set vaulues on the compute function
  68.     let commandEncoder = commandBuffer?.makeComputeCommandEncoder()
  69.     commandEncoder?.setComputePipelineState(additionComputePipelineState)
  70.    
  71.    
  72.     // Set the parameters of our gpu function
  73.     commandEncoder?.setBuffer(arr1Buff, offset: 0, index: 0)
  74.     commandEncoder?.setBuffer(arr2Buff, offset: 0, index: 1)
  75.     commandEncoder?.setBuffer(resultBuff, offset: 0, index: 2)
  76.     commandEncoder?.setBuffer(myValBuf, offset: 0, index: 3)
  77.      
  78.     //commandEncoder?.setBy(stepSize, length:sizeof(stepSize),index: 3)
  79.     //commandEncoder?.setBytes(stepSize, length: MemoryLayout<Int>.size, index: 3)
  80.  
  81.     // Figure out how many threads we need to use for our operation
  82.     let threadsPerGrid = MTLSize(width: count, height: 1, depth: 1)
  83.     let maxThreadsPerThreadgroup = additionComputePipelineState.maxTotalThreadsPerThreadgroup // 1024
  84.     let threadsPerThreadgroup = MTLSize(width: maxThreadsPerThreadgroup, height: 1, depth: 1)
  85.     commandEncoder?.dispatchThreads(threadsPerGrid,
  86.                                     threadsPerThreadgroup: threadsPerThreadgroup)
  87.  
  88.     // Tell the encoder that it is done encoding.  Now we can send this off to the gpu.
  89.     commandEncoder?.endEncoding()
  90.  
  91.     // Push this command to the command queue for processing
  92.     commandBuffer?.commit()
  93.  
  94.     // Wait until the gpu function completes before working with any of the data
  95.     commandBuffer?.waitUntilCompleted()
  96.  
  97.     // Get the pointer to the beginning of our data
  98.     var resultBufferPointer = resultBuff?.contents().bindMemory(to: Int.self,capacity: MemoryLayout<Int>.size * count)
  99.  
  100.     // Print out all of our new added together array information
  101.     for i in 0..<3 {
  102.         print("\(arr1[i]) + \(arr2[i])+ \(stepSize)  = \(Int(resultBufferPointer!.pointee) as Any)")
  103.         resultBufferPointer = resultBufferPointer?.advanced(by: 1)
  104.     }
  105.    
  106.     // Print out the elapsed time
  107.     let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
  108.     print("Time elapsed \(String(format: "%.05f", timeElapsed)) seconds")
  109.     print()
  110. }
  111.  
  112. func basicForLoopWay(arr1: [Int], arr2: [Int]) {
  113.     print("CPU Way")
  114.    
  115.     // Begin the process
  116.     let startTime = CFAbsoluteTimeGetCurrent()
  117.  
  118.     var result = [Int].init(repeating: 0, count: count)
  119.  
  120.     // Process our additions of the arrays together
  121.     for i in 0..<count {
  122.         result[i] = arr1[i] + arr2[i]
  123.     }
  124.  
  125.     // Print out the results
  126.     for i in 0..<3 {
  127.         print("\(arr1[i]) + \(arr2[i]) + \(stepSize) = \(result[i])")
  128.     }
  129.  
  130.     // Print out the elapsed time
  131.     let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
  132.     print("Time elapsed \(String(format: "%.05f", timeElapsed)) seconds")
  133.  
  134.     print()
  135. }
  136.  
  137. // Helper function
  138. func getRandomArray()->[Int] {
  139.     var result = [Int].init(repeating: 0, count: count)
  140.     for i in 0..<count {
  141.         result[i] = Int(arc4random_uniform(10))
  142.     }
  143.     return result
  144. }
  145.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement