You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@joshua.apache.org by mj...@apache.org on 2016/08/30 21:04:50 UTC
[05/17] incubator-joshua git commit: Merge branch 'master' into
7-with-master
http://git-wip-us.apache.org/repos/asf/incubator-joshua/blob/b0b70627/joshua-core/src/test/java/org/apache/joshua/packed/Benchmark.java
----------------------------------------------------------------------
diff --cc joshua-core/src/test/java/org/apache/joshua/packed/Benchmark.java
index 41cf2a0,0000000..7c4fc80
mode 100644,000000..100644
--- a/joshua-core/src/test/java/org/apache/joshua/packed/Benchmark.java
+++ b/joshua-core/src/test/java/org/apache/joshua/packed/Benchmark.java
@@@ -1,126 -1,0 +1,132 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.joshua.packed;
+
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
-
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.nio.IntBuffer;
+import java.nio.MappedByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileChannel.MapMode;
+import java.util.Random;
+
++import org.slf4j.Logger;
++import org.slf4j.LoggerFactory;
++
+/**
+ * This program runs a little benchmark to check reading speed on various data
+ * representations.
- *
++ *
+ * Usage: java Benchmark PACKED_GRAMMAR_DIR TIMES
+ */
+
- public class Benchmark {
++public class Benchmark implements AutoCloseable{
+
-
+ private static final Logger LOG = LoggerFactory.getLogger(Benchmark.class);
+
+ private IntBuffer intBuffer;
+ private MappedByteBuffer byteBuffer;
+ private int[] intArray;
++ private final FileInputStream fin;
+
+ public Benchmark(String dir) throws IOException {
+ File file = new File(dir + "/slice_00000.source");
-
- FileChannel source_channel = new FileInputStream(file).getChannel();
++ this.fin = new FileInputStream(file);
++ FileChannel source_channel = this.fin.getChannel();
+ int byte_size = (int) source_channel.size();
+ int int_size = byte_size / 4;
+
- byteBuffer = source_channel.map(MapMode.READ_ONLY, 0, byte_size);
++ byteBuffer = source_channel.map(MapMode.READ_ONLY, 0, byte_size);
+ intBuffer = byteBuffer.asIntBuffer();
+
+ intArray = new int[int_size];
+ intBuffer.get(intArray);
+ }
+
+ public void benchmark(int times) {
+ LOG.info("Beginning benchmark.");
+
+ Random r = new Random();
+ r.setSeed(1234567890);
+ int[] positions = new int[1000];
+ for (int i = 0; i < positions.length; i++)
+ positions[i] = r.nextInt(intArray.length);
+
+ long sum;
+
+ long start_time = System.currentTimeMillis();
+
+ sum = 0;
+ for (int t = 0; t < times; t++)
+ for (int i = 0; i < positions.length; i++)
+ sum += byteBuffer.getInt(positions[i] * 4);
+ LOG.info("Sum: {}", sum);
+ long byte_time = System.currentTimeMillis();
+
+ sum = 0;
+ for (int t = 0; t < times; t++)
+ for (int i = 0; i < positions.length; i++)
+ sum += intBuffer.get(positions[i]);
+ LOG.info("Sum: {}", sum);
+ long int_time = System.currentTimeMillis();
+
+ sum = 0;
+ for (int t = 0; t < times; t++)
+ for (int i = 0; i < positions.length; i++)
+ sum += intArray[positions[i]];
+ LOG.info("Sum: {}", sum);
+ long array_time = System.currentTimeMillis();
+
+ sum = 0;
+ for (int t = 0; t < times; t++)
+ for (int i = 0; i < (intArray.length / 8); i++)
+ sum += intArray[i * 6] + intArray[i * 6 + 2];
+ LOG.info("Sum: {}", sum);
+ long mult_time = System.currentTimeMillis();
+
+ sum = 0;
+ for (int t = 0; t < times; t++) {
+ int index = 0;
+ for (int i = 0; i < (intArray.length / 8); i++) {
+ sum += intArray[index] + intArray[index + 2];
+ index += 6;
+ }
+ }
+ LOG.info("Sum: {}", sum);
+ long add_time = System.currentTimeMillis();
+
+ LOG.info("ByteBuffer: {}", (byte_time - start_time));
+ LOG.info("IntBuffer: {}", (int_time - byte_time));
+ LOG.info("Array: {}", (array_time - int_time));
+ LOG.info("Multiply: {}", (mult_time - array_time));
+ LOG.info("Add: {}", (add_time - mult_time));
+ }
+
+ public static void main(String args[]) throws IOException {
- Benchmark pr = new Benchmark(args[0]);
- pr.benchmark( Integer.parseInt(args[1]));
++ try (Benchmark pr = new Benchmark(args[0]);) {
++ pr.benchmark( Integer.parseInt(args[1]));
++ }
++ }
++
++ @Override
++ public void close() throws IOException {
++ this.fin.close();
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-joshua/blob/b0b70627/joshua-core/src/test/java/org/apache/joshua/system/MultithreadedTranslationTests.java
----------------------------------------------------------------------
diff --cc joshua-core/src/test/java/org/apache/joshua/system/MultithreadedTranslationTests.java
index 10872d0,0000000..01d3963
mode 100644,000000..100644
--- a/joshua-core/src/test/java/org/apache/joshua/system/MultithreadedTranslationTests.java
+++ b/joshua-core/src/test/java/org/apache/joshua/system/MultithreadedTranslationTests.java
@@@ -1,180 -1,0 +1,180 @@@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.joshua.system;
+
++import static org.mockito.Mockito.doReturn;
++import static org.testng.Assert.assertTrue;
++
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
- import java.nio.charset.Charset;
++import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+
+import org.apache.joshua.decoder.Decoder;
+import org.apache.joshua.decoder.JoshuaConfiguration;
+import org.apache.joshua.decoder.Translation;
+import org.apache.joshua.decoder.TranslationResponseStream;
+import org.apache.joshua.decoder.io.TranslationRequestStream;
+import org.apache.joshua.decoder.segment_file.Sentence;
+import org.mockito.Mockito;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
- import static org.mockito.Mockito.doReturn;
- import static org.testng.Assert.assertTrue;
-
+/**
+ * Integration test for multithreaded Joshua decoder tests. Grammar used is a
+ * toy packed grammar.
+ *
+ * @author Kellen Sunderland kellen.sunderland@gmail.com
+ */
+public class MultithreadedTranslationTests {
+
+ private JoshuaConfiguration joshuaConfig = null;
+ private Decoder decoder = null;
+ private static final String INPUT = "A K B1 U Z1 Z2 B2 C";
+ private static final String EXCEPTION_MESSAGE = "This exception should properly propagate";
+ private int previousLogLevel;
+ private final static long NANO_SECONDS_PER_SECOND = 1_000_000_000;
+
+ @BeforeClass
+ public void setUp() throws Exception {
+ joshuaConfig = new JoshuaConfiguration();
+ joshuaConfig.search_algorithm = "cky";
+ joshuaConfig.mark_oovs = false;
+ joshuaConfig.pop_limit = 100;
+ joshuaConfig.use_unique_nbest = false;
+ joshuaConfig.include_align_index = false;
+ joshuaConfig.topN = 0;
+ joshuaConfig.tms.add("thrax -owner pt -maxspan 20 -path src/test/resources/wa_grammar.packed");
+ joshuaConfig.tms.add("thrax -owner glue -maxspan -1 -path src/test/resources/grammar.glue");
+ joshuaConfig.goal_symbol = "[GOAL]";
+ joshuaConfig.default_non_terminal = "[X]";
+ joshuaConfig.features.add("OOVPenalty");
+ joshuaConfig.weights.add("tm_pt_0 1");
+ joshuaConfig.weights.add("tm_pt_1 1");
+ joshuaConfig.weights.add("tm_pt_2 1");
+ joshuaConfig.weights.add("tm_pt_3 1");
+ joshuaConfig.weights.add("tm_pt_4 1");
+ joshuaConfig.weights.add("tm_pt_5 1");
+ joshuaConfig.weights.add("tm_glue_0 1");
+ joshuaConfig.weights.add("OOVPenalty 2");
+ joshuaConfig.num_parallel_decoders = 500; // This will enable 500 parallel
+ // decoders to run at once.
+ // Useful to help flush out
+ // concurrency errors in
+ // underlying
+ // data-structures.
+ this.decoder = new Decoder(joshuaConfig);
+ previousLogLevel = Decoder.VERBOSE;
+ Decoder.VERBOSE = 0;
+ }
+
+ @AfterClass
+ public void tearDown() throws Exception {
+ this.decoder.cleanUp();
+ this.decoder = null;
+ Decoder.VERBOSE = previousLogLevel;
+ }
+
+
+
+ // This test was created specifically to reproduce a multithreaded issue
+ // related to mapped byte array access in the PackedGrammer getAlignmentArray
+ // function.
+
+ // We'll test the decoding engine using N = 10,000 identical inputs. This
+ // should be sufficient to induce concurrent data access for many shared
+ // data structures.
+
+ @Test()
+ public void givenPackedGrammar_whenNTranslationsCalledConcurrently_thenReturnNResults() throws IOException {
+ // GIVEN
+
+ int inputLines = 10000;
+ joshuaConfig.use_structured_output = true; // Enabled alignments.
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < inputLines; i++) {
+ sb.append(INPUT + "\n");
+ }
+
+ // Append a large string together to simulate N requests to the decoding
+ // engine.
+ TranslationRequestStream req = new TranslationRequestStream(
+ new BufferedReader(new InputStreamReader(new ByteArrayInputStream(sb.toString()
- .getBytes(Charset.forName("UTF-8"))))), joshuaConfig);
-
++ .getBytes(StandardCharsets.UTF_8)))), joshuaConfig);
++
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+
+ // WHEN
+ // Translate all segments in parallel.
+ TranslationResponseStream translationResponseStream = this.decoder.decodeAll(req);
+
+ ArrayList<Translation> translationResults = new ArrayList<Translation>();
+
+
+ final long translationStartTime = System.nanoTime();
+ try {
+ for (Translation t: translationResponseStream)
+ translationResults.add(t);
+ } finally {
+ if (output != null) {
+ try {
+ output.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ final long translationEndTime = System.nanoTime();
+ final double pipelineLoadDurationInSeconds = (translationEndTime - translationStartTime)
+ / ((double)NANO_SECONDS_PER_SECOND);
+ System.err.println(String.format("%.2f seconds", pipelineLoadDurationInSeconds));
+
+ // THEN
+ assertTrue(translationResults.size() == inputLines);
+ }
+
+ @Test(expectedExceptions = RuntimeException.class,
+ expectedExceptionsMessageRegExp = EXCEPTION_MESSAGE)
+ public void givenDecodeAllCalled_whenRuntimeExceptionThrown_thenPropagate() throws IOException {
+ // GIVEN
+ // A spy request stream that will cause an exception to be thrown on a threadpool thread
+ TranslationRequestStream spyReq = Mockito.spy(new TranslationRequestStream(null, joshuaConfig));
+ doReturn(createSentenceSpyWithRuntimeExceptions()).when(spyReq).next();
+
+ // WHEN
+ // Translate all segments in parallel.
+ TranslationResponseStream translationResponseStream = this.decoder.decodeAll(spyReq);
+
+ ArrayList<Translation> translationResults = new ArrayList<>();
+ for (Translation t: translationResponseStream)
+ translationResults.add(t);
+ }
+
+ private Sentence createSentenceSpyWithRuntimeExceptions() {
+ Sentence sent = new Sentence(INPUT, 0, joshuaConfig);
+ Sentence spy = Mockito.spy(sent);
+ Mockito.when(spy.target()).thenThrow(new RuntimeException(EXCEPTION_MESSAGE));
+ return spy;
+ }
+}