sstsimulator / sst-elements Goto Github PK
View Code? Open in Web Editor NEWSST Architectural Simulation Components and Libraries
Home Page: http://www.sst-simulator.org
License: Other
SST Architectural Simulation Components and Libraries
Home Page: http://www.sst-simulator.org
License: Other
Provide the whatwhy summary, followed by the how, sample input deck andor anything else you think will illuminate the function of the component. First, check out the short summary at https:sst-simulator.orgwikiDeveloperComponentSummaryInfo and then click on the component link to access the documentation page for that component.
The SST 5.1 Release plan includes SystemC. There is still no test of SystemC provided for the nightly test Suites.
The Element Library Information needs to be updated for this Element. Refer to the file trunksstcoreelement.h for more information.
After changes finalized, run sstinfo to verify information.
The following message is produced many times when trying to initialize VaultSimC using chdlComponents initial memory contents configuration parameter:
Memory received unexpected Init Command: 2
These start as writes. Elsewhere (memhierarchys memcontroller), command 2 (GetX) is used to provide init data. Even if we allow GetX commands in addition to writebacks to be used to provide initial contents, initialization seems to fail; the memory contents cannot be read back.
Merlin should be capable of autodiscovery of unset network parameters, assuming the parameters are set elsewhere in the system.
MH should support flushing. This functionality is required by some OSesCPUs
An L1 should look at all its cache lines and writeback any valid ones. Potential issues:
A) The cache line is in transient state. Cache should probably wait for response before writing back
B) Cache should temporarily disable other incoming requests (prefetcher, cpu) while flushing
C) Assert that no cache lines have a LOCK bit
D) How many writebacks to send per cycle Gotta be careful not for overflowdeadlock situations
The change in output has not been resolved, but testing is going to stop reporting the errors on Gaussian and expon tests. (Installing current answer as Reference.)
Extend the current MESI Protocol to support the Owned (O) state.
L2L3+ caches should go to sleep (ie clock handler should be temporarly removed) when Idle to increase runtime performance.
MemNIC needs to be modiefied if L3 is to go to sleep. MemNIC should not poll or depend on the LLC to call its clock handler.
When running this script (on a brand new install from SVN):
import sst
sst.setStatisticLoadLevel(3)
sst.setStatisticOutput("sst.statOutputCSV", {"filepath" : "./TestOutput.csv","separator" : "," } )
from sst.merlin import *
sst.merlin._params["flit_size"] = "16B"
sst.merlin._params["link_bw"] = "4.0GB/s"
sst.merlin._params["xbar_bw"] = "4.0GB/s"
sst.merlin._params["input_latency"] = "10.0ns"
sst.merlin._params["output_latency"] = "10.0ns"
sst.merlin._params["input_buf_size"] = "16.0KB"
sst.merlin._params["output_buf_size"] = "16.0KB"
sst.merlin._params["link_lat"] = "16ns"
sst.merlin._params["xbar_arb"] = "merlin.xbar_arb_age"
merlintorusparams = {}
merlintorusparams["num_dims"]=2
merlintorusparams["torus:shape"]="4x4"
merlintorusparams["torus:width"]="1x1"
merlintorusparams["torus:local_ports"]=1
sst.merlin._params.update(merlintorusparams)
topo = topoTorus()
topo.prepParams()
sst.merlin._params["extra_cycles"] = 0
sst.merlin._params["PacketDest:pattern"] = "Uniform"
sst.merlin._params["PacketDest:RangeMax"] = "2.147483647E9"
sst.merlin._params["PacketDest:Seed"] = 0
sst.merlin._params["packet_size"] = "9000b"
sst.merlin._params["message_rate"] = "0.0025GHz"
sst.merlin._params["packets_to_send"] = 500
endPoint = TrafficGenEndPoint()
endPoint.enableAllStatistics("500ns")
endPoint.prepParams()
topo.setEndPoint(endPoint)
topo.build()
sst.enableAllStatisticsForAllComponents({"type":"sst.AccumulatorStatistic","rate":"0ns"})
it works, but if I change this line
sst.merlin._params["packet_size"] = "8000b"
to
sst.merlin._params["packet_size"] = "9000b"
nothing happens and the simulation ends at time 18.4467 Ms...
The results for test2 from SVN from repeated runs produce different answers on MacOS. It has been verified multiple times that the random number streams used is NOT the issue. Repeated runs with the same initial seed yield multiple answers. (This is not observed on any of the Linux platforms regularly tested.)
The Element Library Information needs to be updated for this Element. Refer to the file trunksstcoreelement.h for more information.
After changes finalized, run sstinfo to verify information.
The Element Library Information needs to be updated for this Element. Refer to the file trunksstcoreelement.h for more information.
After changes finalized, run sstinfo to verify information.
We need a mechanism to provide a generic set of tags or attributes to memEvent and have them copied into events further up the system. These attributes can then perform things like force a component to dump statistics (a programmerapplication side statistics barrier), attribute misshit events to SETS of instruction pointers etc. This will greatly help in actually analyzing how an application uses these components.
The problem is only seen on Static Yosemite.
Valgrind (on CentOS) reports over 2 million errors in 49 contexts from MacSim, but no segfault on CentOS.
Its a segment fault.
[yosemitexc63:66125] Process received signal
[yosemitexc63:66125] Signal: Segmentation fault: 11 (11)
[yosemitexc63:66125] Signal code: Address not mapped (1)
[yosemitexc63:66125] Failing at address: 0xb
[yosemitexc63:66125] [ 0] 0 libsystem_platform.dylib 0x00007fff9009ff1a _sigtramp + 26
[yosemitexc63:66125] [ 1] 0 ??? 0x00007fff5dc42a10 0x0 + 140734766524944
[yosemitexc63:66125] [ 2] 0 sstsim.x 0x00000001021c4073 _ZN6core_c11run_a_cycleEb + 163
[yosemitexc63:66125] [ 3] 0 sstsim.x 0x00000001021e4b4a _ZN8macsim_c11run_a_cycleEv + 986
[yosemitexc63:66125] [ 4] 0 sstsim.x 0x0000000102158358 _ZN3SST6MacSim15macsimComponent11ticReceivedEy + 184
[yosemitexc63:66125] [ 5] 0 sstsim.x 0x0000000101fd996c _ZN3SST5Clock7executeEv + 76
[yosemitexc63:66125] [ 6] 0 sstsim.x 0x0000000102033790 _ZN3SST10Simulation3runEv + 400
[yosemitexc63:66125] [ 7] 0 sstsim.x 0x0000000101fbc0f2 main + 8658
[yosemitexc63:66125] [ 8] 0 libdyld.dylib 0x00007fff876f85c9 start + 1
[yosemitexc63:66125] End of error message
After we run out of resources:
/home/jpvandy/CentOS-bamboo-Sep10_0820/devel/trunk/sst/elements/ariel/frontend/simple/examples/stream/runstreamNB.py
terminate called after throwing an instance of 'boost::interprocess::interprocess_exception'
what(): Permission denied
[sst-test:11556] Process received signal
[sst-test:11556] Signal: Aborted (6)
[sst-test:11556] Signal code: (-6)
[sst-test:11556] [ 0] /lib64/libpthread.so.0[0x30a580f710]
[sst-test:11556] [ 1] /lib64/libc.so.6(gsignal+0x35)[0x30a5432625]
[sst-test:11556] [ 2] /lib64/libc.so.6(abort+0x175)[0x30a5433e05]
[sst-test:11556] [ 3] /usr/local/module-pkgs/gcc/4.6.4/lib64/libstdc++.so.6(_ZN9gnu_cxx27verbose_terminate_handlerEv+0x11d)[0x7fe58a6c934d]
[sst-test:11556] [ 4] /usr/local/module-pkgs/gcc/4.6.4/lib64/libstdc++.so.6(+0xb74f6)[0x7fe58a6c74f6]
[sst-test:11556] [ 5] /usr/local/module-pkgs/gcc/4.6.4/lib64/libstdc++.so.6(+0xb7523)[0x7fe58a6c7523]
[sst-test:11556] [ 6] /usr/local/module-pkgs/gcc/4.6.4/lib64/libstdc++.so.6(cxa_rethrow+0x46)[0x7fe58a6c7666]
[sst-test:11556] [ 7] /home/jpvandy/CentOS-bamboo-Sep10_0820/local/lib/sst/libariel.so(_ZN3SST4Core12Interprocess9IPCTunnelINS_14ArielComponent15ArielSharedDataENS3_12ArielCommandEEC2ERKSsmm+0xa5b)[0x7fe584883e6b]
[sst-test:11556] [ 8] /home/jpvandy/CentOS-bamboo-Sep10_0820/local/lib/sst/libariel.so(_ZN3SST14ArielComponent8ArielCPUC1EmRNS_6ParamsE+0x1461)[0x7fe584876e51]
[sst-test:11556] [ 9] /home/jpvandy/CentOS-bamboo-Sep10_0820/local/lib/sst/libariel.so(+0x19024)[0x7fe584873024]
[sst-test:11556] [10] /home/jpvandy/CentOS-bamboo-Sep10_0820/local/bin/sst(_ZN3SST7Factory15CreateComponentEmSsRNS_6ParamsE+0x459)[0x63dc39]
[sst-test:11556] [11] /home/jpvandy/CentOS-bamboo-Sep10_0820/local/bin/sst(_ZN3SST10Simulation13performWireUpERNS_11ConfigGraphEim+0xf6e)[0x67ea7e]
[sst-test:11556] [12] /home/jpvandy/CentOS-bamboo-Sep10_0820/local/bin/sst(main+0x2899)[0x5df3e9]
[sst-test:11556] [13] /lib64/libc.so.6(libc_start_main+0xfd)[0x30a541ed5d]
[sst-test:11556] [14] /home/jpvandy/CentOS-bamboo-Sep10_0820/local/bin/sst[0x5be6f1]
[sst-test:11556] End of error message
/home/jpvandy/CentOS-bamboo-Sep10_0820/devel/trunk/test/testSuites/testSuite_Ariel.sh: line 74: 11556 Aborted
When the generator is re-seeded (trafficgen.h:157) a new Mersenne RNG stream is created but this stream is not redirected to the SSTUniformDistribution, so the original seed is kept.
I fixed that this way:
void seed(uint32_t val)
{
gen = new MersenneRNG((unsigned int) val);
dist->setGenerator(gen);
}
and added a new function setGenerator in SSTUniformDist
We currently build Doxygen files for the core each night. Cesar has added Doxygen updates to the !MemHierarchy component. Add the infrastructure to Jenkins to build Doxygen files for any components (currently one) that support it.
Deprecation of xml input has been described as a goal for 5.0 release of SST. Patterns, portals, qsim, and scheduler still employ xml input files.
Pattern resists auto conversion because the input file grows by a large amount in the sst dumped python. See Issue #311.
Portals tests employ generated sdlsml files.
Qsim generates and modifies the input xml in the course of the test.
Scheduler test 1 employs a generated sdlxml file.
This doesnt address the question of what happens with the Gem5 xxxxM5.xml files when we soon upgrade our Gem5 version.
Nightly test is required for all released components.
Large latencies in the order of 150-350 cycles are seen in the route between the last level caches and directory controller. The problem has come to light with a VaultSim backend configuration whose bandwidth is 5x larger than is reported, and doesnt appear to be the bottleneck. The LLCs are connected by a Merlin router which doesnt appear to contain many crossbar or port stalls. Such large latencies are not to be expected.
Fails to correctly load glibc during profiling.
Packet size still not properly generated.
a Uniform dist with parameters range.first, range.second - 1 is created. There is no reason for this -1 to be here.
From this results that to generate between [1,2] one need to configure with Min=0 and Max=3
only max-min is used to determine the size of the interval. The offset is lost. So using a range [0, 400] is equivalent to using a range [1000, 1400]. The offset should also be given to SSTUniformDistribution
getNextDouble in uniform.h is clearly sub-optimal and too complicated. An uniform can simply be obtained by multiplying the original random sample obtained from the random stream (Mersenne) by the interval size (and later adding the offset). There is no need for looping of any sort.
A configuration with min > max should result in an error
When the application forks, the simulation crashes as Ariel core 0s instruction queue becomes empty. The error message is pasted below: sst: ........sstelementsarielarielcore.cc:236: bool SST::ArielComponent::ArielCore::refillQueue(): Assertion 0 failed.
Currently sst provides setProgramOption stopAtCycle option to stop simulation at certain simulation time. As majority of actual sst simulation jobs are submitted to be run on machine which have queue limits. It would be beneficial if there is option like stopAtWalltime so that simulation could be exited by the allocated time and users can get some result back rather than program termination.
Fails on Linux with n > 1 for thread count.
January 6th, the nightly test on Ubuntu 14.04 (#181) that included prospero failed. The three prospero tests that use DramSim passed, but the three that dont use DramSim failed.
There were no SVN changes from the previous that passed and there has been no recurrence. There have been no related failures on other hosts including a new Ubuntu 14.04 VM.
The trace-back from the failure is attached. (Could not collect gdb into because the failure was a one-only.)
Running the test under Valgrind on sst-test is completely clean.
Running Valgrind on Ubuntu 14.04 is a story unto itself. Valgrind has several complaints about using uninitialized variables. The entire trace-back is in Python library routines. Ubuntu 14.04 uses Python 2.7. CentOS and most other place we run use Python 2.6
Provide the whatwhy summary, followed by the how, sample input deck andor anything else you think will illuminate the function of the component. First, check out the one line summary at https:sst-simulator.orgwikiDeveloperComponentSummaryInfo and then click on the component link to access the documentation page for that component.
Previous issue #329. It will not build with gcc-4.4.7 because of C++11 usage - this is probably not to get fixed. (Nightly testing is disabled if C++11 is not available.)
Current version of chdl will not build with Clang compiler. Appears to be fine with gcc-4.7 and gcc-4.8.1. The log of a Clang compile failure is attached. (Nightly testing is disabled on Clang compilers.)
The test needs two input files which are being fetched from kersey.com, which need to be install in sst downloads.
The external component for chdl comes from three git downloads which are not from a release but from a HEAD of a repository.
In sstelementsembertests, there are about 20 files. But only one (emberLoad.py) is a full run case, others are meant to be imported. This is quite confusing for new comers who might expect all these scripts to define standalone simulation scenarios.
Would it be possible to introduce a distinction between executable scripts and library ones The latter could be regrouped in a sub folder or could adopt a prefix, for example.
What steps will reproduce the problem
Compare the testSuite_VaultSim.sh results before and after the repository changes of approximately December 3rd, 2013 (rev 6024-6031).
After that date, all VaultSim tests fail because of the changed output.
Reference file was not updated, because the resulting change was not desired.
g++ -O3 \
-I../../.. -I/Users/sdhammo/Documents/Git/sst-github-repo \
-pthread -I/Users/sdhammo/Documents/Boost/1.54.0/openmpi/1.8.1/clang/5.1.0/include \
-DBIGARRAY_MULTIPLIER=1 \
-DTARGET_IA32E -DHOST_IA32E -fPIC -DTARGET_MAC \
-I/Users/sdhammo/Documents/PIN/2.14/source/include/pin \
-I/Users/sdhammo/Documents/PIN/2.14/ \
-I/Users/sdhammo/Documents/PIN/2.14/extras/components/include \
-I/Users/sdhammo/Documents/PIN/2.14/source/include/pin/gen/ \
-I/Users/sdhammo/Documents/PIN/2.14/extras/xed-intel64/include \
-fomit-frame-pointer -fno-stack-protector \
-stdlib=libstdc++ \
-o fesimple.o -c \
frontend/simple/fesimple.cc
clang: error: no such file or directory: 'frontend/simple/fesimple.cc'
clang: error: no input files
Hi there,
There's a typo in elements/ember/test/emberLoad.py , line 65:
except getopt.GetopError as err
should be
except getopt.GetoptError as err
I was passing a wrong option and it broke, I stared at the line for a while and wondered why it would break (I thought it was the interpreter missing something) then I realize there's a "t" missing lol
Thanks,
Shang
Configured merlin traffic gen to create random packet sizes in the range [200, 201]. Also configured traffic gen to generate 500 packets. I would expect the send_bit_count to be 200.5 create_issues.sh create_issues.sh~ create_issues_orig.sh csv csvprocessor.c report_12_4.csv run_core_issues_final.sh run_create_issues.sh run_create_issues.sh~ run_create_issues_orig.sh run_create_milestones.sh run_create_milestones.sh~ run_elements_issues_final.sh run_workbench_issues_final.sh 500 = 100250 with some variations across the generators (I have 27). But it is not the case. 26 of the generators report a bit_count of 100,000, and one (no 20) even reports a bit_count of 99,800 (that should not be).
I first thought that this was due to statistical fluctuation. And then set the generator for 1000 packets. Here I still have 26 generators generating 200,000 bits, and no 20 generating 199,800 (which is not 2x99,800...) And for 100 packets all generate 20,000 but no 20 generating 19800.
Looking closer at no 20, with 3 packets -->600
4 packets --> 800
5 packets --> STILL 800 !
So one packet is not sent or something is missing here...
For the uniform sampling of the range, I figured out that rangeMin and rangeMax should be understood as [MIN, MAX[ (i.e. MAX not comprised in the interval). With a range [200, 202[ I indeed obtain 200.5 in average except for no 20, for more than 4 packets...
this is my script:
sst.merlin._params[flit_size] = 16B
sst.merlin._params[link_bw] = 4.0GBs
sst.merlin._params[xbar_bw] = 4.0GBs
sst.merlin._params[input_latency] = 10.0ns
sst.merlin._params[output_latency] = 10.0ns
sst.merlin._params[input_buf_size] = 16.0KB
sst.merlin._params[output_buf_size] = 16.0KB
sst.merlin._params[link_lat] = 16ns
sst.merlin._params[num_dims]=3
sst.merlin._params[torus:shape]=3x3x3
sst.merlin._params[torus:width]=1x1x1
sst.merlin._params[torus:local_ports]=1
topo = topoTorus()
topo.prepParams()
sst.merlin._params[PacketDest:pattern] = Uniform
sst.merlin._params[PacketSize:pattern] = Uniform
sst.merlin._params[PacketSize:RangeMin] = 200.0
sst.merlin._params[PacketSize:RangeMax] = 201.0
# Required by pymerlin but will be overriden
sst.merlin._params[packet_size] = 0KB
sst.merlin._params[PacketDelay:pattern] = Uniform
sst.merlin._params[PacketDelay:RangeMin] = 200.0
sst.merlin._params[PacketDelay:RangeMax] = 300.0
# Required by pymerlin but will be overriden
sst.merlin._params[message_rate] = 1GHz
sst.merlin._params[packets_to_send] = 6
endPoint = TrafficGenEndPoint()
endPoint.prepParams()
topo.setEndPoint(endPoint)
topo.build()
It will be good for the caches to be able to report the occupancy rates of their MSHR. It will help us reason about the back pressure and traffic to the backend.
The patterns input xml files are large. Simply using sst to generate the python file, which will produce the correct output yields a file, which is 25 times as large.
648924 1965393 25347643 test_patterns_allreduce_deep_4096.py
25142 74359 978816 test_patterns_allreduce_deep_4096.xml
764917 2316276 30123344 test_patterns_alltoall_M_Shamrock.py
29988 88006 1154366 test_patterns_alltoall_M_Shamrock.xml
2587420 7836753 101537020 test_patterns_ping_M_XE.py
95796 283441 3765587 test_patterns_ping_M_XE.xml
Commands used in DMAEngine are not compatible with current MH commands
Report from Sebastien at Columbia. If set all EmberLoad performance latencies very low seem to have a 50ns overhead which is not exposed.
Once the LLSC feature has been put in place, this locking mechamism needs to be tested on the current sweeps (w and wo directory)
Tests outputs should match the reference files even when this feature is activated.
Need a tool to parse and analyze the output from hr_router::printStatus (which is called when SIGUSR2 is sent to SST). Output is much too large to analyze manually.
femlm makefile does not work with current versions of PIN which are required by Ariel
DRAMSim2s makefile contains calls to both
This can prevent proper builds of both SST and HybridSim due to mismatching binary files.
If all the g++ calls in the Makefile are changed to $(CC) then everything builds fine.
This occurs running the Patterns test Suite. This presumably results from the Python version upgrade on Yosemite.
It is not a solid (reproducible) failure. To date it has only been seen on tests of the 5.0 release and the 5.0.1 pre-release.
The XML file is attached and is generated in the testSuite. The xml is 96,000 lines (3.7 megabytes) It was not previously replaced with a python input file because it is generated but more importantly, if one uses SST to auto-convert from xml to python, the file grows by a factor of 25!
Log file of the failure is also attached
Need to have ability to have TLB handling across a simulation and make it a module for components to utilize (integrated with SimpleMem interface).
ExponentialDist in trafficgen.h is constructed with an int. It should receive a float or double because
in TrafficGen::buildGenerator() a float is retrieved from the parameters
giving integer only doesnt let the user configure lambda 0.01 for instance, to obtain inter-times of 100ns in average.
Reported by gortipavan, Mar 13, 2013
What steps will reproduce the problem
What is the expected output What do you see instead
I expect power statistics to be output for executing an application. I do not see them.
What version of the product are you using On what operating system (provide version) Are you developing using a Virtual Machine environment If so, provide both virtual and actual machine OS names and versions.
sst-2.3.0
sst-gem5-2.3.0
Red Hat Linux 5.8 Tikanga
Please provide any additional information below.
When building sst, I get the message that gem5 power models are disabled for this build. Is this a problem If so, how to get around this
In trafficgen.cc, seed of the generators (provided through the python params) are overriden by the generator id at lines 102, 108 and 125
102: packetDestGen->seed(id);
108: if ( packetSizeGen ) packetSizeGen->seed(id);
These lines should be removed otherwise seeds as specified in the python are never used.
Hi I was playing with merlin and trying to build a dragonfly network. In the /merlin/topology/dragonfly.cc source code I found (line 215):
uint32_t topo_dragonfly::router_to_group(uint32_t group) const
{
/* For now, assume only 1 connection to each group */
Does it mean I cannot have more than 1 inter-group link per router?
Thanks,
Shang
In elements/miranda/generators/spmvgen.h, line 50:
matrixNNZPerRow = (uint64_t) params.find_integer("matrix_nnz_per_row", 4);
But with sstinfo, this parameter is not provided:
SUBCOMPONENT 1 = SPMVGenerator (Creates a diagonal matrix access pattern)
NUM PARAMETERS = 12
PARAMETER 0 = matrix_nx (Sets the horizontal dimension of the matrix) [10]
PARAMETER 1 = matrix_ny (Sets the vertical dimension of the matrix (the number of rows)) [10]
PARAMETER 2 = element_width (Sets the width of one matrix element, typically 8 for a double) [8]
PARAMETER 3 = lhs_start_addr (Sets the start address of the LHS vector) [0]
PARAMETER 4 = rhs_start_addr (Sets the start address of the RHS vector) [80]
PARAMETER 5 = local_row_start (Sets the row at which this generator will start processing) [0]
PARAMETER 6 = local_row_end (Sets the end at which rows will be processed by this generator) [10]
PARAMETER 7 = ordinal_width (Sets the width of ordinals (indices) in the matrix, typically 4 or 8) [8]
PARAMETER 8 = matrix_row_indices_start_addr (Sets the row indices start address for the matrix) [0]
PARAMETER 9 = matrix_col_indices_start_addr (Sets the col indices start address for the matrix) [0]
PARAMETER 10 = matrix_element_start_addr (Sets the start address of the elements array) [0]
PARAMETER 11 = iterations (Sets the number of repeats to perform) [REQUIRED]
Suggested fix:
In elements/miranda/miranda.cc, starting from line 172, add a line:
{ "matrix_nnz_per_row", "Sets the number of non-zero elements per row", "4" },
Thanks,
Shang
In sstelementsembertestloadInfo.py (around line 100)
In function initWork, each work contained in list workList is enumerated and passed to function readWorkList
In that function, the work is renamed workList and in another for loop, each work of this workList (previously work) is processed.
These multiple work, worklist, workflow, etc. makes loadInfo.py extremely hard to read. Perhaps other variable names could be employed
Also, for what does nidList stand for And what if the different work contained in the worklist as defined in function readWorkList define through their cmd different nidList Same question for ranksPerNode
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.