001/* 002 * To change this template, choose Tools | Templates 003 * and open the template in the editor. 004 */ 005 006package com.nativelibs4java.opencl.util; 007 008import com.nativelibs4java.opencl.CLBuildException; 009import com.nativelibs4java.opencl.CLContext; 010import com.nativelibs4java.opencl.CLBuffer; 011import com.nativelibs4java.opencl.CLEvent; 012import com.nativelibs4java.opencl.CLKernel; 013import com.nativelibs4java.opencl.CLProgram; 014import com.nativelibs4java.opencl.CLQueue; 015import com.nativelibs4java.opencl.JavaCL; 016import com.nativelibs4java.opencl.util.ReductionUtils; 017import com.nativelibs4java.opencl.util.ReductionUtils.Reductor; 018import com.nativelibs4java.util.IOUtils; 019import com.nativelibs4java.util.Pair; 020import static com.nativelibs4java.util.NIOUtils.*; 021import java.io.FileNotFoundException; 022import java.io.IOException; 023import java.io.InputStream; 024import java.io.PrintWriter; 025import java.io.StringWriter; 026import java.util.EnumMap; 027import java.util.HashMap; 028import java.util.Map; 029import java.util.logging.Level; 030import java.util.logging.Logger; 031 032/** 033 * 034 * @author ochafik 035 */ 036@SuppressWarnings("unused") 037public class ParallelMath { 038 039 protected CLContext context; 040 protected CLQueue queue; 041 042 public ParallelMath() { 043 this(JavaCL.createBestContext().createDefaultQueue()); 044 } 045 046 public ParallelMath(CLQueue queue) { 047 this.queue = queue; 048 CLContext context = queue.getContext(); 049 } 050 051 public CLQueue getQueue() { 052 return queue; 053 } 054 055 public CLContext getContext() { 056 return getQueue().getContext(); 057 } 058 059 protected String createVectFun1Source(Fun1 function, Primitive type, StringBuilder out) { 060 String t = type.clTypeName(); 061 String kernelName = "vect_" + function.name() + "_" + t;// + (inPlace ? "_inplace" : ""); 062 out.append("__kernel void " + kernelName + "(\n"); 063 out.append("\t__global const " + t + "* in,\n"); 064 out.append("\t__global " + t + "* out,\n"); 065 out.append("\tlong length\n"); 066 out.append(") {\n"); 067 out.append("\tint i = get_global_id(0);\n"); 068 out.append("\tif (i >= length) return;\n"); 069 out.append("\tout[i] = "); 070 function.expr("in[i]", out); 071 out.append(";\n"); 072 out.append("}\n"); 073 return kernelName; 074 } 075 076 077 protected String createVectFun2Source(Fun2 function, Primitive type1, Primitive type2, Primitive typeOut, StringBuilder out, boolean secondOperandIsScalar) { 078 String t1 = type1.clTypeName(), t2 = type2.clTypeName(), to = typeOut.clTypeName(); 079 String kernelName = "vect_" + function.name() + "_" + t1 + "_" + t2 + "_" + to; 080 out.append("__kernel void " + kernelName + "(\n"); 081 out.append("\t__global const " + t1 + "* in1,\n"); 082 if (secondOperandIsScalar) 083 out.append("\t" + t2 + " in2,\n"); 084 else 085 out.append("\t__global const " + t2 + "* in2,\n"); 086 out.append("\t__global " + to + "* out,\n"); 087 out.append("\tlong length\n"); 088 out.append(") {\n"); 089 out.append("\tint i = get_global_id(0);\n"); 090 out.append("\tif (i >= length) return;\n"); 091 out.append("\tout[i] = (" + to + ")"); 092 function.expr("in1[i]", (secondOperandIsScalar ? "in2" : "in2[i]"), out); 093 out.append(";\n"); 094 out.append("}\n"); 095 return kernelName; 096 } 097 098 099 private EnumMap<Fun1, EnumMap<Primitive, CLKernel>> fun1Kernels = new EnumMap<Fun1, EnumMap<Primitive, CLKernel>>(Fun1.class); 100 101 102 public synchronized CLKernel getKernel(Fun1 op, Primitive prim) throws CLBuildException { 103 EnumMap<Primitive, CLKernel> m = fun1Kernels.get(op); 104 if (m == null) 105 fun1Kernels.put(op, m = new EnumMap<Primitive, CLKernel>(Primitive.class)); 106 107 CLKernel kers = m.get(prim); 108 if (kers == null) { 109 StringBuilder out = new StringBuilder(300); 110 String name = createVectFun1Source(op, prim, out); 111 CLProgram prog = getContext().createProgram(out.toString()).build(); 112 kers = prog.createKernel(name); 113 m.put(prim, kers); 114 } 115 return kers; 116 } 117 118 static class PrimitiveTrio extends Pair<Pair<Primitive, Primitive>, Pair<Primitive, Boolean>> { 119 public PrimitiveTrio(Primitive a, Primitive b, Primitive c, boolean secondOperandIsScalar) { 120 super(new Pair<Primitive, Primitive>(a, b), new Pair<Primitive, Boolean>(c, secondOperandIsScalar)); 121 } 122 } 123 private EnumMap<Fun2, Map<PrimitiveTrio, CLKernel>> fun2Kernels = new EnumMap<Fun2, Map<PrimitiveTrio, CLKernel>>(Fun2.class); 124 public synchronized CLKernel getKernel(Fun2 op, Primitive prim, boolean secondOperandIsScalar) throws CLBuildException { 125 return getKernel(op, prim, prim, prim, secondOperandIsScalar); 126 } 127 128 public synchronized CLKernel getKernel(Fun2 op, Primitive prim1, Primitive prim2, Primitive primOut, boolean secondOperandIsScalar) throws CLBuildException { 129 Map<PrimitiveTrio, CLKernel> m = fun2Kernels.get(op); 130 if (m == null) 131 fun2Kernels.put(op, m = new HashMap<PrimitiveTrio, CLKernel>()); 132 133 PrimitiveTrio key = new PrimitiveTrio(prim1, prim2, primOut, secondOperandIsScalar); 134 CLKernel ker = m.get(key); 135 if (ker == null) { 136 StringBuilder out = new StringBuilder(300); 137 String name = createVectFun2Source(op, prim1, prim2, primOut, out, secondOperandIsScalar); 138 CLProgram prog = getContext().createProgram(out.toString()).build(); 139 ker = prog.createKernel(name); 140 m.put(key, ker); 141 } 142 return ker; 143 } 144 145}