aboutsummaryrefslogtreecommitdiffstats
path: root/src/com/mbien
diff options
context:
space:
mode:
authorMichael Bien <[email protected]>2010-02-22 23:38:56 +0100
committerMichael Bien <[email protected]>2010-02-22 23:38:56 +0100
commitd78faf0ef678cc87f5220d2cb8eccbe173449541 (patch)
tree8a4dcff14f70c88869d6bdc095817474ae729311 /src/com/mbien
parent7c83da1d2e3e8d122e562408a63a13928cc97c83 (diff)
introduced CLObject as common superclass for all OpenCL objects.
Diffstat (limited to 'src/com/mbien')
-rw-r--r--src/com/mbien/opencl/CLCommandQueue.java44
-rw-r--r--src/com/mbien/opencl/CLContext.java24
-rw-r--r--src/com/mbien/opencl/CLDevice.java20
-rw-r--r--src/com/mbien/opencl/CLEvent.java11
-rw-r--r--src/com/mbien/opencl/CLKernel.java7
-rw-r--r--src/com/mbien/opencl/CLMemory.java18
-rw-r--r--src/com/mbien/opencl/CLObject.java57
-rw-r--r--src/com/mbien/opencl/CLProgram.java40
-rw-r--r--src/com/mbien/opencl/CLSampler.java20
-rw-r--r--src/com/mbien/opencl/CLUtils.java14
10 files changed, 145 insertions, 110 deletions
diff --git a/src/com/mbien/opencl/CLCommandQueue.java b/src/com/mbien/opencl/CLCommandQueue.java
index 1a70605a..ce15e715 100644
--- a/src/com/mbien/opencl/CLCommandQueue.java
+++ b/src/com/mbien/opencl/CLCommandQueue.java
@@ -9,6 +9,7 @@ import java.util.List;
import static com.mbien.opencl.CLException.*;
import static com.mbien.opencl.CL.*;
+import static com.mbien.opencl.CLUtils.*;
/**
* The command queue is used to queue a set of operations for a specific {@link CLDevice}.
@@ -20,13 +21,9 @@ import static com.mbien.opencl.CL.*;
* @see CLDevice#createCommandQueue(com.mbien.opencl.CLCommandQueue.Mode[])
* @author Michael Bien
*/
-public class CLCommandQueue implements CLResource {
+public class CLCommandQueue extends CLObject implements CLResource {
- public final long ID;
-
- private final CLContext context;
private final CLDevice device;
- private final CL cl;
private long properties;
/*
@@ -36,9 +33,9 @@ public class CLCommandQueue implements CLResource {
private final PointerBuffer bufferB;
private final PointerBuffer bufferC;
- CLCommandQueue(CLContext context, CLDevice device, long properties) {
- this.context = context;
- this.cl = context.cl;
+ private CLCommandQueue(CLContext context, long id, CLDevice device, long properties) {
+ super(context, id);
+
this.device = device;
this.properties = properties;
@@ -46,11 +43,16 @@ public class CLCommandQueue implements CLResource {
this.bufferB = PointerBuffer.allocateDirect(3);
this.bufferC = PointerBuffer.allocateDirect(3);
+ }
+
+ static CLCommandQueue create(CLContext context, CLDevice device, long properties) {
int[] status = new int[1];
- this.ID = cl.clCreateCommandQueue(context.ID, device.ID, properties, status, 0);
+ long id = context.cl.clCreateCommandQueue(context.ID, device.ID, properties, status, 0);
if(status[0] != CL_SUCCESS)
throw newException(status[0], "can not create command queue on "+device);
+
+ return new CLCommandQueue(context, id, device, properties);
}
public CLCommandQueue putWriteBuffer(CLBuffer<?> writeBuffer, boolean blockingRead) {
@@ -60,7 +62,7 @@ public class CLCommandQueue implements CLResource {
public CLCommandQueue putWriteBuffer(CLBuffer<?> writeBuffer, boolean blockingWrite, CLEventList events) {
int ret = cl.clEnqueueWriteBuffer(
- ID, writeBuffer.ID, blockingWrite ? CL_TRUE : CL_FALSE,
+ ID, writeBuffer.ID, clBoolean(blockingWrite),
0, writeBuffer.getSize(), writeBuffer.buffer,
0, null, events==null ? null : events.IDs);
@@ -82,7 +84,7 @@ public class CLCommandQueue implements CLResource {
public CLCommandQueue putReadBuffer(CLBuffer<?> readBuffer, boolean blockingRead, CLEventList events) {
int ret = cl.clEnqueueReadBuffer(
- ID, readBuffer.ID, blockingRead ? CL_TRUE : CL_FALSE,
+ ID, readBuffer.ID, clBoolean(blockingRead),
0, readBuffer.getSize(), readBuffer.buffer,
0, null, events==null ? null : events.IDs);
@@ -156,7 +158,7 @@ public class CLCommandQueue implements CLResource {
copy2NIO(bufferA, originX, originY, 0);
copy2NIO(bufferB, rangeX, rangeY, 1);
- int ret = cl.clEnqueueWriteImage(ID, writeImage.ID, blockingWrite ? CL_TRUE : CL_FALSE,
+ int ret = cl.clEnqueueWriteImage(ID, writeImage.ID, clBoolean(blockingWrite),
bufferA, bufferB, inputRowPitch, 0, writeImage.buffer,
0, null, events==null ? null : events.IDs);
checkForError(ret, "can not write Image");
@@ -187,7 +189,7 @@ public class CLCommandQueue implements CLResource {
copy2NIO(bufferA, originX, originY, originZ);
copy2NIO(bufferB, rangeX, rangeY, rangeZ);
- int ret = cl.clEnqueueWriteImage(ID, writeImage.ID, blockingWrite ? CL_TRUE : CL_FALSE,
+ int ret = cl.clEnqueueWriteImage(ID, writeImage.ID, clBoolean(blockingWrite),
bufferA, bufferB, inputRowPitch, inputSlicePitch, writeImage.buffer,
0, null, events==null ? null : events.IDs);
checkForError(ret, "can not write Image");
@@ -220,7 +222,7 @@ public class CLCommandQueue implements CLResource {
copy2NIO(bufferA, originX, originY, 0);
copy2NIO(bufferB, rangeX, rangeY, 1);
- int ret = cl.clEnqueueReadImage(ID, readImage.ID, blockingRead ? CL_TRUE : CL_FALSE,
+ int ret = cl.clEnqueueReadImage(ID, readImage.ID, clBoolean(blockingRead),
bufferA, bufferB, inputRowPitch, 0, readImage.buffer,
0, null, events==null ? null : events.IDs);
checkForError(ret, "can not read Image");
@@ -251,9 +253,9 @@ public class CLCommandQueue implements CLResource {
copy2NIO(bufferA, originX, originY, originZ);
copy2NIO(bufferB, rangeX, rangeY, rangeZ);
- int ret = cl.clEnqueueReadImage(ID, readImage.ID, blockingRead ? CL_TRUE : CL_FALSE,
- bufferA, bufferB, inputRowPitch, inputSlicePitch, readImage.buffer,
- 0, null, events==null ? null : events.IDs);
+ int ret = cl.clEnqueueReadImage(ID, readImage.ID, clBoolean(blockingRead),
+ bufferA, bufferB, inputRowPitch, inputSlicePitch, readImage.buffer,
+ 0, null, events==null ? null : events.IDs);
checkForError(ret, "can not read Image");
if(events != null) {
@@ -492,7 +494,7 @@ public class CLCommandQueue implements CLResource {
public ByteBuffer putMapBuffer(CLBuffer<?> buffer, CLMemory.Map flag, long offset, long length, boolean blockingMap, CLEventList events) {
IntBuffer error = bufferA.position(0).getBuffer().asIntBuffer();
- ByteBuffer mappedBuffer = cl.clEnqueueMapBuffer(ID, buffer.ID, blockingMap ? CL_TRUE : CL_FALSE,
+ ByteBuffer mappedBuffer = cl.clEnqueueMapBuffer(ID, buffer.ID, clBoolean(blockingMap),
flag.FLAGS, offset, length,
0, null, events==null ? null : events.IDs, error);
checkForError(error.get(), "can not map buffer");
@@ -527,7 +529,7 @@ public class CLCommandQueue implements CLResource {
copy2NIO(bufferB, offsetX, offsetY, 0);
copy2NIO(bufferC, rangeX, rangeY, 1);
- ByteBuffer mappedImage = cl.clEnqueueMapImage(ID, buffer.ID, blockingMap ? CL_TRUE : CL_FALSE,
+ ByteBuffer mappedImage = cl.clEnqueueMapImage(ID, buffer.ID, clBoolean(blockingMap),
flag.FLAGS, bufferB, bufferC, null, null,
0, null, events==null ? null : events.IDs, error);
checkForError(error.get(), "can not map image2d");
@@ -560,7 +562,7 @@ public class CLCommandQueue implements CLResource {
IntBuffer error = bufferA.position(0).getBuffer().asIntBuffer();
copy2NIO(bufferB, offsetX, offsetY, offsetZ);
copy2NIO(bufferC, rangeX, rangeY, rangeZ);
- ByteBuffer mappedImage = cl.clEnqueueMapImage(ID, buffer.ID, blockingMap ? CL_TRUE : CL_FALSE,
+ ByteBuffer mappedImage = cl.clEnqueueMapImage(ID, buffer.ID, clBoolean(blockingMap),
flag.FLAGS, bufferB, bufferC, null, null,
0, null, events==null ? null : events.IDs, error);
checkForError(error.get(), "can not map image3d");
@@ -823,7 +825,7 @@ public class CLCommandQueue implements CLResource {
* please refere to the specification ({@native clSetCommandQueueProperty}) or vendor documentation.
*/
public void setProperty(Mode property, boolean enabled) {
- int ret = cl.clSetCommandQueueProperty(ID, property.QUEUE_MODE, enabled ? CL_TRUE : CL_FALSE, null);
+ int ret = cl.clSetCommandQueueProperty(ID, property.QUEUE_MODE, clBoolean(enabled), null);
if(ret != CL_SUCCESS) {
checkForError(ret, "can not set command queue property: " + property);
}
diff --git a/src/com/mbien/opencl/CLContext.java b/src/com/mbien/opencl/CLContext.java
index bab61c19..505e4f73 100644
--- a/src/com/mbien/opencl/CLContext.java
+++ b/src/com/mbien/opencl/CLContext.java
@@ -34,23 +34,21 @@ import static com.sun.gluegen.runtime.BufferFactory.*;
* specified in the context.
* @author Michael Bien
*/
-public class CLContext implements CLResource {
-
- final CL cl;
- public final long ID;
+public class CLContext extends CLObject implements CLResource {
protected CLDevice[] devices;
protected final List<CLProgram> programs;
protected final List<CLSampler> samplers;
protected final List<CLMemory<? extends Buffer>> memoryObjects;
+
protected final Map<CLDevice, List<CLCommandQueue>> queuesMap;
+
protected final CLPlatform platform;
protected CLContext(CLPlatform platform, long contextID) {
- this.cl = CLPlatform.getLowLevelCLInterface();
- this.ID = contextID;
+ super(CLPlatform.getLowLevelCLInterface(), contextID);
this.platform = platform;
this.programs = new ArrayList<CLProgram>();
this.samplers = new ArrayList<CLSampler>();
@@ -188,7 +186,7 @@ public class CLContext implements CLResource {
* Creates a program from the given sources, the program is not build yet.
*/
public CLProgram createProgram(String src) {
- CLProgram program = new CLProgram(this, src);
+ CLProgram program = CLProgram.create(this, src);
programs.add(program);
return program;
}
@@ -226,7 +224,7 @@ public class CLContext implements CLResource {
* </ul>
*/
public CLProgram createProgram(Map<CLDevice, byte[]> binaries) {
- CLProgram program = new CLProgram(this, binaries);
+ CLProgram program = CLProgram.create(this, binaries);
programs.add(program);
return program;
}
@@ -314,7 +312,7 @@ public class CLContext implements CLResource {
CLCommandQueue createCommandQueue(CLDevice device, long properties) {
- CLCommandQueue queue = new CLCommandQueue(this, device, properties);
+ CLCommandQueue queue = CLCommandQueue.create(this, device, properties);
List<CLCommandQueue> list = queuesMap.get(device);
if(list == null) {
@@ -327,7 +325,7 @@ public class CLContext implements CLResource {
}
public CLSampler createSampler(AddressingMode addrMode, FilteringMode filtMode, boolean normalizedCoords) {
- CLSampler sampler = new CLSampler(this, addrMode, filtMode, normalizedCoords);
+ CLSampler sampler = CLSampler.create(this, addrMode, filtMode, normalizedCoords);
samplers.add(sampler);
return sampler;
}
@@ -383,10 +381,16 @@ public class CLContext implements CLResource {
/**
* Returns the CLPlatform this context is running on.
*/
+ @Override
public CLPlatform getPlatform() {
return platform;
}
+ @Override
+ public CLContext getContext() {
+ return this;
+ }
+
/**
* Returns a read only view of all programs associated with this context.
*/
diff --git a/src/com/mbien/opencl/CLDevice.java b/src/com/mbien/opencl/CLDevice.java
index 941b8560..3c1c4e25 100644
--- a/src/com/mbien/opencl/CLDevice.java
+++ b/src/com/mbien/opencl/CLDevice.java
@@ -22,29 +22,19 @@ import static com.mbien.opencl.CL.*;
* @see CLContext#getMaxFlopsDevice(com.mbien.opencl.CLDevice.Type)
* @author Michael Bien
*/
-public final class CLDevice {
+public final class CLDevice extends CLObject {
- private final CL cl;
- private CLContext context;
private Set<String> extensions;
private final CLDeviceInfoAccessor deviceInfo;
- /**
- * OpenCL device id for this device.
- */
- public final long ID;
-
CLDevice(CL cl, long id) {
- this.cl = cl;
- this.ID = id;
+ super(cl, id);
this.deviceInfo = new CLDeviceInfoAccessor();
}
CLDevice(CLContext context, long id) {
- this.context = context;
- this.cl = context.cl;
- this.ID = id;
+ super(context, id);
this.deviceInfo = new CLDeviceInfoAccessor();
}
@@ -71,10 +61,6 @@ public final class CLDevice {
throw new IllegalStateException("this device is not associated with a context");
return context.createCommandQueue(this, properties);
}
-
- public CLContext getContext() {
- return context;
- }
/*keep this package private*/
void setContext(CLContext context) {
diff --git a/src/com/mbien/opencl/CLEvent.java b/src/com/mbien/opencl/CLEvent.java
index 5d244190..bcc59efc 100644
--- a/src/com/mbien/opencl/CLEvent.java
+++ b/src/com/mbien/opencl/CLEvent.java
@@ -14,20 +14,13 @@ import static com.mbien.opencl.CLException.*;
* {@link com.mbien.opencl.CLCommandQueue.Mode#PROFILING_MODE}.
* @author Michael Bien
*/
-public class CLEvent implements CLResource {
-
- public final CLContext context;
- public final long ID;
-
- private final CL cl;
+public class CLEvent extends CLObject implements CLResource {
private final CLEventInfoAccessor eventInfo;
private final CLEventProfilingInfoAccessor eventProfilingInfo;
CLEvent(CLContext context, long id) {
- this.context = context;
- this.cl = context.cl;
- this.ID = id;
+ super(context, id);
this.eventInfo = new CLEventInfoAccessor();
this.eventProfilingInfo = new CLEventProfilingInfoAccessor();
}
diff --git a/src/com/mbien/opencl/CLKernel.java b/src/com/mbien/opencl/CLKernel.java
index a8c1ff10..a4573a01 100644
--- a/src/com/mbien/opencl/CLKernel.java
+++ b/src/com/mbien/opencl/CLKernel.java
@@ -19,14 +19,12 @@ import static com.mbien.opencl.CL.*;
* CLKernel is not threadsafe.
* @author Michael Bien
*/
-public class CLKernel implements CLResource, Cloneable {
+public class CLKernel extends CLObject implements CLResource, Cloneable {
- public final long ID;
public final String name;
public final int numArgs;
private final CLProgram program;
- private final CL cl;
private final ByteBuffer buffer;
@@ -34,9 +32,8 @@ public class CLKernel implements CLResource, Cloneable {
private boolean force32BitArgs;
CLKernel(CLProgram program, long id) {
- this.ID = id;
+ super(program.getContext(), id);
this.program = program;
- this.cl = program.context.cl;
this.buffer = BufferFactory.newDirectByteBuffer(8);
PointerBuffer pb = PointerBuffer.allocateDirect(1);
diff --git a/src/com/mbien/opencl/CLMemory.java b/src/com/mbien/opencl/CLMemory.java
index 884744ad..59537f85 100644
--- a/src/com/mbien/opencl/CLMemory.java
+++ b/src/com/mbien/opencl/CLMemory.java
@@ -16,26 +16,17 @@ import static com.mbien.opencl.CL.*;
*
* @author Michael Bien
*/
-public abstract class CLMemory <B extends Buffer> implements CLResource {
+public abstract class CLMemory <B extends Buffer> extends CLObject implements CLResource {
B buffer;
- public final long ID;
-
- protected final CLContext context;
- protected final CL cl;
-
protected <Buffer> CLMemory(CLContext context, long id) {
- this.context = context;
- this.cl = context.cl;
- this.ID = id;
+ super(context, id);
}
protected CLMemory(CLContext context, B directBuffer, long id) {
+ super(context, id);
this.buffer = directBuffer;
- this.context = context;
- this.cl = context.cl;
- this.ID = id;
}
/**
@@ -77,6 +68,9 @@ public abstract class CLMemory <B extends Buffer> implements CLResource {
return this;
}
+ /**
+ * Returns the optional NIO buffer for this memory object.
+ */
public B getBuffer() {
return buffer;
}
diff --git a/src/com/mbien/opencl/CLObject.java b/src/com/mbien/opencl/CLObject.java
new file mode 100644
index 00000000..ff5f7d1f
--- /dev/null
+++ b/src/com/mbien/opencl/CLObject.java
@@ -0,0 +1,57 @@
+package com.mbien.opencl;
+
+/**
+ * Common superclass for all OpenCL objects.
+ * @author Michael Bien
+ */
+abstract class CLObject {
+
+ /**
+ * The OpenCL object handle.
+ */
+ public final long ID;
+
+ protected CLContext context;
+
+ protected final CL cl;
+
+ CLObject(CL cl, long ID) {
+ this.cl = cl;
+ this.context = null;
+ this.ID = ID;
+ }
+
+ CLObject(CLContext context, long ID) {
+ this.cl = context.cl;
+ this.context = context;
+ this.ID = ID;
+ }
+
+ /**
+ * Returns the context for this OpenCL object.
+ */
+ public CLContext getContext() {
+ return context;
+ }
+
+ /**
+ * Returns the platform for this OpenCL object.
+ */
+ public CLPlatform getPlatform() {
+ return context.getPlatform();
+ }
+
+ /**
+ * Returns the OpenCL object handle
+ */
+ public long getID() {
+ return ID;
+ }
+
+ @Override
+ public String toString() {
+ return "CLObject [id: " + ID
+ + " context: " + context+"]";
+ }
+
+}
diff --git a/src/com/mbien/opencl/CLProgram.java b/src/com/mbien/opencl/CLProgram.java
index aafca855..4c3d61f5 100644
--- a/src/com/mbien/opencl/CLProgram.java
+++ b/src/com/mbien/opencl/CLProgram.java
@@ -23,37 +23,32 @@ import static com.mbien.opencl.CL.*;
* @see CLContext#createProgram(java.util.Map)
* @author Michael Bien
*/
-public class CLProgram implements CLResource {
+public class CLProgram extends CLObject implements CLResource {
- public final CLContext context;
- public final long ID;
-
- private final CL cl;
-
private final Set<CLKernel> kernels;
private Map<CLDevice, Status> buildStatusMap;
private boolean executable;
private boolean released;
- CLProgram(CLContext context, String src) {
-
- this.cl = context.cl;
- this.context = context;
+ private CLProgram(CLContext context, long id) {
+ super(context, id);
this.kernels = new HashSet<CLKernel>();
+ }
+
+ static CLProgram create(CLContext context, String src) {
- IntBuffer ib = BufferFactory.newDirectByteBuffer(4).asIntBuffer();
+ IntBuffer status = BufferFactory.newDirectByteBuffer(4).asIntBuffer();
// Create the program
- ID = cl.clCreateProgramWithSource(context.ID, 1, new String[] {src},
- PointerBuffer.allocateDirect(1).put(src.length()), ib);
- checkForError(ib.get(), "can not create program with source");
- }
+ long id = context.cl.clCreateProgramWithSource(context.ID, 1, new String[] {src},
+ PointerBuffer.allocateDirect(1).put(src.length()), status);
- CLProgram(CLContext context, Map<CLDevice, byte[]> binaries) {
+ checkForError(status.get(), "can not create program with source");
+
+ return new CLProgram(context, id);
+ }
- this.cl = context.cl;
- this.context = context;
- this.kernels = new HashSet<CLKernel>();
+ static CLProgram create(CLContext context, Map<CLDevice, byte[]> binaries) {
PointerBuffer devices = PointerBuffer.allocateDirect(binaries.size());
PointerBuffer lengths = PointerBuffer.allocateDirect(binaries.size());
@@ -77,7 +72,7 @@ public class CLProgram implements CLResource {
IntBuffer err = BufferFactory.newDirectByteBuffer(4).asIntBuffer();
// IntBuffer status = BufferFactory.newDirectByteBuffer(binaries.size()*4).asIntBuffer();
- ID = cl.clCreateProgramWithBinary(context.ID, devices.capacity(), devices, lengths, codeBuffers, /*status*/null, err);
+ long id = context.cl.clCreateProgramWithBinary(context.ID, devices.capacity(), devices, lengths, codeBuffers, /*status*/null, err);
// while(status.remaining() != 0) {
// checkForError(status.get(), "unable to load binaries on all devices");
@@ -85,6 +80,7 @@ public class CLProgram implements CLResource {
checkForError(err.get(), "can not create program with binary");
+ return new CLProgram(context, id);
}
private final void initBuildStatus() {
@@ -346,10 +342,6 @@ public class CLProgram implements CLResource {
}
}
- public CLContext getContext() {
- return context;
- }
-
/**
* Returns all devices associated with this program.
*/
diff --git a/src/com/mbien/opencl/CLSampler.java b/src/com/mbien/opencl/CLSampler.java
index 6732abaf..e12fc43b 100644
--- a/src/com/mbien/opencl/CLSampler.java
+++ b/src/com/mbien/opencl/CLSampler.java
@@ -5,32 +5,28 @@ import java.nio.Buffer;
import static com.mbien.opencl.CLException.*;
import static com.mbien.opencl.CL.*;
+import static com.mbien.opencl.CLUtils.*;
/**
* Object representing an OpenCL sampler.
* @author Michael Bien
*/
-public class CLSampler implements CLResource {
-
- public final long ID;
-
- private final CLContext context;
- private final CL cl;
+public class CLSampler extends CLObject implements CLResource {
private final CLSamplerInfoAccessor samplerInfo;
- CLSampler(CLContext context, AddressingMode addrMode, FilteringMode filtMode, boolean normalizedCoords) {
-
- this.context = context;
- this.cl = context.cl;
-
+ private CLSampler(CLContext context, long id, AddressingMode addrMode, FilteringMode filtMode, boolean normalizedCoords) {
+ super(context, id);
this.samplerInfo = new CLSamplerInfoAccessor();
+ }
+ static CLSampler create(CLContext context, AddressingMode addrMode, FilteringMode filtMode, boolean normalizedCoords) {
int[] error = new int[1];
- ID = cl.clCreateSampler(context.ID, normalizedCoords?CL_TRUE:CL_FALSE, addrMode.MODE, filtMode.MODE, error, 0);
+ long id = context.cl.clCreateSampler(context.ID, clBoolean(normalizedCoords), addrMode.MODE, filtMode.MODE, error, 0);
checkForError(error[0], "can not create sampler");
+ return new CLSampler(context, id, addrMode, filtMode, normalizedCoords);
}
public FilteringMode getFilteringMode() {
diff --git a/src/com/mbien/opencl/CLUtils.java b/src/com/mbien/opencl/CLUtils.java
index 03fb559c..0f948175 100644
--- a/src/com/mbien/opencl/CLUtils.java
+++ b/src/com/mbien/opencl/CLUtils.java
@@ -25,6 +25,20 @@ class CLUtils {
}
}
+ /**
+ * Returns true if clBoolean == CL.CL_TRUE.
+ */
+ public static boolean clBoolean(int clBoolean) {
+ return clBoolean == CL.CL_TRUE;
+ }
+
+ /**
+ * Returns b ? CL.CL_TRUE : CL.CL_FALSE
+ */
+ public static int clBoolean(boolean b) {
+ return b ? CL.CL_TRUE : CL.CL_FALSE;
+ }
+
public static Map<String, String> obtainPlatformProperties(CLPlatform platform) {
Map<String, String> map = new LinkedHashMap<String, String>();