anchor.diff:  
     kernelSrc := kernelGen.GenerateDoubleTransformKernel(Expression, numInputs);
   
  -  WriteLn(kernelSrc);
  -
  -  prog := Context.CreateProgram(kernelSrc);
  -  if not prog.Build([Device]) then
  -  begin
  -    raise Exception.Create('Error building OpenCL kernel:' + #13#10 + prog.BuildLog);
  -  end;
  -
  -  kernel := prog.CreateKernel('transform_double_' + IntToStr(numInputs));
  +  if not FKernelCache.Contains[kernelSrc] then
  +  begin
  +    WriteLn(kernelSrc);
  +
  +    prog := Context.CreateProgram(kernelSrc);
  +    if not prog.Build([Device]) then
  +    begin
  +      raise Exception.Create('Error building OpenCL kernel:' + #13#10 + prog.BuildLog);
  +    end;
  +
  +    WriteLn(prog.BuildLog);
  +
  +    kernel := prog.CreateKernel('transform_double_' + IntToStr(numInputs));
  +    FKernelCache[kernelSrc] := kernel;
  +  end
  +  else
  +  begin
  +    kernel := FKernelCache[kernelSrc];
  +  end;
   
     for i := 0 to numInputs-1 do
     begin
  
positive.code:   FContext := plat.CreateContext([FDevice]);
    FCmdQueue := FContext.CreateCommandQueue(FDevice);
    FMemReadQueue := FContext.CreateCommandQueue(FDevice);
    FMemWriteQueue := FContext.CreateCommandQueue(FDevice);
  end;
  
  function TComputeAlgorithmsOpenCLImpl.Transform(const Input,
  
negative.code:     FCmdQueue: CLCommandQueue;
      FMemReadQueue: CLCommandQueue;
      FMemWriteQueue: CLCommandQueue;
      FKernelCache: IDictionary<string, CLKernel>;
  
      function DeviceOptimalNonInterleavedBufferSize: UInt64;
      function DeviceOptimalInterleavedBufferSize: UInt64;
  