GithubHelp home page GithubHelp logo

telecominfraproject / oopt-tai Goto Github PK

View Code? Open in Web Editor NEW
46.0 56.0 30.0 8.71 MB

TIP OOPT - Transponder Abstraction Interface

License: BSD 3-Clause "New" or "Revised" License

C 27.45% Makefile 0.65% C++ 65.82% Dockerfile 0.19% Python 5.89%
transport networking tai sai tip oopt

oopt-tai's People

Contributors

clintbauer avatar dileepbk avatar hidekinishizawa avatar ishidawataru avatar kinmantam avatar lewis-kang avatar m1k10h avatar mikeypiro avatar skuwa avatar tanakatakafumi avatar toru-mano avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

oopt-tai's Issues

memory access out of range

tai_status_t tai_api_initialize(In uint64_t flags,
In const tai_service_method_table_t* services)
{
openlog("stub_tai_adapter", LOG_PID, LOG_USER);
if (0 != flags) {
TAI_SYSLOG_ERROR("Invalid flags passed to TAI API initialize");
return TAI_STATUS_INVALID_PARAMETER;
}

if (NULL == services) {
    TAI_SYSLOG_ERROR("Invalid services handle passed to TAI API initialize");
    return TAI_STATUS_INVALID_PARAMETER;
}

memcpy(&adapter_host_fns, services, sizeof(adapter_host_fns));
**memset(g_modules, 0, sizeof(g_modules) * STUB_NUM_MODULE);**
initialized = true; 

The array size of g_modules is out of range for the below code:
memset(g_modules, 0, sizeof(g_modules) * STUB_NUM_MODULE);
I think it should be:
memset(g_modules, 0, sizeof(g_modules));

Thanks.

Add BER Attribute to Network Interface Object

One of the key measures of quality of a network interface is the bit error rate (BER) of the interface. So I would like add the necessary attribute(s) to support BER for network interfaces. My initial thought is to add a read-only attribute which reports the current BER as a floating point number. In order to get an accurate understanding of the true error rate, the errors prior to any correction (i.e. before forward error correction (FEC) is applied) are the ones which should be used when making the calculation.

Since BER is a "rate", it implies that it is measured over a period of time, i.e. number of bit errors / total number of bits for a period of time. Should that "amount of time" be reported via TAI? The hardware I'm currently working with does the BER calculation in the hardware and simply provides that as a floating point number. It calculates the BER over the last 10 milliseconds, every 10 milliseconds. Other hardware may not perform the BER calculation, but instead rely more on software to periodically read the number of bit errors and perform the division. What are other people's experience with various hardware implementations to support BER?

My proposal is as follows:

    /**
     * @brief The current BER for the network interface
     *
     * @type #tai_float_t
     * @flags READ_ONLY
     */
    TAI_NETWORK_INTERFACE_ATTR_CURRENT_BER,

Add client signal rate attribute

I suggest to support client signal rate attribute.

I propose to add client signal rate attribute under taihostif.
Here is my suggestion sample code:

typedef enum _tai_host_interface_client_signal_rate_t
{
    TAI_HOST_INTERFACE_CLIENT_SIGNAL_RATE_UNKNOWN,
    TAI_HOST_INTERFACE_CLIENT_SIGNAL_RATE_100_GbE,
    TAI_HOST_INTERFACE_CLIENT_SIGNAL_RATE_200_GbE,
    TAI_HOST_INTERFACE_CLIENT_SIGNAL_RATE_400_GbE,
    TAI_HOST_INTERFACE_CLIENT_SIGNAL_RATE_OTU4,
    TAI_HOST_INTERFACE_CLIENT_SIGNAL_RATE_MAX
} tai_host_interface_client_signal_rate_t;

I think the network interface bitrate can be defined by this client signal rate and TAI_MODULE_ATTR_TRIBUTARY_MAPPING. We need to care as there may be a combination of bitrate and modulation format that can not be set in the network interface.
In the future, I want to add OTUCn and FlexE to client signal.

Replace channel/grid spacing support with just frequency support

Remove definitions and support for channel and grid spacing control and status, and replace with definitions and support for only carrier frequency control and status. Implementation would behave as follows.

  • Software snaps to a Read/Write "Requested" frequency attribute to the highest supported grid resolution
  • Software provides a Read Only "Set" frequency attribute for the resulting snapped value

Confirmation of TAI_NETWORK_INTERFACE_ATTR_DSP_STATUS.

Hi everyone, I think user who use the CFP2ACO want to know the two kind of the FAULT alarm for ACO and DSP.
As of now, it looks there is one FAULT alarm in "TAI_NETWORK_INTERFACE_ATTR_OPER_STATUS".
This FAULT alarm is for ACO. Is that right?

And I think we need RMV alarm for maintenance.

What do you think if I add the following new ID for DSP?
_tai_network_interface_attr_t
ID: TAI_NETWORK_INTERFACE_ATTR_DSP_OPER_STATUS
type(parameter): RMV or FAULT
But I also still consider the case of DCO.

Thank you.

TAI_HOST_INTERFACE_ATTR_LANE_FAULT is not defined properly

Commit 2f2abde changed the lane fault definition from a bitmap value to a list of enumerated values. This matches the way SAI handles things. The problem is that a host interface can have multiple lanes, each of which can have faults. So instead of a list of faults, this attribute needs to be a list of lanes each with a list of faults.

This COULD be implemented with the current definition by using a single list, and having the first N entries set aside for lane 0, the next N entries for lane 1, etc.., where N is the number of possible lane faults. But this has two problems:

  1. There is currently no way to specify a "no fault" value which would be necessary to fill the end of each lane's list section.
  2. This is ugly and wasteful. It artificially creates a two dimensional list from a single dimension list, and requires that a # lanes x # fault reasons list be used.

Instead, I think we need to follow the example of the tributary mapping, and create an attribute which points to a list of lanes, each of which is a list of faults on that lane. Something like this:

A new attribute value is added to the tai_attribute_value_t union:

tai_attr_value_list_t attrvallist;

Which is defined as:

typedef struct _tai_attr_value_list_t
{
    /** Number of attribute values in the list */
    uint32_t count;

    /** Attribute value list */
    tai_attribute_value_t *list;
} tai_attr_value_list_t;

The type of the TAI_HOST_INTERFACE_ATTR_LANE_FAULT attribute would then be:

@type #tai_attr_value_list_t #tai_s32_list_t #tai_host_interface_lane_fault_t

Clarification: TAI_MODULE_ATTR_TRIBUTARY_MAPPING

Now that this attribute is defined, I'm about to change the implementation of this attribute from a custom attribute to the standard attribute. I have some questions about how the get_attribute function is supposed to work for this. This attribute is basically a list (tai_object_map_list_t) where each element in that list has a nested list (tai_object_list_t).

First off, I assume that the TAI adapter host is responsible for allocating all memory for the attribute prior to calling get_attribute. The TAI adapter is not responsible for allocating any memory in the get_attribute function. This means that the "list" field of the tai_object_map_list_t must point to an array of "count" tai_object_map_t objects. Similarly each tai_object_map_t element in that array must have a "value.list" field which points to an array of "value.count" tai_object_id_t objects. Please chime in if I'm wrong here.

Now, for the questions:

  1. Is the "key" field of each tai_object_map_t entry expected to be initialized prior to the get_attribute call, so that only those network interfaces specified have their tributary maps returned? OR Are the "key" fields uninitialized, and the list of tai_object_map_t's is expected to be large enough to hold an entry for every network interface object on a module?

I'm thinking the later (key fields are uninitialized). If the size of the tai_object_map_t array is too small, then the TAI adapter puts the required size in the tai_object_map_list_t's "count" field and returns TAI_STATUS_BUFFER_OVERFLOW. If the tai_object_map_list_t's list is larger than the number of network interfaces to be returned in the tai_object_map_t list, then the TAI adapter sets the tai_object_map_list_t's "count" field to the number of entries it filled and returns TAI_STATUS_SUCCESS. This is generally how arrays are supposed to work in SAI/TAI.

  1. And that brings us to the nested lists. If my previous assumption is correct about how SAI/TAI lists work, then the "count" field of each tai_object_list_t entry must be large enough so that the "list" field of the tai_object_list_t entry points to a pre-allocated list of tai_object_id_t's big enough to hold the maximum number of host interfaces that can be mapped to a network interface. If the "count" field of a tai_object_list_t entry is too large, then the TAI adapter will set it to the actual number of host interface object id's it placed in the list. If the "count" field of a tai_object_list_t entry is too small, then the TAI adapter will set the "count" field to the required size and return TAI_STATUS_BUFFER_OVERFLOW. In order to know which list was too small, the TAI adapter host will need to go through the lists, looking for count fields which are larger than what was originally passed to the get_attribute function.

Is this the correct understanding of how the get_attribute function should work for the TAI_MODULE_ATTR_TRIBUTARY_MAPPING attribute?

some issues on TAI-MAI.md

The following APIs or structure is mentioned in https://github.com/Telecominfraproject/oopt-tai/blob/master/docs/TAI-MAI.md

mai_api_initialize()
mai_api_uninitialize()
mai_service_method_table_t

However, according to the code in https://github.com/Telecominfraproject/oopt-tai-implementations/tree/master/tai_mux, the following are being used instead

tai_api_initialize()
tai_api_uninitialize()
tai_service_method_table_t

Should TAI-MAI.md be corrected or the code needs to be changed to match with TAI-MAI.md?

Also, the following paragraph in TAI-MAI.md is not complete and it's wrong by saying "a null point for...."

"After receiving the tai_api_initialize() PA will in turn call Module Adapter's mai_api_initialize() function. There are two parameters passed to the mai_api_initialize() function: flags, which is currently unused and must be set to zero, and a null pointer for mai_service_method_table_t. called"

Tributary support

I'm thinking of adding tributary support in TAI.
At first, Iโ€™d like to check if I understand #1 correct.

Tributary support will enable flexible mapping of host interfaces and network interfaces.

For example, Facebook Voyager has 2 Acacia AC400 inside. AC400 is a dual channel module and can transport 3x100G client signal. When modeling this with TAI, we would have 2 network interfaces and 3 host interfaces inside 1 module.

TAI already has

TAI_MODULE_ATTR_NUM_HOST_INTERFACES and TAI_MODULE_ATTR_NUM_NETWORK_INTERFACES to let the adapter host know how many host interfaces and network interfaces a module has.

However, current TAI master branch lacks attributes for the mapping of host interfaces and network interfaces.

#1 adds some attributes for this purpose.

This PR adds TAI_MODULE_ATTR_NETWORK_MODE which switches how the module exposes the network interfaces inside it.

In case of AC400, if the attribute is set to TAI_MODULE_NETWORK_MODE_INDEPENDENT, 2 network interfaces will be exposed. if set to TAI_MODULE_NETWORK_MODE_COUPLED, only 1 network interface will be exposed.

Based on this attribute, the adapter host will use

  • TAI_HOST_INTERFACE_ATTR_INDEP_RX_NETWORK_TRIBUTARY
  • TAI_NETWORK_INTERFACE_ATTR_INDEP_TX_CLIENT_TRIBUTARY

or

  • TAI_HOST_INTERFACE_ATTR_COUPLED_RX_NETWORK_TRIBUTARY
  • TAI_NETWORK_INTERFACE_ATTR_COUPLED_TX_CLIENT_TRIBUTARY

to set the mapping.

Since RX/TX mapping attribute is separated, we could map RX and TX with different host/network interface pairs.

@scott-emery Could you check if I'm wrong?

Custom Attribute Range Request for Oclaro CFP2-ACO

Would like to add Oclaro CFP2-ACO range in inc/tainetworkif.h as follows.

/** Custom range for the TRB100 adapter */
TAI_NETWORK_INTERFACE_ATTR_CUSTOM_TRB100_START = TAI_NETWORK_INTERFACE_ATTR_CUSTOM_AC400_END + 0x0001,
TAI_NETWORK_INTERFACE_ATTR_CUSTOM_TRB100_END   = TAI_NETWORK_INTERFACE_ATTR_CUSTOM_TRB100_START + 0xFFFF,

Grid spacing 33 GHz

Why is 33 GHz included in the grid spacing attribute? This is not aligned with any standard grid as far as I know.

Method for Supporting Custom Attributes

I order to create working systems, there are some additional object attributes types which may need to be supported. For example, there may be additional functionality enabled by certain transponders that not all transponders would be expected to support. Or there may be some settings which need to be initialized for proper operation which are specific to one transponder. This github issue is being created to propose a method for supporting these custom attributes and hammer out a solution.

Each TAI object currently has a list of standard attributes and an empty list of custom attributes. The standard attributes are listed in the tai_<object>_attr_t enumeration between the TAI_<OBJECT>_ATTR_START and TAI_<OBJECT>_ATTR_END constants. For example, for the module objects, the taimodule.h file defines an enumeration called tai_module_attr_t which lists the standard attributes between the TAI_MODULE_ATTR_START and TAI_MODULE_ATTR_END constants. These include the TAI_MODULE_ATTR_LOCATION, TAI_MODULE_ATTR_VENDOR_NAME, TAI_MODULE_ATTR_NUM_NETWORK_INTERFACES, and many other attributes.

At the end of this enumeration a range for custom attributes is allocated, but is currently unused. This range starts with the TAI_<OBJECT>_ATTR_CUSTOM_RANGE_START constant, which is set to the value 0x10000000. This provides substantial separation from the standard attributes and allows one to easily determine that a attribute's value is in the custom range. Another constant, TAI_<OBJECT>_ATTR_CUSTOM_RANGE_END delimits the end of the range of custom attributes.

The proposal to support custom attributes is to add a single line between the TAI_<OBJECT>_ATTR_CUSTOM_RANGE_START and TAI_<OBJECT>_ATTR_CUSTOM_RANGE_END which is an #include directive to include a file in the new "custom" subdirectory of the "inc" directory. For example, for the module object this line would be #include "custom/taimodule_custom.h". Similar lines would be added for the network interface and host interface objects (and any other objects which get created in the future). The reason for using an #include directive here is to move all custom attributes out of the "standard" TAI include files. I would expect that custom attributes will have more "churn" than the standard attributes and by putting the custom attributes in a separate file from the standard attributes this churn will not impact the standard TAI include files.

The format of the include files in the "custom" directory will simply be a list of attributes, with appropriate comments, of course. We could potentially place #include directives in the custom/tai<object>_custom.h files, one for each transponder that has custom attributes, but that seems like overkill at this point.

Add additional attributes

The object attributes which are currently defined are those attributes which were part of the CFP MSA MIS 2.2. Attributes not in the MSA were deemed vendor-extensions and not included in the TAI. But there are some very important attributes, such as the modulation and signal coding of a network interface, which should be included in the TAI.

I'm opening this issue as a way to keep track of the "non-standard" attributes which should be added to TAI in a standard way.

Loopback Support

It is common for network operators to test the optical line system by placing a network interface in loopback, sending data to that interface from a far-end system, and checking the data received back on that far-end system.

I would like to add a loopback attribute to network interfaces. Setting this attribute to true will cause all data received on the network interface to be sent back out on the same network interface.

And just for good measure, I would also like to add a host interface loopback. When enabled, this would send all data received on a host interface back out that same host interface.

Does this seem valuable?

Is a boolean value the appropriate type for these attributes? I could imagine transponders where different types of loopback are supported (optical loopback, digital loopback, etc.). Is that overkill? The MSA MIS appears to only allow enable/disable. If different types of loopback should be supported, are there references for the types of loopbacks typically supported?

Baudrate attribute

I could not find any attribute related to baudrate or bitrate. Shouldn't this be a network interface attribute or do you only target modules supporting a single baudrate?

Additional setting attributes for transmission mode description

This issue suggests adding new setting attributes for transmission mode description enhancement.

Transmission modes and their descriptions

This issue defines a transmission mode as a transponder's operational mode corresponding to an optical interface specification (e.g., OpenROADM 400G) such as OpenROADM, CableLabs, ITU-T, IEEE, and OIF specification.

A transmission mode specifies the transponder's parameters, including line rate, modulation format, FEC type, etc. To configure the transponder properly, we have to uniquely describe and specify a transmission mode because a transponder may support multiple transmission modes.

An issue on mode description

Currently, we specify a transmission mode with host interface signal rate TAI_HOST_INTERFACE_ATTR_SIGNAL_RATE and network interface modulation format TAI_NETWORK_INTERFACE_ATTR_MODULATION_FORMAT, and other configuration parameters are automatically selected. However, we have two different standardized transmission modes, OpenROADM 400G[1] and OIF 400ZR[10], that have the same signal rate and modulation format. To distinguish them, we need to use custom attributes.

Standardized transmission modes

The following table lists the standardized transmission modes that correspond to the existing specifications by OpenROADM [1,2], CableLabs [3,4], ITU-T[5,6,7,8], IEEE[9], OIF[10], OpenZR+[11]. Note that, each line represents a transmission mode.

Line Rate Modulation FEC Client Mapping Baud Rate [GHz] Organization
100G DP-QPSK SC FEC OTU4-LR 28.0 OpenROADM, CableLabs, ITU-T, IEEE
100G DP-QPSK oFEC FlexO-LR 31.6 OpenROADM
100G DP-QPSK oFEC ZR 30.0 OpenZR+
200G DP-16QAM oFEC FlexO-LR 31.6 OpenROADM, CableLabs
200G DP-QPSK oFEC FlexO-LR 63.1 OpenROADM, CableLabs, ITU-T
200G DP-QPSK oFEC ZR 60.1 OpenZR+
300G DP-8QAM oFEC FlexO-LR 63.1 OpenROADM
300G DP-8QAM oFEC ZR 60.1 OpenZR+
400G DP-16QAM oFEC FlexO-LR 63.1 OpenROADM, ITU-T
400G DP-16QAM oFEC ZR 60.1 OpenZR+
400G DP-16QAM CFEC ZR 59.8 OIF

In the table, several specifications relate to a single transmission mode because they are equivalent in the context of DSP's operational mode. For example, 100G with SC FEC transmission mode corresponds to OpenROADM, CableLabs, ITU-T, and IEEE specifications. These specifications have the same modulation format, baud rate, symbol mapping, frame format, pilot symbols, etc., and thus are equivalent in the viewpoint of DSP's operational mode.

The client mapping name corresponds to the title of the corresponding specification title. That is, "OTU4-LR" refers to the client signal mapping method described in ITU-T G.709.2 "OUT4 long-reach interface." "FlexO-LR" refers to the client signal mapping method described in ITU-T G.709.3 "Flexible OTN long-reach interface." "ZR" refers to OIF 400ZR and OpenZR+.

A suggestion to resolving the issue

General idea

DPSs internally have transmission mode descriptions, but different DSPs use different descriptions. This issue suggests hiding such vendor-specific descriptions and providing a common method, or standard-setting attributes, to describe transmission modes.

Description by attributes combination

This suggestion adds new setting attributes and specifies a transmission mode as a combination of attributes.

The following is an example code.

/**
 * @brief Network interface attribute IDs
 */
typedef enum _tai_network_interface_attr_t
{
   /** snip */
    /**
     * @brief The line rate
     *
     * @type #tai_network_interface_line_rate_t
     * @flags CREATE_AND_SET
     * @default vendor-specific
     */
    TAI_NETWORK_INTERFACE_ATTR_LINE_RATE,

    /**
     * @brief The FEC type
     *
     * @type #tai_network_interface_fec_type_t
     * @flags CREATE_AND_SET
     * @default vendor-specific
     */
    TAI_NETWORK_INTERFACE_ATTR_FEC_TYPE,

    /**
     * @brief The client signal mapping type
     *
     * @type #tai_network_interface_client_mapping_t
     * @flags CREATE_AND_SET
     * @default vendor-specific
     */
    TAI_NETWORK_INTERFACE_ATTR_CLIENT_MAPPING,


   /** snip */
} tai_network_interface_attr_t;

In this example, we will specify a transmission mode as a combination of

  • line rate TAI_NETWORK_INTERFACE_ATTR_LINE_RATE,
  • modulation format TAI_NETWORK_INTERFACE_ATTR_MODULATION_FORMAT,
  • FEC type TAI_NETWORK_INTERFACE_ATTR_FEC_TYPE,
  • and, client signal mapping method TAI_NETWORK_INTERFACE_ATTR_CLIENT_MAPPING.

Related sub-issues

This section summarizes related sub-issues to deal with transponders that support multiple transmission modes.

(These sub-issues and suggestions have been discussed so far in this issue. I will update if needed)

Sub-issue 1

We need a way to get supported transmission modes (or valid combinations of setting attributes that specify the mode) from the TAI adaptor.

Suggestion 1

Add an attribute that represents a list of supported transmission modes like below.

TAI_NETWORK_INTERFACE_ATTR_IMPLEMENTATION_TEMPLATES = [(rate:400g, mode:dp-16qam, fec:ofec), (rate:400g, mode:dp-16qam, fec:cfec), (rate:100g, mode:dp-qpsk, fec:sc-fec)]

Unfortunately, there is no good C struct to represent the implementation template. One possible way is allowing a list of lists in tai_attr_value_list_t to represent the implementation template.

Sub-issue 2

Since the TAI adaptor host (or network controller) and TAI adaptor will use different mode descriptions (referred to as implementation templates and mode templates in the comment #131 (comment)), we need a way to translate them. They exist in the different abstraction layers; TAI adaptor operates on hardware registers while adaptor host (or network controller) mainly operates on the abstracted network data model, e.g., Yang model.

Suggestion 2

Let the TAI adaptor host (or network controller) convert their descriptions (or mode templates) to the TAI adaptor's descriptions (implementation templates). This is because there will be multiple network controllers, and if the TAI adaptor tries to translate descriptions (or templates), it must know all the descriptions used by the network controllers.

To support network controller developers, we may provide a table like #131 (comment) explaining which attributes' combinations correspond to the standardized mode. For example, we can provide information like "if you want to use OpenROADM 400G, then use the following parameter combinations."

Sub-issue 3

Due to the lack of information or software compatibility, some controllers may specify only a part of attributes, e.g., only the line rate values.

Suggestion 3

Define the supported modes (or implementation templates) TAI_NETWORK_INTERFACE_ATTR_IMPLEMENTATION_TEMPLATES as an ordered list as in sub-issue 1 and use the first template that matches the given attribute values.

Sub-issue 4

We need a way to retrieve parameters like CD tolerance and receiver OSNR tolerance to provide compatibility or check the optical path feasibility.

Suggestion 4

Add new read-only attributes to obtain those parameter values. I will make another issue to discuss what kind of parameters are required. To find what parameters should be included, we can consult existing specification materials such as OpenROADM, ITU-T G.698.2, IETF Yang mode, and so on.

References

[1] OpenROADM, OpenROADM MSA Specification ver 5.0 https://openroadm.org, 2021
[2] OpenROADM, OpenROADM MSA 5.0 W-Port Digital Specification https://openroadm.org, 2021
[3] CableLabs, P2P Coherent Optics Physical Layer 1.0 Specification https://www.cablelabs.com/specifications, 2020
[4] CableLabs, Physical Layer 2.0 Specification https://www.cablelabs.com/specifications, 2020
[5] ITU-T, G.709/Y.1331 Interfaces for the optical transport network, 2020
[6] ITU-T, G.709.1/Y.1331.1 Flexible OTN short-reach interfaces, 2020
[7] ITU-T, G.709.2/Y.1331.2 OTU4 long-reach interface, 2018
[8] ITU-T, G.709.3/Y.1331.3 Flexible OTN long-reach interfaces, 2020
[9] IEEE802.3ct-2021, IEEE Standard for Ethernet Amendment 13:Physical Layers and Management Parameters for 100 Gb/s Operation over DWDM Systems, 2021
[10] OIF, Implementation Agreement 400ZR, 2020
[11] OpenZR+ Specifications, version 1.0, 4 September 2020, http://openzrplus.org/site/assets/files/1075/openzrplus_1p0.pdf

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.