Skip to content

Commit

Permalink
add DIANNE namespace defining capability (and NN service) properties
Browse files Browse the repository at this point in the history
  • Loading branch information
tverbele committed Oct 19, 2018
1 parent a9e325c commit d478acc
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 8 deletions.
1 change: 1 addition & 0 deletions be.iminds.iot.dianne.api/bnd.bnd
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Export-Package: \
be.iminds.iot.dianne.api.nn,\
be.iminds.iot.dianne.api.nn.runtime,\
be.iminds.iot.dianne.api.nn.module,\
be.iminds.iot.dianne.api.namespace,\
be.iminds.iot.dianne.api.nn.util,\
be.iminds.iot.dianne.api.nn.module.dto,\
be.iminds.iot.dianne.api.nn.module.factory,\
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
/*******************************************************************************
* DIANNE - Framework for distributed artificial neural networks
* Copyright (C) 2015 iMinds - IBCN - UGent
*
* This file is part of DIANNE.
*
* DIANNE is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Contributors:
* Tim Verbelen, Steven Bohez
*******************************************************************************/
package be.iminds.iot.dianne.api.namespace;

public final class DianneNamespace {

/**
* Namespace name for neural network capabilities
*/
public static final String DIANNE_NAMESPACE = "dianne.nn";

/**
* String with the input type the neural network expects
*
* e.g. "image"
*/
public static final String INPUT = "input";

/**
* Potential properties to indicate supported input dimensions (Long type)
*/
public static final String INPUT_WIDTH = "input.width";
public static final String INPUT_HEIGHT = "input.height";
public static final String INPUT_DEPTH = "input.depth";
public static final String INPUT_SIZE = "input.size";

/**
* String indicating necesarry input preprocessing
*/
public static final String INPUT_PREPROCESSING = "input.preprocessing";

/**
* String with the output type the neural network provides
*
* e.g. "classification","regression",...
*/
public static final String OUTPUT = "ouput";

/**
* Potential properties to indicate supported output dimensions (Long type)
*/
public static final String OUTPUT_WIDTH = "output.width";
public static final String OUTPUT_HEIGHT = "output.height";
public static final String OUTPUT_DEPTH = "output.depth";
public static final String OUTPUT_SIZE = "output.size";

/**
* The dataset it was trained on
*/
public static final String DATASET = "dataset";

/**
* String indicating the task of the neural network
*/
public static final String TASK = "task";

private DianneNamespace() {
// empty
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
version 0.7.0
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ public class DianneExportCommands {

@Descriptor("Export a neural network to a .jar.")
public void jar(String nnName, String... properties) throws IOException {
String fileName = nnName+".jar";
String fileName = "be.iminds.iot.dianne.nn."+nnName.toLowerCase()+".jar";

String[] tags = null;
Map<String, String> config = ConfigurationParser.parse(properties);
if(config.containsKey("tag")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.omg.Messaging.SyncScopeHelper;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.Version;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;

import be.iminds.iot.dianne.api.namespace.DianneNamespace;
import be.iminds.iot.dianne.api.nn.module.dto.NeuralNetworkDTO;
import be.iminds.iot.dianne.api.nn.util.DianneExporter;
import be.iminds.iot.dianne.api.repository.DianneRepository;
Expand Down Expand Up @@ -84,7 +86,7 @@ public byte[] export(String name, Map<String, String> properties, String... tags
}
}
// maybe there is a tag that can be used as version?
if(version == null) {
if(version == null && tags != null) {
for (String t : tags) {
if (isVersion(t)) {
version = t;
Expand All @@ -103,14 +105,19 @@ public byte[] export(String name, Map<String, String> properties, String... tags
atts.put(Attributes.Name.MANIFEST_VERSION, "1.0");
atts.putValue(Constants.BUNDLE_MANIFESTVERSION, "2");
atts.putValue(Constants.BUNDLE_NAME, "Dianne NN " + name);
atts.putValue(Constants.BUNDLE_SYMBOLICNAME, "be.iminds.iot.dianne.nn." + name);
atts.putValue(Constants.BUNDLE_SYMBOLICNAME, "be.iminds.iot.dianne.nn." + name.toLowerCase());
atts.putValue(Constants.BUNDLE_VERSION, version);
atts.putValue("NeuralNetwork", name);
// TODO add requirement on a DIANNE runtime capability instead of Import-Package?
atts.putValue("Import-Package", "be.iminds.iot.dianne.api.nn.runtime;version=\"" + dianneVersion() + "\"");
atts.putValue("Import-Package", "be.iminds.iot.dianne.api.nn.runtime;version=\"" + dianneVersion() + "\","
+ "be.iminds.iot.dianne.api.nn;version=\"" + dianneVersion() + "\"");

// TODO do we need to add (some of) the properties as capabilities?
// TODO do we need to specify a namespace for this?
String caps = capabilityString(properties);
if(caps != null) {
atts.putValue("Provide-Capability", caps);
}

zos.putNextEntry(new ZipEntry("META-INF/MANIFEST.MF"));
manifest.write(zos);
Expand Down Expand Up @@ -185,4 +192,50 @@ private String dianneVersion() {
// omit qualifier
return v.getMajor() + "." + v.getMinor() + "." + v.getMicro();
}

private String capabilityString(Map<String, String> properties) {
List<String> caps = new ArrayList<>();

properties.entrySet().forEach(e -> {
switch(e.getKey()) {
// filter out the stuff which is not String type
case DianneNamespace.INPUT_WIDTH:
caps.add(DianneNamespace.INPUT_WIDTH+":Long="+e.getValue());
break;
case DianneNamespace.INPUT_HEIGHT:
caps.add(DianneNamespace.INPUT_HEIGHT+":Long="+e.getValue());
break;
case DianneNamespace.INPUT_DEPTH:
caps.add(DianneNamespace.INPUT_DEPTH+":Long="+e.getValue());
break;
case DianneNamespace.INPUT_SIZE:
caps.add(DianneNamespace.INPUT_SIZE+":Long="+e.getValue());
break;
case DianneNamespace.OUTPUT_WIDTH:
caps.add(DianneNamespace.OUTPUT_WIDTH+":Long="+e.getValue());
break;
case DianneNamespace.OUTPUT_HEIGHT:
caps.add(DianneNamespace.OUTPUT_HEIGHT+":Long="+e.getValue());
break;
case DianneNamespace.OUTPUT_DEPTH:
caps.add(DianneNamespace.OUTPUT_DEPTH+":Long="+e.getValue());
break;
case DianneNamespace.OUTPUT_SIZE:
caps.add(DianneNamespace.OUTPUT_SIZE+":Long="+e.getValue());
break;
default:
if(e.getValue().contains(",")) {
caps.add(e.getKey()+":List="+e.getValue());
} else {
caps.add(e.getKey()+":String="+e.getValue());
}
}});

if(caps.isEmpty()) {
return null;
}

return DianneNamespace.DIANNE_NAMESPACE +
";"+String.join(",", caps.toArray(new String[caps.size()]));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -646,17 +646,18 @@ public void onError(UUID moduleId, ModuleException e, String... tags) {

Dictionary<String, Object> properties = new Hashtable<String, Object>();
properties.put("nn.id", nni.id.toString());
properties.put("nn.name", nni.name);
properties.put("aiolos.export", false);
properties.put("aiolos.unique", true);

// if a NeuralNetworkDTO is available, add its properties as service properties
// if a NeuralNetworkDTO is available, add its properties as service properties, prefixed with "nn"
if(nni.nn != null) {
for(Entry<String, String> e : nni.nn.properties.entrySet()) {
if(e.getValue().contains(",")) {
// interpret as String[]
properties.put(e.getKey(), e.getValue().split(","));
properties.put("nn."+e.getKey(), e.getValue().split(","));
} else {
properties.put(e.getKey(), e.getValue());
properties.put("nn."+e.getKey(), e.getValue());
}
}
}
Expand Down

0 comments on commit d478acc

Please sign in to comment.