     }
 }
 
+func generateLibrary(device: MTLDevice) -> MTLLibrary {
+    let library : MTLLibrary?;
+    do {
+        let source : String = try String(contentsOfFile: "./addFunction.metal" )
+        library = try device.newLibraryWithSource(source, options: nil) // do we need compile options?
+    }
+    catch _ {
+        print("error creating library ...");
+        library = nil
+    }
+    return library!
+}
+
 func computeSumMetal(array1 array1 : [Float], array2 : [Float], inout sumArray : [Float], N : Int) {
     
     let devices: [MTLDevice] = MTLCopyAllDevices();

    
    sumArray = Array(UnsafeBufferPointer(start: output, count: N));
    
    
}

// create an array of random floats

var N : Int = 1024 * 1024 * 10;

print("Running test with N = ", N);


        print("error with compute pipeline state ...");
        return;
    }

    // 1. Call the setComputePipelineState(_:) method with the MTLComputePipelineState object that contains the compute function that will be executed.
    commandEncoder.setComputePipelineState(computePipelineState!);
    
    // 2 Specify resources that hold the input data (or output destination) for the compute function. Set the location (index) of each resource in its corresponding argument table.
    let resourceOptions: MTLResourceOptions = MTLResourceOptions.StorageModeManaged
    
    let arrayBuffer1 = defaultDevice.newBufferWithBytes(array1, length: N * sizeof(Float), options: resourceOptions)
    let arrayBuffer2 = defaultDevice.newBufferWithBytes(array2, length: N * sizeof(Float), options: resourceOptions)
    let sumBuffer = defaultDevice.newBufferWithBytes(sumArray, length: N * sizeof(Float), options: resourceOptions)
