Move everything under kotlin-native folder

I was forced to manually do update the following files, because otherwise
they would be ignored according .gitignore settings. Probably they
should be deleted from repo.

Interop/.idea/compiler.xml
Interop/.idea/gradle.xml
Interop/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_runtime_1_0_3.xml
Interop/.idea/libraries/Gradle__org_jetbrains_kotlin_kotlin_stdlib_1_0_3.xml
Interop/.idea/modules.xml
Interop/.idea/modules/Indexer/Indexer.iml
Interop/.idea/modules/Runtime/Runtime.iml
Interop/.idea/modules/StubGenerator/StubGenerator.iml
backend.native/backend.native.iml
backend.native/bc.frontend/bc.frontend.iml
backend.native/cli.bc/cli.bc.iml
backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2Native.kt
backend.native/cli.bc/src/org/jetbrains/kotlin/cli/bc/K2NativeCompilerArguments.kt
backend.native/tests/link/lib/foo.kt
backend.native/tests/link/lib/foo2.kt
backend.native/tests/teamcity-test.property
This commit is contained in:
Stanislav Erokhin
2020-10-27 21:00:28 +03:00
parent 91e4162dad
commit f624800b84
2830 changed files with 0 additions and 0 deletions
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the LICENSE file.
*/
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.plugin.mpp.NativeBuildType
plugins {
id("benchmarking")
}
val defaultBuildType = NativeBuildType.RELEASE
benchmark {
applicationName = "Cinterop"
commonSrcDirs = listOf("../../tools/benchmarks/shared/src/main/kotlin/report", "src/main/kotlin", "../shared/src/main/kotlin")
jvmSrcDirs = listOf("src/main/kotlin-jvm", "../shared/src/main/kotlin-jvm")
nativeSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/common")
mingwSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/mingw")
posixSrcDirs = listOf("src/main/kotlin-native", "../shared/src/main/kotlin-native/posix")
buildType = (findProperty("nativeBuildType") as String?)?.let { NativeBuildType.valueOf(it) } ?: defaultBuildType
dependencies.common(project(":endorsedLibraries:kotlinx.cli"))
}
val native = kotlin.targets.getByName("native") as KotlinNativeTarget
native.compilations["main"].cinterops {
create("macros")
create("struct")
create("types")
}
@@ -0,0 +1 @@
kotlin.native.home=../../dist
@@ -0,0 +1,27 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed 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.jetbrains.structsBenchmarks
actual fun structBenchmark() {
error("Benchmark structBenchmark is unsupported on JVM!")
}
actual fun unionBenchmark() {
error("Benchmark unionBenchmark is unsupported on JVM!")
}
actual fun enumBenchmark() {
error("Benchmark enumBenchmark is unsupported on JVM!")
}
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed 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.jetbrains.structsProducedByMacrosBenchmarks
actual fun macrosBenchmark() {
error("Benchmark macrosBenchmark is unsupported on JVM!")
}
@@ -0,0 +1,46 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed 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.jetbrains.typesBenchmarks
actual class StringBenchmark actual constructor() {
actual fun stringToCBenchmark() {
error("Benchmark stringToCBenchmark is unsupported on JVM!")
}
actual fun stringToKotlinBenchmark() {
error("Benchmark stringToKotlinBenchmark is unsupported on JVM!")
}
}
actual class IntBenchmark actual constructor() {
actual fun intBenchmark() {
error("Benchmark intBenchmark is unsupported on JVM!")
}
}
actual class BoxedIntBenchmark actual constructor() {
actual fun boxedIntBenchmark() {
error("Benchmark boxedIntBenchmark is unsupported on JVM!")
}
}
actual class IntMatrixBenchmark actual constructor() {
actual fun intMatrixBenchmark() {
error("Benchmark intMatrixBenchmark is unsupported on JVM!")
}
}
@@ -0,0 +1,81 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed 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.jetbrains.structsBenchmarks
import kotlinx.cinterop.*
import platform.posix.*
import kotlin.math.sqrt
const val benchmarkSize = 10000
actual fun structBenchmark() {
memScoped {
val containsFunction = staticCFunction<CPointer<ElementS>?, CPointer<ElementS>?, Int> { first, second ->
if (first == null || second == null) {
0
} else if (first.pointed.string.toKString().contains(second.pointed.string.toKString())) {
1
}
else {
0
}
}
val elementsList = mutableListOf<ElementS>()
// Fill list.
for (i in 1..benchmarkSize) {
val element = alloc<ElementS>()
element.floatValue = i + sqrt(i.toDouble()).toFloat()
element.integer = i.toLong()
sprintf(element.string, "%d", i)
element.contains = containsFunction
elementsList.add(element)
}
val summary = elementsList.map { multiplyElementS(it.readValue(), (0..10).random()) }
.reduce { acc, it -> sumElementSPtr(acc.ptr, it.ptr)!!.pointed.readValue() }
val intValue = summary.useContents { integer }
elementsList.last().contains!!(elementsList.last().ptr, elementsList.first().ptr)
}
}
actual fun unionBenchmark() {
memScoped {
val elementsList = mutableListOf<ElementU>()
// Fill list.
for (i in 1..benchmarkSize) {
val element = alloc<ElementU>()
element.integer = i.toLong()
elementsList.add(element)
}
elementsList.forEach {
it.floatValue = it.integer + sqrt(it.integer.toDouble()).toFloat()
}
val summary = elementsList.map { multiplyElementU(it.readValue(), (0..10).random()) }
.reduce { acc, it -> sumElementUPtr(acc.ptr, it.ptr)!!.pointed.readValue() }
summary.useContents { integer }
}
}
actual fun enumBenchmark() {
val days = arrayOf("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")
val enumValues = mutableListOf<WeekDay>()
for (i in 1..benchmarkSize) {
enumValues.add(getWeekDay(days[(0..6).random()]))
}
enumValues.forEach {
isWeekEnd(it)
}
}
@@ -0,0 +1,59 @@
/*
* Copyright 2010-2019 JetBrains s.r.o.
*
* Licensed 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.jetbrains.structsProducedByMacrosBenchmarks
import kotlinx.cinterop.*
import kotlin.math.abs
const val benachmarkSize = 1000
actual fun macrosBenchmark() {
memScoped {
val ints = new_list_int()
for (i in 1..benachmarkSize) {
list_push_front_int(ints, i)
}
val floats = new_list_float()
// Copy integer list to float one.
ints?.pointed?.apply {
var current = _first
while(current != null) {
list_push_front_float(floats, current?.pointed?._data?.toFloat()
?: error("Null elements in list are not expected!")
)
current = current?.pointed?._next
}
}
// Reverse list.
var previous: CPointer<list_elem_float>? = null
var current = floats?.pointed?._first
while (current != null) {
val next = current?.pointed?._next
current?.pointed?._next = previous
previous = current
current = next
}
floats?.pointed?._first = previous
free_list_int(ints)
try {
if (abs(list_front_float(floats) - benachmarkSize.toFloat()) > 0.00001) {
error("Wrong first element!")
}
} finally {
free_list_float(floats)
}
}
}
@@ -0,0 +1,133 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed 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.jetbrains.typesBenchmarks
import kotlin.random.Random
import kotlinx.cinterop.*
const val benchmarkSize = 1000
actual class StringBenchmark actual constructor() {
val charPool: List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9')
val randomString = generateRandomString()
val randomChar = charPool[Random.nextInt(0, charPool.size)]
val strings = mutableListOf<String>()
init {
// Generate random strings.
for (i in 1..benchmarkSize) {
strings.add(generateRandomString())
}
}
fun generateRandomString(): String {
return (1..benchmarkSize)
.map { i -> Random.nextInt(0, charPool.size) }
.map(charPool::get)
.joinToString("")
}
actual fun stringToCBenchmark() {
// Generate random strings.
for (i in 1..benchmarkSize) {
charFrequency(randomString, randomChar.toByte())
}
}
actual fun stringToKotlinBenchmark() {
memScoped {
val result = StringBuilder()
for (i in 1..benchmarkSize) {
val pointer = findSuitableString(strings.toCStringArray(this), benchmarkSize, "a")
val str = pointer?.toKString()
result.append(str)
freeSuitableString(pointer)
}
}
}
}
actual class IntMatrixBenchmark actual constructor(){
val matrixSize = 1000
val first = generateMatrix(matrixSize)
val second = generateMatrix(matrixSize)
fun generateMatrix(size: Int): Array<IntArray> {
val matrix = Array(size, { IntArray(size) })
for (i in (0 until size)) {
for (j in (0 until size)) {
matrix[i][j] = (1..20).random()
}
}
return matrix
}
actual fun intMatrixBenchmark() {
memScoped {
val result = allocArray<CPointerVar<IntVar>>(matrixSize)
for (i in (0 until matrixSize)) {
result[i] = allocArray<IntVar>(matrixSize)
}
val resultMatrix = multiplyMatrix(matrixSize, matrixSize,
first.map { it.toCValues().ptr }.toCValues().ptr,
matrixSize, matrixSize,
second.map { it.toCValues().ptr }.toCValues().ptr)
val resultOutput = buildString {
for (i in (0 until matrixSize)) {
for (j in (0 until matrixSize)) {
append(resultMatrix!![i]!![j])
append(" ")
}
append("\n")
}
}
}
}
}
actual class IntBenchmark actual constructor() {
val size = 20
val array = Array<Int>(size, { (0 until size).random() })
actual fun intBenchmark() {
for (i in 1..benchmarkSize) {
average(array[0], array[1], array[2], array[3], array[4], array[5], array[6], array[7], array[8],
array[9], array[10], array[11], array[12], array[13], array[14], array[15], array[16],
array[17], array[18], array[19])
}
}
}
actual class BoxedIntBenchmark actual constructor() {
val size = 20
val array = Array<Int?>(size, { null })
init {
for (i in (0 until size)) {
val element: Int? = (0 until size).random()
array[i] = element
}
}
actual fun boxedIntBenchmark() {
for (i in 1..benchmarkSize) {
average(array[0]!!, array[1]!!, array[2]!!, array[3]!!, array[4]!!, array[5]!!, array[6]!!, array[7]!!, array[8]!!,
array[9]!!, array[10]!!, array[11]!!, array[12]!!, array[13]!!, array[14]!!, array[15]!!, array[16]!!,
array[17]!!, array[18]!!, array[19]!!)
}
}
}
@@ -0,0 +1,48 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed 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.
*/
import org.jetbrains.structsProducedByMacrosBenchmarks.*
import org.jetbrains.benchmarksLauncher.*
import org.jetbrains.structsBenchmarks.*
import org.jetbrains.typesBenchmarks.*
import kotlinx.cli.*
class CinteropLauncher : Launcher() {
override val benchmarks = BenchmarksCollection(
mutableMapOf(
"macros" to BenchmarkEntry(::macrosBenchmark),
"struct" to BenchmarkEntry(::structBenchmark),
"union" to BenchmarkEntry(::unionBenchmark),
"enum" to BenchmarkEntry(::enumBenchmark),
"stringToC" to BenchmarkEntryWithInit.create(::StringBenchmark, { stringToCBenchmark() }),
"stringToKotlin" to BenchmarkEntryWithInit.create(::StringBenchmark, { stringToKotlinBenchmark() }),
"intMatrix" to BenchmarkEntryWithInit.create(::IntMatrixBenchmark, { intMatrixBenchmark() }),
"int" to BenchmarkEntryWithInit.create(::IntBenchmark, { intBenchmark() }),
"boxedInt" to BenchmarkEntryWithInit.create(::BoxedIntBenchmark, { boxedIntBenchmark() })
)
)
}
fun main(args: Array<String>) {
val launcher = CinteropLauncher()
BenchmarksRunner.runBenchmarks(args, { arguments: BenchmarkArguments ->
if (arguments is BaseBenchmarkArguments) {
launcher.launch(arguments.warmup, arguments.repeat, arguments.prefix,
arguments.filter, arguments.filterRegex, arguments.verbose)
} else emptyList()
}, benchmarksListAction = launcher::benchmarksListAction)
}
@@ -0,0 +1,21 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed 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.jetbrains.structsBenchmarks
expect fun structBenchmark()
expect fun unionBenchmark()
expect fun enumBenchmark()
@@ -0,0 +1,19 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed 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.jetbrains.structsProducedByMacrosBenchmarks
expect fun macrosBenchmark()
@@ -0,0 +1,31 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed 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.jetbrains.typesBenchmarks
expect class StringBenchmark() {
fun stringToCBenchmark()
fun stringToKotlinBenchmark()
}
expect class IntBenchmark() {
fun intBenchmark()
}
expect class BoxedIntBenchmark() {
fun boxedIntBenchmark()
}
expect class IntMatrixBenchmark() {
fun intMatrixBenchmark()
}
@@ -0,0 +1,93 @@
package = org.jetbrains.structsProducedByMacrosBenchmarks
---
#include <stdio.h>
#include <stdlib.h>
#define define_list(type) \
\
struct _list_##type; \
\
typedef struct \
{ \
int (*is_empty)(const struct _list_##type*); \
size_t (*size)(const struct _list_##type*); \
const type (*front)(const struct _list_##type*); \
void (*push_front)(struct _list_##type*, type); \
} _list_functions_##type; \
\
typedef struct _list_elem_##type \
{ \
type _data; \
struct _list_elem_##type* _next; \
} list_elem_##type; \
\
typedef struct _list_##type \
{ \
size_t _size; \
list_elem_##type* _first; \
list_elem_##type* _last; \
_list_functions_##type* _functions; \
} List_##type; \
\
List_##type* new_list_##type(); \
int list_is_empty_##type(const List_##type* list); \
size_t list_size_##type(const List_##type* list); \
const type list_front_##type(const List_##type* list); \
void list_push_front_##type(List_##type* list, type elem); \
\
int list_is_empty_##type(const List_##type* list) \
{ \
return list->_size == 0; \
} \
\
size_t list_size_##type(const List_##type* list) \
{ \
return list->_size; \
} \
\
const type list_front_##type(const List_##type* list) \
{ \
return list->_first->_data; \
} \
\
void list_push_front_##type(List_##type* list, type elem) \
{ \
struct _list_elem_##type* element = (struct _list_elem_##type*) malloc(sizeof(struct _list_elem_##type)); \
element->_data = elem; \
element->_next = list->_first; \
list->_first = element; \
list->_size++; \
} \
\
_list_functions_##type _list_funcs_##type = { \
&list_is_empty_##type, \
&list_size_##type, \
&list_front_##type, \
&list_push_front_##type, \
}; \
\
List_##type* new_list_##type() \
{ \
List_##type* res = (List_##type*) malloc(sizeof(List_##type)); \
res->_size = 0; \
res->_first = NULL; \
res->_functions = &_list_funcs_##type; \
return res; \
} \
\
void free_list_##type(List_##type* list) \
{ \
struct _list_elem_##type* current = list->_first; \
while (current != NULL) \
{ \
struct _list_elem_##type* next = current->_next; \
free(current); \
current = next; \
} \
free(list); \
}
define_list(int)
define_list(float)
@@ -0,0 +1,97 @@
package = org.jetbrains.structsBenchmarks
strictEnums = WeekDay
---
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
enum WeekDay {Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday};
int isWeekEnd(enum WeekDay day) {
if (day == Saturday || day == Sunday)
return 1;
return 0;
}
enum WeekDay getWeekDay(const char* date) {
if (strstr(date, "Sunday") != NULL) {
return Sunday;
} else if (strstr(date, "Monday") != NULL) {
return Monday;
} else if (strstr(date, "Tuesday") != NULL) {
return Tuesday;
} else if (strstr(date, "Wednesday") != NULL) {
return Wednesday;
} else if (strstr(date, "Thursday") != NULL) {
return Thursday;
} else if (strstr(date, "Friday") != NULL) {
return Friday;
} else if (strstr(date, "Saturday") != NULL) {
return Saturday;
}
abort();
}
struct ElementS {
long long integer;
float floatValue;
char string[32];
int (*contains)(const struct ElementS*, const struct ElementS*);
};
int elementContains(const struct ElementS* self, const struct ElementS* other) {
if (self == NULL || other == NULL) {
return 0;
}
if (strstr(self->string, other->string) != NULL) {
return 1;
}
return 0;
}
union ElementU {
long long integer;
float floatValue;
char string[32];
};
union ElementU multiplyElementU(union ElementU element, int coefficient) {
union ElementU newElement;
newElement.integer = coefficient * element.integer;
return newElement;
}
struct ElementS multiplyElementS(struct ElementS element, int coefficient) {
struct ElementS newElement;
newElement.integer = coefficient * element.integer;
newElement.floatValue = coefficient * element.floatValue;
int i = 0;
while (element.string[i] != '\0') {
newElement.string[i] = coefficient * element.string[i];
i++;
}
return newElement;
}
union ElementU* sumElementUPtr(const union ElementU* first, const union ElementU* second) {
if (first == NULL || second == NULL) {
return NULL;
}
union ElementU* newElement = (union ElementU*)malloc(sizeof(union ElementU));
newElement->integer = first->integer + second->integer;
return newElement;
}
struct ElementS* sumElementSPtr(const struct ElementS* first, const struct ElementS* second) {
if (first == NULL || second == NULL) {
return NULL;
}
struct ElementS* newElement = (struct ElementS*)malloc(sizeof(struct ElementS));
newElement->integer = first->integer + second->integer;
newElement->floatValue = first->floatValue + second->floatValue;
sprintf(newElement->string, "%d", newElement->integer);
return newElement;
}
@@ -0,0 +1,68 @@
package = org.jetbrains.typesBenchmarks
---
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
int charFrequency(const char* string, char charToFind) {
int frequency = 0;
for(int i = 0; string[i] != '\0'; ++i) {
if(charToFind == string[i])
++frequency;
}
return frequency;
}
const char* findSuitableString(const char* stringsArray[], int arraySize, const char* stringToFind) {
for(int i = 0; i < arraySize; ++i) {
if (strstr(stringsArray[i], stringToFind) != NULL) {
char* result = (char*) malloc((strlen(stringsArray[i])+1)*sizeof(char));
strcpy(result, stringsArray[i]);
return result;
}
}
return NULL;
}
void freeSuitableString(char* unusedString) {
free(unusedString);
}
unsigned long int sum(int array[], int arraySize) {
unsigned long int result = 0;
for(int i = 0; i < arraySize; ++i) {
result += array[i];
}
return result;
}
double average(int count, ...) {
va_list list;
int j = 0;
va_start(list, count);
double sum = 0;
for(j=0; j<count; j++) {
sum += va_arg(list, int);
}
va_end(list);
return sum / count;
}
int** multiplyMatrix(int m1, int m2, const int** mat1, int n1, int n2, const int** mat2) {
int x, i, j;
int **res = (int **)malloc(m1 * sizeof(int *));
for (i=0; i<m1; i++) {
res[i] = (int *)malloc(n2 * sizeof(int));
}
for (i = 0; i < m1; i++) {
for (j = 0; j < n2; j++) {
res[i][j] = 0;
for (x = 0; x < m2; x++) {
res[i][j] += mat1[i][x] * mat2[x][j];
}
}
}
return res;
}