Java tutorial
/* # Crowdsourcing experiments using mobile devices # provided by volunteers # (current scenario: program multi-objective crowdtuning # and SW/HW co-design) # # (C)opyright, Grigori Fursin and non-profit cTuning foundation # 2015-2016 # BSD 3-clause license # # Powered by Collective Knowledge # http://github.com/ctuning/ck */ package openscience.crowdsource.experiments; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.opengl.GLSurfaceView; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.support.v7.app.AppCompatActivity; import android.util.Base64; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.CheckBox; import android.widget.EditText; import org.ctuning.openme.openme; import org.json.JSONException; import org.json.JSONObject; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.FileReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.URL; import java.net.URLConnection; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.List; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; public class MainActivity extends AppCompatActivity implements GLSurfaceView.Renderer { String welcome = "We would like to thank you for participating in experiment crowdsourcing " + "to collaboratively solve complex problems!\n\n" + "One of the available scenarios is collaborative optimization of computer systems: " + "computers become very inefficient and it is not uncommon to get 10x speedups, " + " 2x size reduction and 40% energy reductions" + " for popular algorithms (DNN, vision, BLAS) - see \"About\". " + "We have developed collaborative scenario to crowdsource program autotuning" + " across various Android mobile devices and apply machine learning" + " to predict optimal optimizations!\n\n" + "NOTE: we strongly suggest you to have an access to unlimited internet" + " to download differently optimized kernels with various data sets," + " run them on your mobile device, and send execution statistics back" + " to a public Collective Knowledge Server!\n\n" + "We would like to sincerely thank you for supporting our reproducible and open science initiatives" + " and helping us optimize computer systems to accelerate knowledge discovery," + " boost innovation in science and technology, and make our planet greener!\n\n"; String problem = "maybe it is overloaded or down - please report this problem via collective-knowledge@googlegroups.com !"; String path_opencl = "/system/vendor/lib/libOpenCL.so"; String s_line = "====================================\n"; String s_line1 = "------------------------------------\n"; String url_sdk = "http://github.com/ctuning/ck"; String url_about = "https://github.com/ctuning/ck/wiki/Advanced_usage_crowdsourcing"; String url_stats = "http://cTuning.org/crowd-results"; String url_users = "http://cTuning.org/crowdtuning-timeline"; String url_cserver = "http://cTuning.org/shared-computing-resources-json/ck.json"; String repo_uoa = "upload"; String s_b_start = "Start"; String s_b_stop = "Exit"; String s_thanks = "Thank you for participation!\n"; int iterations = 1; static String email = ""; EditText log = null; Button b_start = null; String cemail = "email.txt"; String path1 = "ck-crowdtuning"; private AsyncTask crowdTask = null; Boolean running = false; static String pf_gpu = ""; static String pf_gpu_vendor = ""; static String path = ""; // Path to local tmp files static String path0 = ""; static Button b_clean; EditText t_email; private GLSurfaceView glSurfaceView; String fpack = "ck-pack.zip"; String chmod744 = "/system/bin/chmod 744"; boolean skip_freq_check = true; /*************************************************************************/ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); b_start = (Button) findViewById(R.id.b_start); b_start.setText(s_b_start); t_email = (EditText) findViewById(R.id.t_email); addListenersOnButtons(); log = (EditText) findViewById(R.id.log); log.append(welcome); // Getting local tmp path (for this app) File fpath = getFilesDir(); path0 = fpath.toString(); path = path0 + '/' + path1; File fp = new File(path); if (!fp.exists()) { if (!fp.mkdirs()) { log.append("\nERROR: can't create directory for local tmp files!\n"); return; } } /* Read config */ email = read_one_string_file(path0 + '/' + cemail); if (email == null) email = ""; if (!email.equals("")) { t_email.setText(email.trim()); } this.glSurfaceView = new GLSurfaceView(this); this.glSurfaceView.setRenderer(this); ((ViewGroup) log.getParent()).addView(this.glSurfaceView); try { Thread.sleep(500); } catch (InterruptedException e) { } } /*************************************************************************/ public void addListenersOnButtons() { Button b_sdk = (Button) findViewById(R.id.b_sdk); Button b_about = (Button) findViewById(R.id.b_about); b_clean = (Button) findViewById(R.id.b_clean); Button b_stats = (Button) findViewById(R.id.b_stats); Button b_users = (Button) findViewById(R.id.b_users); /*************************************************************************/ b_sdk.setOnClickListener(new View.OnClickListener() { @SuppressWarnings({ "unused", "unchecked" }) @Override public void onClick(View arg0) { log.append("\nOpening " + url_sdk + " ...\n"); Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url_sdk)); startActivity(browserIntent); } }); /*************************************************************************/ b_about.setOnClickListener(new View.OnClickListener() { @SuppressWarnings({ "unused", "unchecked" }) @Override public void onClick(View arg0) { log.append("\nOpening " + url_about + " ...\n"); Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url_about)); startActivity(browserIntent); } }); /*************************************************************************/ b_clean.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { log.setText(""); log.setText("Cleaning local tmp files ...\n"); if (!clean_log_tmp()) log.setText(" ERROR: Can't create directory " + path + " ...\n"); } }); /*************************************************************************/ b_stats.setOnClickListener(new View.OnClickListener() { @SuppressWarnings({ "unused", "unchecked" }) @Override public void onClick(View arg0) { log.append("\nOpening " + url_stats + " ...\n"); Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url_stats)); startActivity(browserIntent); } }); /*************************************************************************/ b_users.setOnClickListener(new View.OnClickListener() { @SuppressWarnings({ "unused", "unchecked" }) @Override public void onClick(View arg0) { log.append("\nOpening " + url_users + " ...\n"); Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url_users)); startActivity(browserIntent); } }); /*************************************************************************/ b_start.setOnClickListener(new View.OnClickListener() { @SuppressWarnings({ "unused", "unchecked" }) @Override public void onClick(View arg0) { if (running) { running = false; b_start.setEnabled(false); log.append(s_line); log.append(s_thanks); log.append("Interrupting crowd-tuning and quitting program ..."); Handler handler = new Handler(); handler.postDelayed(new Runnable() { public void run() { finish(); System.exit(0); } }, 1500); } else { running = true; b_start.setText(s_b_stop); b_clean.setEnabled(false); String email1 = t_email.getText().toString().replaceAll("(\\r|\\n)", ""); if (email1.equals("")) { email1 = openme.gen_uid(); } if (!email1.equals(email)) { email = email1; String pp = path0 + '/' + cemail; if (!save_one_string_file(pp, email)) { log.append("ERROR: can't write local configuration (" + pp + "!"); return; } } CheckBox c_continuous = (CheckBox) findViewById(R.id.c_continuous); if (c_continuous.isChecked()) iterations = -1; crowdTask = new runCodeAsync().execute(""); } } }); } /*************************************************************************/ private void alertbox(String title, String mymessage) { // TODO Auto-generated method stub new AlertDialog.Builder(this).setMessage(mymessage).setTitle(title).setCancelable(true) .setNeutralButton(android.R.string.ok, new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { } }).show(); } /*************************************************************************/ /* delete files and directories recursively */ private void rmdirs(File start) { if (start.isDirectory()) { for (File leaf : start.listFiles()) rmdirs(leaf); } start.delete(); } /*************************************************************************/ /* read one string file */ private String read_one_string_file(String fname) { String ret = null; Boolean fail = false; BufferedReader fp = null; try { fp = new BufferedReader(new FileReader(fname)); } catch (IOException ex) { fail = true; } if (!fail) { try { ret = fp.readLine(); } catch (IOException ex) { fail = true; } } try { if (fp != null) fp.close(); } catch (IOException ex) { fail = true; } return ret; } /*************************************************************************/ /* read one string file */ private boolean save_one_string_file(String fname, String text) { FileOutputStream o = null; try { o = new FileOutputStream(fname, false); } catch (FileNotFoundException e) { return false; } OutputStreamWriter oo = new OutputStreamWriter(o); try { oo.append(text); oo.flush(); oo.close(); } catch (IOException e) { return false; } return true; } /*************************************************************************/ /* exchange info with CK server */ private JSONObject exchange_info_with_ck_server(JSONObject ii) { JSONObject r = null; try { r = openme.remote_access(ii); } catch (JSONException e) { try { r = new JSONObject(); r.put("return", 32); r.put("error", "Error calling OpenME interface (" + e.getMessage() + ")"); } catch (JSONException e1) { return null; } return r; } int rr = 0; if (!r.has("return")) { try { r = new JSONObject(); r.put("return", 32); r.put("error", "Error obtaining key 'return' from OpenME output"); } catch (JSONException e1) { return null; } return r; } try { Object rx = r.get("return"); if (rx instanceof String) rr = Integer.parseInt((String) rx); else rr = (Integer) rx; } catch (JSONException e) { try { r = new JSONObject(); r.put("return", 32); r.put("error", "Error obtaining key 'return' from OpenME output (" + e.getMessage() + ")"); } catch (JSONException e1) { return null; } return r; } //Update return with integer try { r.put("return", rr); } catch (JSONException e) { } if (rr > 0) { String err = ""; try { err = (String) r.get("error"); } catch (JSONException e) { try { r = new JSONObject(); r.put("return", 32); r.put("error", "Error obtaining key 'error' from OpenME output (" + e.getMessage() + ")"); } catch (JSONException e1) { return null; } } } return r; } /*************************************************************************/ boolean clean_log_tmp() { File fp = new File(path); rmdirs(fp); if (!fp.mkdirs()) { return false; } return true; } /*************************************************************************/ /* get CPU frequencies */ private List<Double[]> get_cpu_freqs() { int num_procs = 0; List<Double[]> cpu_list = new ArrayList<Double[]>(); JSONObject r = null; String xpath = ""; String val = ""; double fval = 0; for (int i = 0; i < 1024; i++) { Double[] cpu = new Double[3]; // Check if online xpath = "/sys/devices/system/cpu/cpu" + Integer.toString(i) + "/online"; val = read_one_string_file(xpath); if (val == null) break; val = val.trim(); fval = 0; if (!val.equals("")) fval = Float.parseFloat(val); cpu[0] = fval; // Check max freq xpath = "/sys/devices/system/cpu/cpu" + Integer.toString(i) + "/cpufreq/cpuinfo_max_freq"; val = read_one_string_file(xpath); if (val == null) val = ""; val = val.trim(); fval = 0; if (!val.equals("")) fval = Float.parseFloat(val) / 1E3; cpu[1] = fval; // Check max freq xpath = "/sys/devices/system/cpu/cpu" + Integer.toString(i) + "/cpufreq/scaling_cur_freq"; val = read_one_string_file(xpath); if (val == null) val = ""; val = val.trim(); fval = 0; if (!val.equals("")) fval = Float.parseFloat(val) / 1E3; cpu[2] = fval; //adding to final array cpu_list.add(cpu); } return cpu_list; } @Override public void onSurfaceCreated(GL10 gl10, EGLConfig config) { pf_gpu_vendor = gl10.glGetString(GL10.GL_VENDOR); if (pf_gpu_vendor.equals("null")) pf_gpu_vendor = ""; String x = gl10.glGetString(GL10.GL_RENDERER); if (x.equals("null")) pf_gpu = ""; else pf_gpu = pf_gpu_vendor + " " + x; runOnUiThread(new Runnable() { @Override public void run() { glSurfaceView.setVisibility(View.GONE); } }); } @Override public void onSurfaceChanged(GL10 gl, int width, int height) { // no-op } @Override public void onDrawFrame(GL10 gl) { // no-op } /*************************************************************************/ private class runCodeAsync extends AsyncTask<String, String, String> { /*************************************************************************/ public String get_shared_computing_resource(String url) { String s = ""; try { //Connect URL u = new URL(url); URLConnection urlc = u.openConnection(); BufferedReader br = new BufferedReader(new InputStreamReader(urlc.getInputStream())); String line = ""; while ((line = br.readLine()) != null) s += line + '\n'; br.close(); } catch (Exception e) { return "ERROR: " + e.getMessage(); } /* Trying to convert to dict from JSON */ JSONObject a = null; try { a = new JSONObject(s); } catch (JSONException e) { return "ERROR: Can't convert string to JSON:\n" + s + "\n(" + e.getMessage() + ")\n"; } /* For now just take default one, later add random or balancing */ JSONObject rs = null; try { if (a.has("default")) rs = (JSONObject) a.get("default"); if (rs != null) { if (rs.has("url")) s = (String) rs.get("url"); } } catch (JSONException e) { return "ERROR: Cant' convert string to JSON:\n" + s + "\n(" + e.getMessage() + ")\n"; } if (s == null) s = ""; else if (!s.endsWith("?")) s += "/?"; return s; } /*************************************************************************/ protected void onPostExecute(String x) { b_start.setText(s_b_start); b_clean.setEnabled(true); running = false; } /*************************************************************************/ protected void onProgressUpdate(String... values) { if (values[0] != "") { log.append(values[0]); log.setSelection(log.getText().length()); } else if (values[1] != "") { alertbox(values[1], values[2]); } } /*************************************************************************/ @Override protected String doInBackground(String... arg0) { String pf_system = ""; String pf_system_vendor = ""; String pf_system_model = ""; String pf_cpu = ""; String pf_cpu_subname = ""; String pf_cpu_features = ""; String pf_cpu_abi = ""; String pf_cpu_num = ""; String pf_gpu_opencl = ""; String pf_gpu_openclx = ""; String pf_memory = ""; String pf_os = ""; String pf_os_short = ""; String pf_os_long = ""; String pf_os_bits = "32"; JSONObject r = null; JSONObject ii = null; JSONObject ft_cpu = null; JSONObject ft_os = null; JSONObject ft_gpu = null; JSONObject ft_plat = null; JSONObject ft = null; JSONObject ftuoa = null; // Example of alert box for errors // publishProgress("", "Error", "Internal problem"); /*********** Printing local tmp directory **************/ publishProgress(s_line); publishProgress("Local tmp directory: " + path + "\n"); publishProgress("User ID: " + email + "\n"); /*********** Obtaining CK server **************/ publishProgress(s_line); publishProgress("Obtaining list of public Collective Knowledge servers from " + url_cserver + " ...\n"); String curl = get_shared_computing_resource(url_cserver); publishProgress("\n"); if (curl.startsWith("ERROR")) { publishProgress(curl); publishProgress("\n"); return null; } else { publishProgress("Public Collective Knowledge Server found:\n"); publishProgress(curl); publishProgress("\n"); } publishProgress("\n"); publishProgress("Testing Collective Knowledge server ...\n"); ii = new JSONObject(); try { ii.put("remote_server_url", curl); ii.put("action", "test"); ii.put("module_uoa", "program.optimization"); ii.put("email", email); ii.put("type", "mobile-crowdtuning"); ii.put("out", "json"); } catch (JSONException e) { publishProgress("\nError with JSONObject ...\n\n"); return null; } try { r = openme.remote_access(ii); } catch (JSONException e) { publishProgress("\nError calling OpenME interface (" + e.getMessage() + ") ...\n\n"); return null; } int rr = 0; if (!r.has("return")) { publishProgress("\nError obtaining key 'return' from OpenME output ...\n\n"); return null; } try { Object rx = r.get("return"); if (rx instanceof String) rr = Integer.parseInt((String) rx); else rr = (Integer) rx; } catch (JSONException e) { publishProgress( "\nError obtaining key 'return' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } if (rr > 0) { String err = ""; try { err = (String) r.get("error"); } catch (JSONException e) { publishProgress( "\nError obtaining key 'error' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } publishProgress("\nProblem accessing CK server: " + err + "\n"); publishProgress("\nPossible reason: " + problem + "\n"); return null; } String status = ""; try { status = (String) r.get("status"); } catch (JSONException e) { publishProgress( "\nError obtaining key 'string' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } publishProgress(" " + status + "\n"); /*********** Getting local information about platform **************/ publishProgress(s_line); publishProgress("Detecting some of your platform features ...\n"); //Get system info ************************************************** try { r = openme.read_text_file_and_convert_to_json("/system/build.prop", "=", false, false); } catch (JSONException e) { publishProgress("\nError calling OpenME interface (" + e.getMessage() + ") ...\n\n"); return null; } try { if ((Long) r.get("return") > 0) publishProgress("\nProblem during OpenME: " + (String) r.get("error") + "\n\n"); } catch (JSONException e) { publishProgress("\nError calling OpenME interface (" + e.getMessage() + ") ...\n\n"); return null; } String model = ""; String manu = ""; JSONObject ra = null; try { ra = (JSONObject) r.get("dict"); } catch (JSONException e) { publishProgress("\nError calling OpenME interface (" + e.getMessage() + ") ...\n\n"); return null; } if (ra != null) { try { model = (String) ra.get("ro.product.model"); } catch (JSONException e) { publishProgress("\nError calling OpenME interface (" + e.getMessage() + ") ...\n\n"); return null; } try { manu = (String) ra.get("ro.product.manufacturer"); } catch (JSONException e) { publishProgress("\nError calling OpenME interface (" + e.getMessage() + ") ...\n\n"); return null; } if (!model.equals("") && !manu.equals("")) if (model.toLowerCase().startsWith(manu.toLowerCase())) model = model.substring(manu.length() + 1, model.length()); if (manu.equals("") && !model.equals("")) manu = model; manu = manu.toUpperCase(); model = model.toUpperCase(); pf_system = manu; if (!model.equals("")) pf_system += ' ' + model; pf_system_model = model; pf_system_vendor = manu; } //Get processor info ************************************************** //It's not yet working properly on heterogeneous CPU, like big/little //So results can't be trusted and this part should be improved! try { r = openme.read_text_file_and_convert_to_json("/proc/cpuinfo", ":", false, false); } catch (JSONException e) { publishProgress("\nError calling OpenME interface (" + e.getMessage() + ") ...\n\n"); return null; } try { if ((Long) r.get("return") > 0) publishProgress("\nProblem during OpenME: " + (String) r.get("error") + "\n\n"); } catch (JSONException e) { publishProgress("\nError calling OpenME interface (" + e.getMessage() + ") ...\n\n"); return null; } String processor_file = null; try { processor_file = (String) r.get("file_as_string"); } catch (JSONException e) { publishProgress("\nError calling OpenME interface (" + e.getMessage() + ") ...\n\n"); return null; } if (processor_file == null) processor_file = ""; try { ra = (JSONObject) r.get("dict"); } catch (JSONException e) { publishProgress("\nError calling OpenME interface (" + e.getMessage() + ") ...\n\n"); return null; } if (ra != null) { String x1 = null; String x2 = null; String x3 = null; String x4 = null; try { x1 = (String) ra.get("Processor"); } catch (JSONException e) { } try { x2 = (String) ra.get("model_name"); } catch (JSONException e) { } try { x3 = (String) ra.get("Hardware"); } catch (JSONException e) { } try { x4 = (String) ra.get("Features"); } catch (JSONException e) { } if (x2 != null && !x2.equals("")) pf_cpu_subname = x2; else if (x1 != null && !x1.equals("")) pf_cpu_subname = x1; if (x3 != null) pf_cpu = x3; if (x4 != null) pf_cpu_features = x4; // On Intel-based Android if (pf_cpu.equals("") && !pf_cpu_subname.equals("")) pf_cpu = pf_cpu_subname; // If CPU is empty, possibly new format if (pf_cpu.equals("")) { String ic1 = ""; String ic2 = ""; String ic3 = ""; String ic4 = ""; String ic5 = ""; try { ic1 = (String) ra.get("CPU implementer"); } catch (JSONException e) { } try { ic2 = (String) ra.get("CPU architecture"); } catch (JSONException e) { } try { ic3 = (String) ra.get("CPU variant"); } catch (JSONException e) { } try { ic4 = (String) ra.get("CPU part"); } catch (JSONException e) { } try { ic5 = (String) ra.get("CPU revision"); } catch (JSONException e) { } pf_cpu += ic1 + "-" + ic2 + "-" + ic3 + "-" + ic4 + "-" + ic5; } // If CPU is still empty, send report to CK to fix ... if (pf_cpu.equals("")) { publishProgress( "\nPROBLEM: we could not detect CPU name and features on your device :( ! Please, report to authors!\n\n"); ii = new JSONObject(); try { ii.put("remote_server_url", curl); ii.put("action", "problem"); ii.put("module_uoa", "program.optimization"); ii.put("email", email); ii.put("problem", "mobile_crowdtuning_cpu_name_empty"); ii.put("problem_data", processor_file); ii.put("out", "json"); } catch (JSONException e) { publishProgress("\nError with JSONObject ...\n\n"); return null; } try { r = openme.remote_access(ii); } catch (JSONException e) { publishProgress("\nError calling OpenME interface (" + e.getMessage() + ") ...\n\n"); return null; } rr = 0; if (!r.has("return")) { publishProgress("\nError obtaining key 'return' from OpenME output ...\n\n"); return null; } try { Object rx = r.get("return"); if (rx instanceof String) rr = Integer.parseInt((String) rx); else rr = (Integer) rx; } catch (JSONException e) { publishProgress("\nError obtaining key 'return' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } if (rr > 0) { String err = ""; try { err = (String) r.get("error"); } catch (JSONException e) { publishProgress("\nError obtaining key 'error' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } publishProgress("\nProblem accessing CK server: " + err + "\n"); return null; } return null; } } //Get memory info ************************************************** try { r = openme.read_text_file_and_convert_to_json("/proc/meminfo", ":", false, false); } catch (JSONException e) { publishProgress("\nError calling OpenME interface (" + e.getMessage() + ") ...\n\n"); return null; } try { if ((Long) r.get("return") > 0 && (Long) r.get("return") != 16) publishProgress("\nProblem during OpenME: " + (String) r.get("error") + "\n\n"); } catch (JSONException e) { publishProgress("\nError calling OpenME interface (" + e.getMessage() + ") ...\n\n"); return null; } try { ra = (JSONObject) r.get("dict"); } catch (JSONException e) { publishProgress("\nError calling OpenME interface (" + e.getMessage() + ") ...\n\n"); return null; } if (ra != null) { String mem_tot = ""; try { mem_tot = (String) ra.get("memtotal"); } catch (JSONException e) { } if (mem_tot == null || mem_tot.equals("")) try { mem_tot = (String) ra.get("MemTotal"); } catch (JSONException e) { } if (mem_tot != null && !mem_tot.equals("")) { int i = mem_tot.indexOf(' '); if (i > 0) { String mem1 = mem_tot.substring(0, i).trim(); String mem2 = "1"; if (mem1.length() > 3) mem2 = mem1.substring(0, mem1.length() - 3); pf_memory = mem2 + " MB"; } } } //Get available processors and frequencies ************************************************** List<Double[]> cpus = get_cpu_freqs(); Double[] cpu = null; int cpu_num = cpus.size(); pf_cpu_num = Integer.toString(cpu_num); pf_cpu_abi = Build.CPU_ABI; //System.getProperty("os.arch"); - not exactly the same! //Get OS info ************************************************** pf_os = "Android " + android.os.Build.VERSION.RELEASE; try { r = openme.read_text_file_and_convert_to_json("/proc/version", ":", false, false); } catch (JSONException e) { publishProgress("\nError calling OpenME interface (" + e.getMessage() + ") ...\n\n"); return null; } try { if ((Long) r.get("return") > 0) publishProgress("\nProblem during OpenME: " + (String) r.get("error") + "\n\n"); } catch (JSONException e) { publishProgress("\nError calling OpenME interface (" + e.getMessage() + ") ...\n\n"); return null; } try { pf_os_long = (String) r.get("file_as_string"); } catch (JSONException e) { } if (pf_os_long == null) pf_os_long = ""; else { pf_os_long = pf_os_long.trim(); pf_os_short = pf_os_long; int ix = pf_os_long.indexOf(" ("); if (ix >= 0) { int ix1 = pf_os_long.indexOf("-"); if (ix1 >= 0 && ix1 < ix) ix = ix1; pf_os_short = pf_os_long.substring(0, ix).trim(); } } int ix = pf_os_long.indexOf("_64"); if (ix > 0) pf_os_bits = "64"; //Get OpenCL info ************************************************** File fopencl = new File(path_opencl); long lfopencl = fopencl.length(); if (lfopencl > 0) { pf_gpu_opencl = "libOpenCL.so - found (" + Long.toString(lfopencl) + " bytes)"; pf_gpu_openclx = "yes"; } else { pf_gpu_opencl = "libOpenCL.so - not found"; pf_gpu_openclx = "no"; } //Print ************************************************** publishProgress("\n"); publishProgress("PLATFORM: " + pf_system + "\n"); publishProgress("* VENDOR: " + pf_system_vendor + "\n"); publishProgress("* MODEL: " + pf_system_model + "\n"); publishProgress("OS: " + pf_os + "\n"); publishProgress("* SHORT: " + pf_os_short + "\n"); publishProgress("* LONG: " + pf_os_long + "\n"); publishProgress("* BITS: " + pf_os_bits + "\n"); publishProgress("MEMORY: " + pf_memory + "\n"); publishProgress("CPU: " + pf_cpu + "\n"); publishProgress("* SUBNAME: " + pf_cpu_subname + "\n"); publishProgress("* ABI: " + pf_cpu_abi + "\n"); publishProgress("* FEATURES: " + pf_cpu_features + "\n"); publishProgress("* CORES: " + pf_cpu_num + "\n"); for (int i = 0; i < cpu_num; i++) { String x = " " + Integer.toString(i) + ") "; cpu = cpus.get(i); double x0 = cpu[0]; ; double x1 = cpu[1]; double x2 = cpu[2]; if (x0 == 0) x += "offline"; else x += "online; " + Double.toString(x2) + " of " + Double.toString(x1) + " MHz"; publishProgress(x + "\n"); } publishProgress("GPU: " + pf_gpu + "\n"); publishProgress("* VENDOR: " + pf_gpu_vendor + "\n"); publishProgress("* OPENCL: " + pf_gpu_opencl + "\n"); //Delay program for 1 sec try { Thread.sleep(1000); } catch (InterruptedException ex) { } //Communicate with CK ************************************************** JSONObject j_os, j_cpu, j_gpu, j_sys; String j_os_uid = ""; String j_cpu_uid = ""; String j_gpu_uid = ""; String j_sys_uid = ""; publishProgress(s_line); publishProgress( "Exchanging info about your platform with CK server to retrieve latest meta for crowdtuning ..."); ii = new JSONObject(); ft = new JSONObject(); // OS ****** publishProgress("\n Exchanging OS info ...\n"); try { ft_os = new JSONObject(); ft_os.put("name", pf_os); ft_os.put("name_long", pf_os_long); ft_os.put("name_short", pf_os_short); ft_os.put("bits", pf_os_bits); ft.put("features", ft_os); ii.put("remote_server_url", curl); ii.put("action", "exchange"); ii.put("module_uoa", "platform"); ii.put("sub_module_uoa", "platform.os"); ii.put("data_name", pf_os); ii.put("repo_uoa", repo_uoa); ii.put("all", "yes"); ii.put("dict", ft); ii.put("out", "json"); } catch (JSONException e) { publishProgress("\nError with JSONObject ...\n\n"); return null; } j_os = exchange_info_with_ck_server(ii); try { Object rx = j_os.get("return"); if (rx instanceof String) rr = Integer.parseInt((String) rx); else rr = (Integer) rx; } catch (JSONException e) { publishProgress( "\nError obtaining key 'return' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } if (rr > 0) { String err = ""; try { err = (String) j_os.get("error"); } catch (JSONException e) { publishProgress( "\nError obtaining key 'error' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } publishProgress("\nProblem accessing CK server: " + err + "\n"); return null; } else { String found = ""; try { found = (String) j_os.get("found"); } catch (JSONException e) { } if (found.equals("yes")) { try { j_os_uid = (String) j_os.get("data_uid"); } catch (JSONException e) { } String x = " Already exists"; if (!j_os_uid.equals("")) x += " (CK UOA=" + j_os_uid + ")"; x += "!\n"; publishProgress(x); } } // GPU ****** if (!pf_gpu.equals("")) { publishProgress(" Exchanging GPU info ...\n"); try { ft_gpu = new JSONObject(); ft_gpu.put("name", pf_gpu); ft_gpu.put("vendor", pf_gpu_vendor); ft.put("features", ft_gpu); ii.put("remote_server_url", curl); ii.put("action", "exchange"); ii.put("module_uoa", "platform"); ii.put("sub_module_uoa", "platform.gpu"); ii.put("data_name", pf_gpu); ii.put("repo_uoa", repo_uoa); ii.put("all", "yes"); ii.put("dict", ft); ii.put("out", "json"); } catch (JSONException e) { publishProgress("\nError with JSONObject ...\n\n"); return null; } j_gpu = exchange_info_with_ck_server(ii); try { Object rx = j_gpu.get("return"); if (rx instanceof String) rr = Integer.parseInt((String) rx); else rr = (Integer) rx; } catch (JSONException e) { publishProgress( "\nError obtaining key 'return' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } if (rr > 0) { String err = ""; try { err = (String) j_gpu.get("error"); } catch (JSONException e) { publishProgress("\nError obtaining key 'error' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } publishProgress("\nProblem accessing CK server: " + err + "\n"); return null; } else { String found = ""; try { found = (String) j_gpu.get("found"); } catch (JSONException e) { } if (found.equals("yes")) { try { j_gpu_uid = (String) j_gpu.get("data_uid"); } catch (JSONException e) { } String x = " Already exists"; if (!j_gpu_uid.equals("")) x += " (CK UOA=" + j_gpu_uid + ")"; x += "!\n"; publishProgress(x); } } } // CPU ****** publishProgress(" Exchanging CPU info ...\n"); try { ft_cpu = new JSONObject(); ft_cpu.put("name", pf_cpu); ft_cpu.put("sub_name", pf_cpu_subname); ft_cpu.put("cpu_features", pf_cpu_features); ft_cpu.put("cpu_abi", pf_cpu_abi); ft_cpu.put("num_proc", pf_cpu_num); JSONObject freq_max = new JSONObject(); for (int i = 0; i < cpu_num; i++) { String x = " " + Integer.toString(i) + ") "; cpu = cpus.get(i); double x1 = cpu[1]; if (x1 != 0) freq_max.put(Integer.toString(i), x1); } ft_cpu.put("max_freq", freq_max); ft.put("features", ft_cpu); ii.put("remote_server_url", curl); ii.put("action", "exchange"); ii.put("module_uoa", "platform"); ii.put("sub_module_uoa", "platform.cpu"); ii.put("data_name", pf_cpu); ii.put("repo_uoa", repo_uoa); ii.put("all", "yes"); ii.put("dict", ft); ii.put("out", "json"); } catch (JSONException e) { publishProgress("\nError with JSONObject ...\n\n"); return null; } j_cpu = exchange_info_with_ck_server(ii); try { Object rx = j_cpu.get("return"); if (rx instanceof String) rr = Integer.parseInt((String) rx); else rr = (Integer) rx; } catch (JSONException e) { publishProgress( "\nError obtaining key 'return' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } if (rr > 0) { String err = ""; try { err = (String) j_cpu.get("error"); } catch (JSONException e) { publishProgress( "\nError obtaining key 'error' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } publishProgress("\nProblem accessing CK server: " + err + "\n"); return null; } else { String found = ""; try { found = (String) j_cpu.get("found"); } catch (JSONException e) { } if (found.equals("yes")) { try { j_cpu_uid = (String) j_cpu.get("data_uid"); } catch (JSONException e) { } String x = " Already exists"; if (!j_cpu_uid.equals("")) x += " (CK UOA=" + j_cpu_uid + ")"; x += "!\n"; publishProgress(x); } } // Platform ****** publishProgress(" Exchanging platform info ...\n"); try { ft_plat = new JSONObject(); ft_plat.put("name", pf_system); ft_plat.put("vendor", pf_system_vendor); ft_plat.put("model", pf_system_model); ft.put("features", ft_plat); ii.put("remote_server_url", curl); ii.put("action", "exchange"); ii.put("module_uoa", "platform"); ii.put("sub_module_uoa", "platform"); ii.put("data_name", pf_system); ii.put("repo_uoa", repo_uoa); ii.put("all", "yes"); ii.put("dict", ft); ii.put("out", "json"); } catch (JSONException e) { publishProgress("\nError with JSONObject ...\n\n"); return null; } j_sys = exchange_info_with_ck_server(ii); try { Object rx = j_sys.get("return"); if (rx instanceof String) rr = Integer.parseInt((String) rx); else rr = (Integer) rx; } catch (JSONException e) { publishProgress( "\nError obtaining key 'return' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } if (rr > 0) { String err = ""; try { err = (String) j_sys.get("error"); } catch (JSONException e) { publishProgress( "\nError obtaining key 'error' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } publishProgress("\nProblem accessing CK server: " + err + "\n"); return null; } else { String found = ""; try { found = (String) j_sys.get("found"); } catch (JSONException e) { } if (found.equals("yes")) { try { j_sys_uid = (String) j_sys.get("data_uid"); } catch (JSONException e) { } String x = " Already exists"; if (!j_sys_uid.equals("")) x += " (CK UOA=" + j_sys_uid + ")"; x += "!\n"; publishProgress(x); } } //Delay program for 1 sec try { Thread.sleep(1000); } catch (InterruptedException ex) { } /*********** Starting iterations **************/ int iter = 0; while ((iterations == -1) || (iter < iterations)) { if (!running) break; iter += 1; publishProgress(s_line); publishProgress("Iteration: " + Integer.toString(iter)); if (iterations == -1) publishProgress(" (continuous)"); publishProgress("\n\n"); /*********** Cleaning local files **************/ publishProgress(" Cleaning local tmp files ...\n"); if (!clean_log_tmp()) { publishProgress(" ERROR: can't create local tmp directory " + path + " ..."); running = false; return null; } /*######################################################################################################*/ publishProgress( "\n Generating and downloading experiment crowdsourcing pack from CK server for your mobile device - typical size between 50KB and 1.2MB - it may sometimes take a few minutes - please, wait.\n\nNOTE that if there is no response for too long likely due to too slow Internet connection (say 3 minutes), try to exit application and start it again... Also note that some newly generated binaries may crash on your devices due to internal bugs - don't worry and start new experiment (this info also helps the community crowdsource compiler bug detection) ...\n\n"); ii = new JSONObject(); try { ft = new JSONObject(); ft.put("cpu", ft_cpu); ft.put("cpu_uid", j_cpu_uid); ft.put("cpu_uoa", j_cpu_uid); ft.put("gpu", ft_gpu); ft.put("gpu_uid", j_gpu_uid); ft.put("gpu_uoa", j_gpu_uid); // Need to tell CK server if OpenCL present // for collaborative OpenCL optimization using mobile devices JSONObject ft_gpu_misc = new JSONObject(); ft_gpu_misc.put("opencl_lib_present", pf_gpu_openclx); ft.put("gpu_misc", ft_gpu_misc); ft.put("os", ft_os); ft.put("os_uid", j_os_uid); ft.put("os_uoa", j_os_uid); ft.put("platform", ft_plat); ft.put("platform_uid", j_sys_uid); ft.put("platform_uoa", j_sys_uid); ii.put("remote_server_url", curl); ii.put("action", "crowdsource"); ii.put("new_engine", "yes"); // request new CK crowdtuning engine ii.put("module_uoa", "experiment"); ii.put("tags", "crowdsource-via-mobile"); ii.put("once", "yes"); ii.put("email", email); ii.put("platform_features", ft); ii.put("out", "json"); } catch (JSONException e) { publishProgress("\nError with JSONObject ...\n\n"); return null; } try { r = openme.remote_access(ii); } catch (JSONException e) { publishProgress("\nError calling OpenME interface (" + e.getMessage() + ") ...\n\n"); return null; } rr = 0; if (!r.has("return")) { publishProgress("\nError obtaining key 'return' from OpenME output ...\n\n"); return null; } try { Object rx = r.get("return"); if (rx instanceof String) rr = Integer.parseInt((String) rx); else rr = (Integer) rx; } catch (JSONException e) { publishProgress( "\nError obtaining key 'return' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } if (rr > 0) { String err = ""; try { err = (String) r.get("error"); } catch (JSONException e) { publishProgress("\nError obtaining key 'error' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } // if (err.length()>256) err=err.substring(0,255) + " ..."; publishProgress("\nProblem at CK server: " + err + "\n"); return null; } String queue_uid = ""; // Check that got request ID try { queue_uid = (String) r.get("queue_uid"); } catch (JSONException e) { publishProgress( "\nError obtaining key 'queue_uid' from CK server (" + e.getMessage() + ") ...\n\n"); return null; } publishProgress("CK server queue UID received: " + queue_uid + "\n\n"); //Waiting for response String crowd_uid = ""; int ncheck = 10; for (int check = 0; check < ncheck; check++) { publishProgress("Waiting for a crowd-pack from CK server (15 sec.)\n"); //Delay program for 15 sec try { Thread.sleep(15000); } catch (InterruptedException ex) { } publishProgress(" Querying server (attempt " + Integer.toString(check + 1) + " of " + Integer.toString(ncheck) + ") ...\n"); ii = new JSONObject(); try { ii.put("remote_server_url", curl); ii.put("action", "check"); ii.put("module_uoa", "program.optimization.mobile"); ii.put("queue_uid", queue_uid); ii.put("out", "json"); } catch (JSONException e) { publishProgress("\nError with JSONObject ...\n\n"); return null; } try { r = openme.remote_access(ii); } catch (JSONException e) { publishProgress("\nError calling OpenME interface (" + e.getMessage() + ") ...\n\n"); return null; } rr = 0; if (!r.has("return")) { publishProgress("\nError obtaining key 'return' from OpenME output ...\n\n"); return null; } try { Object rx = r.get("return"); if (rx instanceof String) rr = Integer.parseInt((String) rx); else rr = (Integer) rx; } catch (JSONException e) { publishProgress("\nError obtaining key 'return' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } if (rr > 0) { String err = ""; try { err = (String) r.get("error"); } catch (JSONException e) { publishProgress("\nError obtaining key 'error' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } // if (err.length()>256) err=err.substring(0,255) + " ..."; publishProgress("\nProblem at CK server: " + err + "\n"); return null; } // Check that got request ID try { crowd_uid = (String) r.get("crowd_uid"); } catch (JSONException e) { publishProgress("\nError obtaining key 'crowd_uid' from CK server (" + e.getMessage() + ") ...\n\n"); return null; } if (!crowd_uid.equals("")) { publishProgress("\nCK server crowd UID received: " + crowd_uid + "\n\n"); break; } } if (crowd_uid.equals("")) { publishProgress("\nCK server did not return crowd-pack - " + problem + "\n"); return null; } // Start experiments String fcb64 = ""; String md5sum = ""; int size = 0; String desc = ""; String run_cmd_main = ""; String bin_file0 = ""; String bin_file1 = ""; long lbf0 = 0; long lbf1 = 0; int repeat = 5; String calibrate = "yes"; long ct_repeat = 1; int cmi = 10; double ct = 5.0; try { fcb64 = (String) r.get("file_content_base64"); } catch (JSONException e) { publishProgress("\nError obtaining key 'file_content_base64' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } try { md5sum = (String) r.get("md5sum"); } catch (JSONException e) { publishProgress( "\nError obtaining key 'md5sum' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } try { size = (Integer) r.get("size"); } catch (JSONException e) { publishProgress( "\nError obtaining key 'size' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } publishProgress(" * Crowd ID: " + crowd_uid + "\n"); publishProgress(" * Size: " + Integer.toString(size) + " bytes\n"); publishProgress(" * MD5: " + md5sum + "\n"); /* Checking MD5 */ publishProgress(" Checking MD5 sum ...\n"); StringBuffer hexString = new StringBuffer(); String md5test = ""; try { MessageDigest digest = java.security.MessageDigest.getInstance("MD5"); digest.update(fcb64.getBytes()); byte messageDigest[] = digest.digest(); for (int i = 0; i < messageDigest.length; i++) { int x = 0xFF & messageDigest[i]; String y = Integer.toHexString(x).toString(); if (x < 0x10) y = "0" + y; md5test += y; } } catch (NoSuchAlgorithmException e) { publishProgress("\nError calculating MD5 sum (" + e.getMessage() + ") ...\n\n"); return null; } if (!md5test.equals(md5sum)) { publishProgress(" ERROR: MD5 sum differs (" + md5test + ") \n"); return null; } else { publishProgress(" OK\n"); } /*********** Recording file **************/ publishProgress(" Recording obtained file to local directory ...\n"); byte[] pack; try { pack = Base64.decode(fcb64, Base64.URL_SAFE); } catch (Exception e) { publishProgress("\nError decoding received file (" + e.getMessage() + ") ...\n\n"); return null; } String xp = path + '/' + fpack; File ff = new File(xp); FileOutputStream fos = null; try { fos = new FileOutputStream(ff, true); } catch (FileNotFoundException e) { publishProgress("\nError creating tmp file (" + e.getMessage() + ") ...\n\n"); return null; } try { fos.write(pack); fos.flush(); fos.close(); } catch (IOException e) { publishProgress( "\nError recording obtained file to local tmp dir (" + e.getMessage() + ") ...\n\n"); return null; } /*********** Unzipping file **************/ publishProgress(" Unzipping file ...\n"); InputStream is; try { is = new FileInputStream(xp); } catch (FileNotFoundException e) { publishProgress("\nError creating InputStream (" + e.getMessage() + ") ...\n\n"); return null; } BufferedInputStream bis = new BufferedInputStream(is); ZipInputStream zis = new ZipInputStream(bis); byte[] buf = new byte[16384]; int cc; ZipEntry zz; try { while ((zz = zis.getNextEntry()) != null) { String fn = zz.getName(); String px = path + '/' + fn; if (zz.isDirectory()) { File pathfn = new File(px); pathfn.mkdirs(); } else { FileOutputStream fout = new FileOutputStream(px); while ((cc = zis.read(buf)) != -1) fout.write(buf, 0, cc); fout.close(); zis.closeEntry(); } /* If .so, make executable */ if (px.endsWith(".so")) { String[] ret = openme.openme_run_program(chmod744 + " ./" + fn, null, path); if (ret[0] != "") { publishProgress("\nError: failed to set permissions to library " + px + "\n(\n" + ret[0] + "\n" + ret[1] + "\n" + ret[2] + "\n)\nPlease, report above error to authors!\n"); return null; } } } } catch (IOException e) { publishProgress("\nError unzipping file (" + e.getMessage() + ") ...\n\n"); return null; } try { zis.close(); } catch (IOException e) { publishProgress("\nError closing zipfile (" + e.getMessage() + ") ...\n\n"); return null; } // Continue processing try { desc = (String) r.get("desc"); } catch (JSONException e) { publishProgress( "\nError obtaining key 'desc' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } try { run_cmd_main = (String) r.get("run_cmd_main"); } catch (JSONException e) { publishProgress("\nError obtaining key 'run_cmd_main' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } if (run_cmd_main.startsWith("\"") && run_cmd_main.endsWith("\"")) { run_cmd_main = run_cmd_main.substring(1, run_cmd_main.length() - 1); } try { bin_file0 = (String) r.get("bin_file0"); } catch (JSONException e) { publishProgress("\nError obtaining key 'bin_file0' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } try { bin_file1 = (String) r.get("bin_file1"); } catch (JSONException e) { } try { calibrate = (String) r.get("calibrate"); } catch (JSONException e) { } try { repeat = (Integer) r.get("repeat"); } catch (JSONException e) { } try { ct_repeat = (Integer) r.get("ct_repeat"); } catch (JSONException e) { } try { cmi = (Integer) r.get("calibrate_max_iters"); } catch (JSONException e) { } try { ct = (Double) r.get("calibrate_time"); } catch (JSONException e) { } // Check file sizes String y = path + '/' + bin_file0; File fxx = new File(y); if (!bin_file0.equals("") && fxx.exists()) lbf0 = fxx.length(); y = path + '/' + bin_file1; fxx = new File(y); if (!bin_file1.equals("") && fxx.exists()) lbf1 = fxx.length(); publishProgress(s_line); publishProgress(desc + "\n"); //Delay program for 1 sec try { Thread.sleep(2000); } catch (InterruptedException ex) { } //Start experiments ******************************************************** String cur_freq_string = ""; long startTime = 0; long totalTime = 0; long totalTime0 = -1; long totalTime0max = -1; long totalTime1 = -1; long totalTime1max = -1; float ft0 = 0; float ft0max = 0; float ft1 = 0; float ft1max = 0; String[] ret; List<Float> aft0 = new ArrayList<Float>(); List<Float> aft1 = new ArrayList<Float>(); List<Float> exec0 = new ArrayList<Float>(); List<Float> exec1 = new ArrayList<Float>(); double speedup = 0.0; /* Process first file */ String cmd = "./" + bin_file0 + " " + run_cmd_main; ret = openme.openme_run_program(chmod744 + " ./" + bin_file0, null, path); if (ret[0] != "") { publishProgress("\nError: failed to set 744 permissions to binary file " + bin_file0 + "\n(" + ret[0] + "\n" + ret[1] + "\n" + ret[2] + "\n)\nPlease, report above error to authors!\n"); return null; } /* Calibration, if supported (and warming up) */ if (calibrate.equals("yes")) { publishProgress(s_line1); publishProgress("Starting calibration ...\n"); publishProgress(" " + cmd); publishProgress("\n"); publishProgress("\n"); boolean calibration_finished = false; for (int c = 0; c < cmi && !calibration_finished; c++) { String[] env = { "CT_REPEAT_MAIN=" + String.valueOf(ct_repeat), "LD_LIBRARY_PATH=" + path }; startTime = System.currentTimeMillis(); ret = openme.openme_run_program(cmd, env, path); totalTime = System.currentTimeMillis() - startTime; //Debug - later send output to remote server too //for example to analyze output correctness, numerical stability, etc ... // publishProgress("\nX1="+ret[0]+"\n\n"); // publishProgress("\nX2="+ret[1]+"\n\n"); if (ret[0] != "") { publishProgress("\n"); publishProgress("Error: execution failure!\n(\n" + ret[0] + "\n" + ret[1] + "\n" + ret[2] + "\n)\nPlease, report above error to authors!\n"); return null; } ft0 = ((float) totalTime) / 1000; publishProgress(" Execution time=" + String.valueOf(ft0) + " sec.\n"); if (!calibration_finished) { long orepeat = ct_repeat; if (ft0 < 0.5) ct_repeat *= 10; else if (0.2 < (ct / ft0) && (ct / ft0) < 1.4) { calibration_finished = true; break; } else ct_repeat *= (float) (ct / ft0); if (ct_repeat == orepeat || ct_repeat < 1) { calibration_finished = true; break; } publishProgress( " * Calibration: CT_REPEAT_MAIN=" + String.valueOf(ct_repeat) + "\n"); } } if (!calibration_finished) { publishProgress("\nError: Calibration failed!\n\n"); return null; } publishProgress("\nCalibration finished: CT_REPEAT_MAIN=" + String.valueOf(ct_repeat) + "\n"); } /* Warming up ***********************************************************/ publishProgress(s_line1); publishProgress("Running program to warm up system and set frequency (if adaptive):\n"); publishProgress(" " + cmd); publishProgress("\n"); publishProgress("\n"); String[] envx = { "CT_REPEAT_MAIN=" + String.valueOf(ct_repeat), "LD_LIBRARY_PATH=" + path }; startTime = System.currentTimeMillis(); ret = openme.openme_run_program(cmd, envx, path); totalTime = System.currentTimeMillis() - startTime; if (ret[0] != "") { publishProgress("\n"); publishProgress("Error: execution failure!\n(\n" + ret[0] + "\n" + ret[1] + "\n" + ret[2] + "\n)\nPlease, report above error to authors!\n"); return null; } // First experiment ******************************************************* publishProgress(s_line1); publishProgress("Running default experiment ...\n"); publishProgress(" " + cmd); publishProgress("\n"); publishProgress("\n"); // Getting frequency 0 publishProgress(" Current frequency (to compare):\n"); List<Double[]> cpus0 = get_cpu_freqs(); Double[] cpu0 = null; int cpu_num0 = cpus.size(); List<Double[]> cpus5 = null; Double[] cpu5 = null; int cpu_num5 = 0; for (int i = 0; i < cpu_num0; i++) { String x = " " + Integer.toString(i) + ") "; cpu0 = cpus0.get(i); double x0 = cpu0[0]; ; double x1 = cpu0[1]; double x2 = cpu0[2]; if (x0 == 0) x += "offline"; else x += "online; " + Double.toString(x2) + " of " + Double.toString(x1) + " MHz"; publishProgress(x + "\n"); } publishProgress("\n"); rr = 0; while (rr < repeat) { publishProgress("Statistical repetition: " + String.valueOf(rr + 1) + " (CT_REPEAT_MAIN=" + String.valueOf(ct_repeat) + ")\n"); String[] env = { "CT_REPEAT_MAIN=" + String.valueOf(ct_repeat), "LD_LIBRARY_PATH=" + path }; startTime = System.currentTimeMillis(); ret = openme.openme_run_program(cmd, env, path); totalTime = System.currentTimeMillis() - startTime; if (ret[0] != "") { publishProgress("Error: execution failure!\n(\n" + ret[0] + "\n" + ret[1] + "\n" + ret[2] + "\n)\nPlease, report above error to authors!\n"); return null; } ft0 = ((float) totalTime) / 1000; publishProgress(" Execution time=" + String.valueOf(ft0) + " sec.\n"); exec0.add(ft0); publishProgress(" Current frequency:\n"); cpus5 = get_cpu_freqs(); cpu5 = null; cpu_num5 = cpus.size(); boolean freq_changed = false; for (int i = 0; i < cpu_num5; i++) { String x = " " + Integer.toString(i) + ") "; cpu5 = cpus5.get(i); double x0 = cpu5[0]; ; double x1 = cpu5[1]; double x2 = cpu5[2]; double y0 = 0; double y1 = 0; double y2 = 0; if (i < cpu_num0) { y0 = cpu0[0]; y1 = cpu0[1]; y2 = cpu0[2]; } x += Double.toString(x2) + " MHz vs " + Double.toString(y2) + " MHz"; publishProgress(x + "\n"); if (y2 == 0 && x2 != 0) { freq_changed = true; break; } if (y2 != 0) { double change = x2 / y2; if (change < 0.96 || change > 1.04) { freq_changed = true; break; } } } if (freq_changed && !skip_freq_check) { publishProgress(" frequency changed - skipping result\n"); } else { aft0.add(ft0); //Take minimal time if (totalTime0 == -1) totalTime0 = totalTime; else if (totalTime0 > totalTime) totalTime0 = totalTime; if (totalTime0max == -1) totalTime0max = totalTime; else if (totalTime0max < totalTime) totalTime0max = totalTime; } rr++; } if (totalTime0 <= 0) { publishProgress(" ERROR: Couldn't obtain stable execution time!\n"); break; } ft0 = ((float) totalTime0) / 1000; ft0max = ((float) totalTime0max) / 1000; float var = (ft0max - ft0) * 100 / ft0; publishProgress("\n"); publishProgress("Execution time (1): MIN=" + String.valueOf(ft0) + " sec.; VAR=" + String.format("%.1f", var) + "%\n"); if (var > 15) { publishProgress("\n"); publishProgress("Warning: execution time variation is too high, speed may not be trusted!"); publishProgress( "For the moment, we take lower bound of execution time, i.e. what we can squeeze from your architecture! "); publishProgress( "On the server, we have autotuning plugins to check normality and expected value of experimental results!\n"); } /* Running 2nd experiment ***************************************************/ if (!bin_file1.equals("")) { cmd = "./" + bin_file1 + " " + run_cmd_main; ret = openme.openme_run_program(chmod744 + " ./" + bin_file1, null, path); if (ret[0] != "") { publishProgress("\nError: failed to set 744 permissions to binary file " + bin_file1 + "\n(\n" + ret[0] + "\n" + ret[1] + "\n" + ret[2] + ")\nPlease, report above error to authors!\n"); return null; } publishProgress("\n"); publishProgress(s_line1); publishProgress("Running new experiment ...\n"); publishProgress(" " + cmd); publishProgress("\n"); publishProgress("\n"); rr = 0; while (rr < repeat) { String[] env = { "CT_REPEAT_MAIN=" + String.valueOf(ct_repeat), "LD_LIBRARY_PATH=" + path }; publishProgress("Statistical repetition: " + String.valueOf(rr + 1) + " (CT_REPEAT_MAIN=" + String.valueOf(ct_repeat) + ")\n"); startTime = System.currentTimeMillis(); ret = openme.openme_run_program(cmd, env, path); totalTime = System.currentTimeMillis() - startTime; if (ret[0] != "") { publishProgress("Error: execution failure!\n(\n" + ret[0] + "\n" + ret[1] + "\n" + ret[2] + "\n)\nPlease, report above error to authors!\n"); return null; } ft1 = ((float) totalTime) / 1000; publishProgress(" Execution time=" + String.valueOf(ft1) + " sec.\n"); exec1.add(ft1); publishProgress(" Current frequency:\n"); cpus5 = get_cpu_freqs(); cpu5 = null; cpu_num5 = cpus.size(); boolean freq_changed = false; for (int i = 0; i < cpu_num5; i++) { String x = " " + Integer.toString(i) + ") "; cpu5 = cpus5.get(i); double x0 = cpu5[0]; ; double x1 = cpu5[1]; double x2 = cpu5[2]; double y0 = 0; double y1 = 0; double y2 = 0; if (i < cpu_num0) { y0 = cpu0[0]; y1 = cpu0[1]; y2 = cpu0[2]; } x += Double.toString(x2) + " MHz vs " + Double.toString(y2) + " MHz"; publishProgress(x + "\n"); if (y2 == 0 && x2 != 0) { freq_changed = true; break; } if (y2 != 0) { double change = x2 / y2; if (change < 0.96 || change > 1.04) { freq_changed = true; break; } } } if (freq_changed && !skip_freq_check) { publishProgress(" frequency changed - skipping result\n"); } else { aft1.add(ft1); if (totalTime1 == -1) totalTime1 = totalTime; else if (totalTime1 > totalTime) totalTime1 = totalTime; if (totalTime1max == -1) totalTime1max = totalTime; else if (totalTime1max < totalTime) totalTime1max = totalTime; } rr++; } if (totalTime1 <= 0) { publishProgress(" ERROR: Couldn't obtain stable execution time!\n"); break; } ft1 = ((float) totalTime1) / 1000; ft1max = ((float) totalTime1max) / 1000; var = (ft1max - ft1) * 100 / ft1; publishProgress("\nExecution time (2): MIN=" + String.valueOf(ft1) + " sec.; VAR=" + String.format("%.1f", var) + "%\n"); if (var > 10) { publishProgress("\n"); publishProgress( "WARNING: execution time variation is too high, speed up may not be trusted!\n"); publishProgress( "For the moment, we take lower bound of execution time, i.e. what we can squeeze from your architecture!\n"); publishProgress( "On the server, we have autotuning plugins to check normality and expected value of experimental results!\n"); } speedup = ft0 / ft1; String sp = ""; if (speedup < 0.995) { sp = " (degradation)"; } publishProgress("\n"); publishProgress("Execution time speedup: " + String.format("%.2f", speedup) + sp + "\n"); } // Submitting results to CK server publishProgress(s_line); publishProgress( "Submitting results to Collective Knowledge Aggregator for online classification ...\n"); ii = new JSONObject(); try { JSONObject results = new JSONObject(); results.put("speedup", speedup); results.put("ct_repeat", ct_repeat); if (lbf0 != 0) results.put("bin_file_size0", lbf0); if (lbf1 != 0) results.put("bin_file_size1", lbf1); JSONObject freq0 = new JSONObject(); for (int i = 0; i < cpu_num0; i++) { cpu0 = cpus0.get(i); double x2 = cpu0[2]; if (x2 != 0) freq0.put(Integer.toString(i), x2); } results.put("cpu_freq0", freq0); JSONObject freq1 = new JSONObject(); for (int i = 0; i < cpu_num5; i++) { cpu5 = cpus5.get(i); double x2 = cpu0[2]; if (x2 != 0) freq1.put(Integer.toString(i), x2); } results.put("cpu_freq1", freq1); JSONObject jexec0 = new JSONObject(); for (int i = 0; i < exec0.size(); i++) { double v = exec0.get(i); jexec0.put(Float.toString(i), v); } results.put("characteristics0", jexec0); JSONObject jexec1 = new JSONObject(); for (int i = 0; i < exec1.size(); i++) { double v = exec1.get(i); jexec1.put(Float.toString(i), v); } results.put("characteristics1", jexec1); ii.put("remote_server_url", curl); ii.put("action", "request"); ii.put("module_uoa", "program.optimization.mobile"); ii.put("email", email); ii.put("crowd_uid", crowd_uid); ii.put("out", "json"); ii.put("results", results); ii.put("out", "json"); } catch (JSONException e) { publishProgress("\nError with JSONObject ...\n\n"); return null; } try { r = openme.remote_access(ii); } catch (JSONException e) { publishProgress("\nError calling OpenME interface (" + e.getMessage() + ") ...\n\n"); return null; } rr = 0; if (!r.has("return")) { publishProgress("\nError obtaining key 'return' from OpenME output ...\n\n"); return null; } try { Object rx = r.get("return"); if (rx instanceof String) rr = Integer.parseInt((String) rx); else rr = (Integer) rx; } catch (JSONException e) { publishProgress( "\nError obtaining key 'return' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } if (rr > 0) { String err = ""; try { err = (String) r.get("error"); } catch (JSONException e) { publishProgress("\nError obtaining key 'error' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } publishProgress("\nProblem accessing CK server: " + err + "\n"); return null; } status = ""; try { status = (String) r.get("status"); } catch (JSONException e) { publishProgress( "\nError obtaining key 'status' from OpenME output (" + e.getMessage() + ") ...\n\n"); return null; } publishProgress('\n' + status + '\n'); /* Sleep before possible next iteration */ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } if (running) { publishProgress(s_line); publishProgress("Crowd-tuning finished!\n"); publishProgress(s_thanks); } return null; } } }