I am using Metal Performance Shader to set up a neural network, and encountered the issue when writing the weights initialization class: Type 'MyWeights' does not conform to protocol 'NSCopying'. What caused the error, and how to fix this?
PS. I tried to fix it by adding the copy() function, however I do not know what to return or what it means.
import Foundation
import MetalPerformanceShaders
class MyWeights: NSObject, MPSCNNConvolutionDataSource {
//Error: Type 'MyWeights' does not conform to protocol 'NSCopying'
/*
func copy(with zone: NSZone? = nil) -> Any {
return self
}
*/
let name: String
let kernelWidth: Int
let kernelHeight: Int
let inputFeatureChannels: Int
let outputFeatureChannels: Int
var data: Data?
init(name: String, kernelWidth: Int, kernelHeight: Int,
inputFeatureChannels: Int, outputFeatureChannels: Int,
useLeaky: Bool = true) {
self.name = name
self.kernelWidth = kernelWidth
self.kernelHeight = kernelHeight
self.inputFeatureChannels = inputFeatureChannels
self.outputFeatureChannels = outputFeatureChannels
}
func dataType() -> MPSDataType {
return .float32
}
func descriptor() -> MPSCNNConvolutionDescriptor {
let desc = MPSCNNConvolutionDescriptor(kernelWidth: kernelWidth,
kernelHeight: kernelHeight,
inputFeatureChannels: inputFeatureChannels,
outputFeatureChannels: outputFeatureChannels)
return desc
}
func weights() -> UnsafeMutableRawPointer {
return UnsafeMutableRawPointer(mutating: (data! as NSData).bytes)
}
func biasTerms() -> UnsafeMutablePointer<Float>? {
return nil
}
func load() -> Bool {
if let url = Bundle.main.url(forResource: name, withExtension: "dat") {
do {
data = try Data(contentsOf: url)
return true
} catch {
print("Error: could not load \(url): \(error)")
}
}
return false
}
func purge() {
data = nil
}
func label() -> String? {
return name
}
}
It's telling you exactly what to do.
You need to declare that your class conforms to the NSCopying
protocol, and then you need to implement the only function in that protocol, copy(with:)
class MyWeights: NSObject, MPSCNNConvolutionDataSource, NSCopying {
func copy(with zone: NSZone? = nil) -> Any {
return MyWeights(
name: self.name,
kernelWidth: self.kernelWidth,
kernelHeight: self.kernelHeight,
inputFeatureChannels: self.inputFeatureChannels,
outputFeatureChannels: self.outputFeatureChannels,
useLeaky: self.useLeaky)
}
//The rest of your class
}